merge: integrate main channel config changes

This commit is contained in:
Hoshina 2026-04-14 00:34:17 +08:00
commit 93f69a98ba
186 changed files with 6505 additions and 4190 deletions

View file

@ -19,6 +19,7 @@ import (
"github.com/sipeed/picoclaw/cmd/picoclaw/internal"
"github.com/sipeed/picoclaw/pkg/config"
"github.com/sipeed/picoclaw/pkg/logger"
)
const (
@ -155,11 +156,31 @@ func defaultWeComQRFlowOptions(timeout time.Duration) wecomQRFlowOptions {
}
func applyWeComAuthResult(cfg *config.Config, botInfo wecomQRBotInfo) {
cfg.Channels.WeCom.Enabled = true
cfg.Channels.WeCom.BotID = botInfo.BotID
cfg.Channels.WeCom.SetSecret(botInfo.Secret)
if strings.TrimSpace(cfg.Channels.WeCom.WebSocketURL) == "" {
cfg.Channels.WeCom.WebSocketURL = wecomDefaultWebSocketURL
bc := cfg.Channels.GetByType(config.ChannelWeCom)
if bc == nil {
bc = &config.Channel{Type: config.ChannelWeCom}
cfg.Channels["wecom"] = bc
}
bc.Enabled = true
decoded, err := bc.GetDecoded()
if err != nil {
logger.ErrorCF("wecom", "failed to decode WeCom settings", map[string]any{
"error": err.Error(),
})
return
}
wecomCfg, ok := decoded.(*config.WeComSettings)
if !ok {
logger.ErrorCF("wecom", "unexpected WeCom settings type", map[string]any{
"got": fmt.Sprintf("%T", decoded),
})
return
}
wecomCfg.BotID = botInfo.BotID
wecomCfg.Secret = *config.NewSecureString(botInfo.Secret)
if strings.TrimSpace(wecomCfg.WebSocketURL) == "" {
wecomCfg.WebSocketURL = wecomDefaultWebSocketURL
}
}

View file

@ -112,17 +112,23 @@ func TestPollWeComQRCodeResult(t *testing.T) {
func TestApplyWeComAuthResult(t *testing.T) {
cfg := config.DefaultConfig()
cfg.Channels.WeCom.WebSocketURL = ""
require.NoError(t, config.InitChannelList(cfg.Channels))
wecom := cfg.Channels["wecom"]
t.Logf("wecom: %+v", wecom)
decoded, err := wecom.GetDecoded()
require.NoError(t, err)
weCfg := decoded.(*config.WeComSettings)
weCfg.WebSocketURL = ""
applyWeComAuthResult(cfg, wecomQRBotInfo{
BotID: "bot-1",
Secret: "secret-1",
})
assert.True(t, cfg.Channels.WeCom.Enabled)
assert.Equal(t, "bot-1", cfg.Channels.WeCom.BotID)
assert.Equal(t, "secret-1", cfg.Channels.WeCom.Secret.String())
assert.Equal(t, wecomDefaultWebSocketURL, cfg.Channels.WeCom.WebSocketURL)
assert.True(t, wecom.Enabled)
assert.Equal(t, "bot-1", weCfg.BotID)
assert.Equal(t, "secret-1", weCfg.Secret.String())
assert.Equal(t, wecomDefaultWebSocketURL, weCfg.WebSocketURL)
}
func TestAuthWeComCmdWithScanner(t *testing.T) {
@ -149,9 +155,13 @@ func TestAuthWeComCmdWithScanner(t *testing.T) {
cfg, err := config.LoadConfig(internal.GetConfigPath())
require.NoError(t, err)
assert.True(t, cfg.Channels.WeCom.Enabled)
assert.Equal(t, "bot-1", cfg.Channels.WeCom.BotID)
assert.Equal(t, "secret-1", cfg.Channels.WeCom.Secret.String())
assert.Equal(t, wecomDefaultWebSocketURL, cfg.Channels.WeCom.WebSocketURL)
wecom := cfg.Channels["wecom"]
decoded, err := wecom.GetDecoded()
require.NoError(t, err)
weCfg := decoded.(*config.WeComSettings)
assert.True(t, wecom.Enabled)
assert.Equal(t, "bot-1", weCfg.BotID)
assert.Equal(t, "secret-1", weCfg.Secret.String())
assert.Equal(t, wecomDefaultWebSocketURL, weCfg.WebSocketURL)
assert.Contains(t, output.String(), "WeCom connected.")
}

View file

@ -95,14 +95,24 @@ func saveWeixinConfig(token, baseURL, proxy string) error {
return fmt.Errorf("failed to load config: %w", err)
}
cfg.Channels.Weixin.Enabled = true
cfg.Channels.Weixin.SetToken(token)
const defaultBase = "https://ilinkai.weixin.qq.com/"
if baseURL != "" && baseURL != defaultBase {
cfg.Channels.Weixin.BaseURL = baseURL
bc := cfg.Channels.GetByType(config.ChannelWeixin)
if bc == nil {
bc = &config.Channel{Type: config.ChannelWeixin}
cfg.Channels[config.ChannelWeixin] = bc
}
if proxy != "" {
cfg.Channels.Weixin.Proxy = proxy
bc.Enabled = true
if decoded, err := bc.GetDecoded(); err == nil && decoded != nil {
if weixinCfg, ok := decoded.(*config.WeixinSettings); ok {
weixinCfg.Token = *config.NewSecureString(token)
const defaultBase = "https://ilinkai.weixin.qq.com/"
if baseURL != "" && baseURL != defaultBase {
weixinCfg.BaseURL = baseURL
}
if proxy != "" {
weixinCfg.Proxy = proxy
}
}
}
return config.SaveConfig(cfgPath, cfg)

View file

@ -8,9 +8,10 @@ DingTalk est la plateforme de communication d'entreprise d'Alibaba, très popula
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ DingTalkはアリババの企業向けコミュニケーションプラットフ
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ DingTalk is Alibaba's enterprise communication platform, widely used in Chinese
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ DingTalk é a plataforma de comunicação empresarial da Alibaba, amplamente uti
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ DingTalk là nền tảng giao tiếp doanh nghiệp của Alibaba, được s
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ Discord est une application gratuite de chat vocal, vidéo et textuel conçue po
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Discord はコミュニティ向けに設計された無料の音声・ビデオ
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Discord is a free voice, video, and text chat application designed for communiti
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Discord é um aplicativo gratuito de chat de voz, vídeo e texto projetado para
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Discord là ứng dụng chat thoại, video và văn bản miễn phí được
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Discord 是一个专为社区设计的免费语音、视频和文本聊天应用
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"group_trigger": {

View file

@ -8,9 +8,10 @@ Feishu (nom international : Lark) est une plateforme de collaboration d'entrepri
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@ Feishu (international name: Lark) is an enterprise collaboration platform by Byt
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@ Feishu (nome internacional: Lark) é uma plataforma de colaboração empresarial
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@ Feishu (tên quốc tế: Lark) là nền tảng cộng tác doanh nghiệp củ
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",

View file

@ -8,9 +8,10 @@ PicoClaw prend en charge LINE via l'API LINE Messaging avec des callbacks webhoo
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ PicoClaw は LINE Messaging API と Webhook コールバックを通じて LINE
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ PicoClaw supports LINE through the LINE Messaging API with webhook callbacks.
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ O PicoClaw suporta o LINE por meio da LINE Messaging API com callbacks de webhoo
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ PicoClaw hỗ trợ LINE thông qua LINE Messaging API kết hợp với webhook
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ PicoClaw 通过 LINE Messaging API 配合 Webhook 回调功能实现对 LINE 的
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",

View file

@ -8,9 +8,10 @@ MaixCam est un canal dédié à la connexion aux caméras AI Sipeed MaixCAM et M
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ MaixCam は、Sipeed MaixCAM および MaixCAM2 AI カメラデバイスへの
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ MaixCam is a dedicated channel for connecting to Sipeed MaixCAM and MaixCAM2 AI
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ MaixCam é um canal dedicado para conectar dispositivos de câmera AI Sipeed Mai
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ MaixCam là kênh chuyên dụng để kết nối với các thiết bị camer
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ MaixCam 是专用于连接矽速科技 MaixCAM 与 MaixCAM2 AI 摄像设备的
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"host": "0.0.0.0",
"port": 18790,
"allow_from": []

View file

@ -8,9 +8,10 @@ Ajoutez ceci à `config.json` :
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@ Add this to `config.json`:
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@ Adicione isto ao `config.json`:
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@ Thêm vào `config.json`:
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",

View file

@ -8,9 +8,10 @@ OneBot est un standard de protocole ouvert pour les bots QQ, fournissant une int
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ OneBot は QQ ボット向けのオープンプロトコル標準で、複数の
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ OneBot is an open protocol standard for QQ bots, providing a unified interface f
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ OneBot é um padrão de protocolo aberto para bots QQ, fornecendo uma interface
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ OneBot là tiêu chuẩn giao thức mở dành cho bot QQ, cung cấp giao di
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ OneBot 是一个面向 QQ 机器人的开放协议标准,为多种 QQ 机器
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://localhost:8080",
"access_token": "",
"allow_from": []

View file

@ -8,9 +8,10 @@ PicoClaw prend en charge QQ via l'API Bot officielle de la plateforme ouverte QQ
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ PicoClaw は QQ オープンプラットフォームの公式 Bot API を通じ
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ PicoClaw provides QQ support via the official Bot API from the QQ Open Platform.
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ O PicoClaw oferece suporte ao QQ via API Bot oficial da Plataforma Aberta QQ.
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ PicoClaw hỗ trợ QQ thông qua API Bot chính thức của Nền tảng Mở
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []

View file

@ -8,9 +8,10 @@ PicoClaw 通过 QQ 开放平台的官方机器人 API 提供对 QQ 的支持。
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": [],

View file

@ -8,9 +8,10 @@ Slack est l'une des principales plateformes de messagerie instantanée pour les
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ Slack は世界をリードする企業向けインスタントメッセージ
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ Slack is a leading enterprise instant messaging platform. PicoClaw uses Slack's
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ O Slack é uma das principais plataformas de mensagens instantâneas para empres
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ Slack là nền tảng nhắn tin tức thì hàng đầu dành cho doanh nghi
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ Slack 是全球领先的企业级即时通讯平台。PicoClaw 采用 Slack 的
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"allow_from": []

View file

@ -8,9 +8,10 @@ Le canal Telegram utilise le long polling via l'API Bot Telegram pour une commun
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -42,9 +43,10 @@ Vous pouvez définir `use_markdown_v2: true` pour activer les options de formata
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -8,9 +8,10 @@ Telegram チャンネルは、Telegram Bot API を使用したロングポーリ
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -42,9 +43,10 @@ Telegram チャンネルは、Telegram Bot API を使用したロングポーリ
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -8,9 +8,10 @@ The Telegram channel uses long polling via the Telegram Bot API for bot-based co
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -62,9 +63,10 @@ You can set `use_markdown_v2: true` to enable enhanced formatting options. This
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -8,9 +8,10 @@ O canal Telegram utiliza long polling via a API de Bot do Telegram para comunica
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -42,9 +43,10 @@ Você pode definir `use_markdown_v2: true` para habilitar opções de formataç
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -8,9 +8,10 @@ Kênh Telegram sử dụng long polling qua Telegram Bot API để giao tiếp d
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -42,9 +43,10 @@ Bạn có thể đặt `use_markdown_v2: true` để bật các tùy chọn đ
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -8,9 +8,10 @@ Telegram Channel 通过 Telegram 机器人 API 使用长轮询实现基于机器
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
"allow_from": ["123456789"],
"proxy": "",
@ -62,9 +63,10 @@ explain how to squash the last 3 commits
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": true

View file

@ -6,9 +6,10 @@ The VK channel uses Bots Long Poll API for bot-based communication with VK socia
```json
{
"channels": {
"channel_list": {
"vk": {
"enabled": true,
"type": "vk",
"token": "NOT_HERE",
"group_id": 123456789,
"allow_from": ["123456789"],
@ -120,9 +121,10 @@ VK has a maximum message length of 4000 characters. PicoClaw automatically split
```json
{
"channels": {
"channel_list": {
"vk": {
"enabled": true,
"type": "vk",
"token": "NOT_HERE",
"group_id": 123456789
}
@ -134,9 +136,10 @@ VK has a maximum message length of 4000 characters. PicoClaw automatically split
```json
{
"channels": {
"channel_list": {
"vk": {
"enabled": true,
"type": "vk",
"token": "NOT_HERE",
"group_id": 123456789,
"allow_from": ["123456789", "987654321"]
@ -149,9 +152,10 @@ VK has a maximum message length of 4000 characters. PicoClaw automatically split
```json
{
"channels": {
"channel_list": {
"vk": {
"enabled": true,
"type": "vk",
"token": "NOT_HERE",
"group_id": 123456789,
"group_trigger": {

View file

@ -56,9 +56,10 @@ Si vous disposez déjà d'un `bot_id` et d'un `secret` depuis la plateforme WeCo
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -56,9 +56,10 @@ WeCom AI Bot プラットフォームから `bot_id` と `secret` を既にお
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -56,9 +56,10 @@ If you already have a `bot_id` and `secret` from the WeCom AI Bot platform, conf
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -56,9 +56,10 @@ Se você já possui um `bot_id` e `secret` da plataforma WeCom AI Bot, configure
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -56,9 +56,10 @@ Nếu bạn đã có `bot_id` và `secret` từ nền tảng WeCom AI Bot, hãy
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -56,9 +56,10 @@ picoclaw auth wecom --timeout 10m
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",

View file

@ -29,9 +29,10 @@ You can also manually configure the filter rules in `config.json` under the `cha
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_WEIXIN_TOKEN",
"allow_from": [
"user_id_1",

View file

@ -29,9 +29,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_WEIXIN_TOKEN",
"allow_from": [
"user_id_1",

View file

@ -40,9 +40,10 @@ Talk to your picoclaw through Telegram, Discord, WhatsApp, Matrix, QQ, DingTalk,
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": false
@ -101,9 +102,10 @@ You can set use_markdown_v2: true to enable enhanced formatting options. This al
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -124,7 +126,7 @@ By default the bot responds to all messages in a server channel. To restrict res
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -136,7 +138,7 @@ You can also trigger by keyword prefixes (e.g. `!bot`):
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -165,9 +167,10 @@ PicoClaw can connect to WhatsApp in two ways:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -199,9 +202,10 @@ Scan the printed QR code with your WeChat mobile app. On success, the token is s
(Optional) Update `allow_from` with your WeChat User ID to restrict who can message the bot:
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -230,9 +234,10 @@ QQ Open Platform provides a one-click setup page for OpenClaw-compatible bots:
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -272,9 +277,10 @@ If you prefer to create the bot manually:
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -305,9 +311,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -341,9 +348,10 @@ For full options (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`,
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -399,9 +407,10 @@ This command shows a QR code, waits for approval in WeCom, and writes `bot_id` +
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",
@ -440,9 +449,10 @@ PicoClaw connects to Feishu via WebSocket/SDK mode — no public webhook URL or
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -480,9 +490,10 @@ For full options, see [Feishu Channel Configuration Guide](channels/feishu/READM
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -507,9 +518,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -547,9 +559,10 @@ Install and run a OneBot v11 compatible QQ bot framework. Enable its WebSocket s
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []

View file

@ -20,6 +20,16 @@ PicoClaw uses a schema versioning system for `config.json` to ensure smooth upgr
- V0 configs now migrate directly to CurrentVersion (V2) instead of going through V1
- `makeBackup()` now uses date-only suffix (e.g., `config.json.20260330.bak`) and also backs up `.security.yml`
### Version 3
- **Introduction**: Enhanced type safety and improved error handling
- **Changes**:
- Added comma-ok type assertions in channel configuration decoding to prevent potential panics
- Improved error logging for Weixin channel configuration decoding
- Enhanced security configuration documentation and examples
- **Auto-migration**: V2 configs are automatically migrated to V3 on load with no user action required
- **Backup**: Before migration, the system creates a date-stamped backup (e.g., `config.json.20260413.bak`) in the same directory
- **Downgrade risk**: Once migrated to V3, the config cannot be safely loaded by older V2-only versions. To downgrade, restore from the auto-created backup file.
## How It Works
### Automatic Migration
@ -39,7 +49,7 @@ The `version` field in `config.json` indicates the schema version:
```json
{
"version": 2,
"version": 3,
"agents": {...},
...
}
@ -164,6 +174,52 @@ func TestMigrateV2ToV3(t *testing.T) {
7. **Test Thoroughly**: Test with real user config files
8. **Update Defaults**: Keep `defaults.go` in sync with the latest schema
## V2→V3 Migration Guide
### What Changed?
Version 3 introduces improved type safety and error handling:
- **Type-safe channel decoding**: All channel type assertions now use comma-ok pattern (`val, ok := v.(*Settings)`) to prevent panics if Type and Settings are mismatched
- **Enhanced error logging**: Weixin channel now logs errors on `GetDecoded()` failure for consistency with other channels
- **Documentation fixes**: Corrected stray quotes in JSON configuration examples
### Auto-Migration Behavior
When you run PicoClaw with a V2 config file:
1. **Detection**: PicoClaw reads the `version` field and detects V2
2. **Backup**: Before any changes, creates `config.json.YYYYMMDD.bak` (e.g., `config.json.20260413.bak`)
3. **Migration**: Applies V2→V3 structural changes (primarily internal type safety improvements)
4. **Save**: Writes the updated config with `"version": 3`
5. **Continue**: Starts normally with the V3 config
**No user action required** — the migration happens automatically on first load.
### Backup Location
Backups are created in the same directory as your config file:
- **Default**: `~/.picoclaw/config.json.20260413.bak`
- **Custom path**: If using `PICOCLAW_CONFIG`, backup is created next to that file
- **Security file**: `.security.yml` is also backed up as `.security.yml.YYYYMMDD.bak`
### Downgrade Risk
⚠️ **Important**: Once migrated to V3, the config **cannot** be safely loaded by older PicoClaw versions that only support V2.
**To downgrade:**
1. Stop PicoClaw
2. Restore the backup:
```bash
cp ~/.picoclaw/config.json.20260413.bak ~/.picoclaw/config.json
cp ~/.picoclaw/.security.yml.20260413.bak ~/.picoclaw/.security.yml # if it exists
```
3. Use a PicoClaw version that supports V2 configs
**Alternative**: Manually edit `config.json` and change `"version": 3` to `"version": 2`. This works because V3 changes are primarily code-level safety improvements, not structural schema changes.
## Example Migration
### Scenario: Adding a new field with default value
@ -171,7 +227,7 @@ func TestMigrateV2ToV3(t *testing.T) {
Old config (version 2):
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "gpt-5.4",

View file

@ -537,9 +537,10 @@ chmod 600 ~/.picoclaw/.security.yml
// api_key loaded from .security.yml
}
],
"channels": {
"channel_list": {
"telegram": {
"enabled": true"
"enabled": true,
"type": "telegram",
// token loaded from .security.yml
}
}
@ -852,9 +853,10 @@ This keeps the runtime lightweight while making new OpenAI-compatible backends m
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true"
"enabled": true,
"type": "telegram",
// token: set in .security.yml
"allow_from": ["123456789"]
}

View file

@ -40,9 +40,10 @@ Communiquez avec votre PicoClaw via Telegram, Discord, WhatsApp, Matrix, QQ, Din
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -90,9 +91,10 @@ Si l'enregistrement des commandes échoue (erreurs transitoires réseau/API), le
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -113,7 +115,7 @@ Par défaut, le bot répond à tous les messages dans un canal de serveur. Pour
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -125,7 +127,7 @@ Vous pouvez également déclencher par préfixes de mots-clés (par ex. `!bot`)
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -154,9 +156,10 @@ PicoClaw peut se connecter à WhatsApp de deux manières :
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -188,9 +191,10 @@ Scannez le QR code affiché avec votre application WeChat mobile. Une fois conne
(Optionnel) Ajoutez votre identifiant utilisateur WeChat dans `allow_from` pour restreindre qui peut envoyer des messages au bot :
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -219,9 +223,10 @@ QQ Open Platform propose une page de configuration en un clic pour les bots comp
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -261,9 +266,10 @@ Si vous préférez créer le bot manuellement :
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -294,9 +300,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -330,9 +337,10 @@ Pour toutes les options (`device_id`, `join_on_invite`, `group_trigger`, `placeh
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -388,9 +396,10 @@ Voir le [Guide de Configuration WeCom AI Bot](../channels/wecom/wecom_aibot/READ
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
@ -421,7 +430,7 @@ Voir le [Guide de Configuration WeCom AI Bot](../channels/wecom/wecom_aibot/READ
```json
{
"channels": {
"channel_list": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
@ -456,7 +465,7 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
@ -497,9 +506,10 @@ PicoClaw se connecte à Feishu via le mode WebSocket/SDK — aucune URL webhook
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -537,9 +547,10 @@ Pour toutes les options, voir le [Guide de Configuration du Canal Feishu](../cha
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -564,9 +575,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -604,9 +616,10 @@ Installez et exécutez un framework de bot QQ compatible OneBot v11. Activez son
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []
@ -641,9 +654,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true,
"type": "maixcam",
"allow_from": []
}
}

View file

@ -276,7 +276,7 @@ L'ancienne configuration `providers` est **dépréciée** et a été supprimée
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -362,19 +362,22 @@ picoclaw agent -m "Hello"
"api_key": "gsk_xxx"
}
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -382,6 +385,7 @@ picoclaw agent -m "Hello"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -390,6 +394,7 @@ picoclaw agent -m "Hello"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -345,6 +345,7 @@ Au lieu de charger tous les outils, le LLM reçoit un outil de recherche léger
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -44,9 +44,10 @@ PicoClaw は複数のチャットプラットフォームをサポートして
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -95,9 +96,10 @@ Telegram 側はコマンドメニュー登録機能を保持し、汎用コマ
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -118,7 +120,7 @@ Telegram 側はコマンドメニュー登録機能を保持し、汎用コマ
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -130,7 +132,7 @@ Telegram 側はコマンドメニュー登録機能を保持し、汎用コマ
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -159,9 +161,10 @@ PicoClaw は 2 つの WhatsApp 接続方式をサポートしています:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -193,9 +196,10 @@ WeChat モバイルアプリで表示された QR コードをスキャンして
(オプション)ボットと会話できるユーザーを制限するために `allow_from` に WeChat ユーザー ID を追加します:
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -223,9 +227,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -259,9 +264,10 @@ QQ 開放プラットフォームでは、OpenClaw 互換ボットのワンク
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -302,9 +308,10 @@ QQ 開放プラットフォームでは、OpenClaw 互換ボットのワンク
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -329,9 +336,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -369,9 +377,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -404,9 +413,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -456,9 +466,10 @@ PicoClaw は WebSocket/SDK モードで飛書に接続します — 公開 Webho
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -504,9 +515,10 @@ PicoClaw は 3 種類の WeCom 統合をサポートしています:
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
@ -537,7 +549,7 @@ PicoClaw は 3 種類の WeCom 統合をサポートしています:
```json
{
"channels": {
"channel_list": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
@ -572,7 +584,7 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
@ -610,9 +622,10 @@ OneBot v11 互換の QQ ボットフレームワークをインストールし
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []
@ -643,9 +656,10 @@ Sipeed AI カメラハードウェア向けの統合チャネルです。
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}

View file

@ -287,7 +287,7 @@ PicoClaw はリクエスト送信前に外側の `litellm/` プレフィック
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -373,19 +373,22 @@ picoclaw agent -m "こんにちは"
"api_key": "gsk_xxx"
}
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -393,6 +396,7 @@ picoclaw agent -m "こんにちは"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -401,6 +405,7 @@ picoclaw agent -m "こんにちは"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -345,6 +345,7 @@ MCP ツールは外部の Model Context Protocol サーバーとの統合を可
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -50,7 +50,7 @@ The new `model_list` configuration offers several advantages:
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "gpt4",

View file

@ -38,9 +38,10 @@ Berbual dengan picoclaw anda melalui Telegram, Discord, WhatsApp, Matrix, QQ, Di
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": false,
@ -91,9 +92,10 @@ Anda boleh menetapkan `use_markdown_v2: true` untuk mengaktifkan pilihan pemform
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -114,7 +116,7 @@ Secara lalai bot membalas semua mesej dalam saluran pelayan. Untuk mengehadkan b
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -126,7 +128,7 @@ Anda juga boleh mencetuskan dengan awalan kata kunci (contohnya `!bot`):
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -154,9 +156,10 @@ PicoClaw boleh menyambung ke WhatsApp dalam dua cara:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -181,9 +184,10 @@ Jika `session_store_path` kosong, sesi akan disimpan dalam `<workspace>/whatsapp
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -215,9 +219,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -247,9 +252,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -282,9 +288,10 @@ Untuk pilihan penuh (`device_id`, `join_on_invite`, `group_trigger`, `placeholde
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -339,9 +346,10 @@ Lihat [Panduan Konfigurasi WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
@ -372,7 +380,7 @@ Lihat [Panduan Konfigurasi WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.
```json
{
"channels": {
"channel_list": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
@ -407,7 +415,7 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",

View file

@ -390,7 +390,7 @@ The old `providers` configuration is **deprecated** and has been removed in V2.
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -480,19 +480,22 @@ picoclaw agent -m "Hello"
"model_name": "voice-gemini",
"echo_transcription": false
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -500,6 +503,7 @@ picoclaw agent -m "Hello"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -508,6 +512,7 @@ picoclaw agent -m "Hello"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -40,9 +40,10 @@ Converse com seu picoclaw através do Telegram, Discord, WhatsApp, Matrix, QQ, D
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -90,9 +91,10 @@ Se o registro de comandos falhar (erros transitórios de rede/API), o canal aind
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -113,7 +115,7 @@ Por padrão, o bot responde a todas as mensagens em um canal do servidor. Para r
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -125,7 +127,7 @@ Você também pode ativar por prefixos de palavras-chave (ex.: `!bot`):
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -154,9 +156,10 @@ O PicoClaw pode se conectar ao WhatsApp de duas formas:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -188,9 +191,10 @@ Escaneie o QR code exibido com seu aplicativo WeChat mobile. Após o login bem-s
(Opcional) Adicione seu ID de usuário WeChat em `allow_from` para restringir quem pode enviar mensagens ao bot:
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -219,9 +223,10 @@ A QQ Open Platform oferece uma página de configuração com um clique para bots
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -261,9 +266,10 @@ Se preferir criar o bot manualmente:
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -290,9 +296,10 @@ Canal de integração projetado especificamente para hardware de câmera AI Sipe
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}
@ -318,9 +325,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -354,9 +362,10 @@ Para opções completas (`device_id`, `join_on_invite`, `group_trigger`, `placeh
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -412,9 +421,10 @@ Veja o [Guia de Configuração do WeCom AI Bot](../channels/wecom/wecom_aibot/RE
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
@ -445,7 +455,7 @@ Veja o [Guia de Configuração do WeCom AI Bot](../channels/wecom/wecom_aibot/RE
```json
{
"channels": {
"channel_list": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
@ -480,7 +490,7 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
@ -520,9 +530,10 @@ O PicoClaw se conecta ao Feishu via modo WebSocket/SDK — não é necessário U
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -560,9 +571,10 @@ Para opções completas, veja o [Guia de Configuração do Canal Feishu](../chan
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -587,9 +599,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -627,9 +640,10 @@ Instale e execute um framework de bot QQ compatível com OneBot v11. Habilite se
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []
@ -659,9 +673,10 @@ Canal de integração projetado especificamente para hardware de câmera AI Sipe
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}

View file

@ -276,7 +276,7 @@ A configuração antiga `providers` está **descontinuada** e foi removida no V2
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -362,19 +362,22 @@ picoclaw agent -m "Hello"
"api_key": "gsk_xxx"
}
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -382,6 +385,7 @@ picoclaw agent -m "Hello"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -390,6 +394,7 @@ picoclaw agent -m "Hello"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -345,6 +345,7 @@ Em vez de carregar todas as ferramentas, o LLM recebe uma ferramenta de pesquisa
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -148,9 +148,10 @@ You can now remove sensitive fields from `config.json` since they're loaded from
"api_key": "sk-your-actual-api-key-here"
}
],
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz"
}
}
@ -168,9 +169,10 @@ You can now remove sensitive fields from `config.json` since they're loaded from
// api_key is now loaded from .security.yml
}
],
"channels": {
"channel_list": {
"telegram": {
"enabled": true"
"enabled": true,
"type": "telegram"
// token is now loaded from .security.yml
}
}
@ -444,7 +446,7 @@ Returns the path to `.security.yml` relative to the config file.
```json
{
"version": 2,
"version": 3,
"agents": {
"defaults": {
"workspace": "~/picoclaw-workspace",
@ -463,9 +465,10 @@ Returns the path to `.security.yml` relative to the config file.
"api_base": "https://api.anthropic.com/v1"
}
],
"channels": {
"channel_list": {
"telegram": {
"enabled": true
"enabled": true,
"type": "telegram"
}
},
"tools": {

View file

@ -397,6 +397,7 @@ dynamically only when requested by the user.*
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -40,9 +40,10 @@ Trò chuyện với picoclaw của bạn qua Telegram, Discord, WhatsApp, Matrix
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -90,9 +91,10 @@ Nếu đăng ký lệnh thất bại (lỗi tạm thời mạng/API), kênh vẫ
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -113,7 +115,7 @@ Mặc định bot phản hồi tất cả tin nhắn trong kênh server. Để g
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -125,7 +127,7 @@ Bạn cũng có thể kích hoạt bằng tiền tố từ khóa (ví dụ: `!bo
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -154,9 +156,10 @@ PicoClaw có thể kết nối WhatsApp theo hai cách:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -188,9 +191,10 @@ Quét mã QR được in ra bằng ứng dụng WeChat trên điện thoại. Sa
(Tùy chọn) Thêm ID người dùng WeChat vào `allow_from` để giới hạn ai có thể nhắn tin với bot:
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -219,9 +223,10 @@ QQ Open Platform cung cấp trang thiết lập một chạm cho bot tương th
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -261,9 +266,10 @@ Nếu bạn muốn tạo bot thủ công:
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -290,9 +296,10 @@ Kênh tích hợp được thiết kế đặc biệt cho phần cứng camera A
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}
@ -318,9 +325,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -354,9 +362,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -412,9 +421,10 @@ Xem [Hướng Dẫn Cấu Hình WeCom AI Bot](../channels/wecom/wecom_aibot/READ
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
@ -445,7 +455,7 @@ Xem [Hướng Dẫn Cấu Hình WeCom AI Bot](../channels/wecom/wecom_aibot/READ
```json
{
"channels": {
"channel_list": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
@ -480,7 +490,7 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
@ -521,9 +531,10 @@ PicoClaw kết nối với Feishu qua chế độ WebSocket/SDK — không cần
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -561,9 +572,10 @@ Mở Feishu, tìm tên bot của bạn và bắt đầu trò chuyện. Bạn cũ
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -588,9 +600,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -628,9 +641,10 @@ Cài đặt và chạy framework bot QQ tương thích OneBot v11. Bật máy ch
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []
@ -660,9 +674,10 @@ Kênh tích hợp được thiết kế đặc biệt cho phần cứng camera A
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}

View file

@ -276,7 +276,7 @@ Cấu hình `providers` cũ đã **bị deprecated** và đã được loại b
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -362,19 +362,22 @@ picoclaw agent -m "Hello"
"api_key": "gsk_xxx"
}
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -382,6 +385,7 @@ picoclaw agent -m "Hello"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -390,6 +394,7 @@ picoclaw agent -m "Hello"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -345,6 +345,7 @@ Thay vì tải tất cả các công cụ, LLM được cung cấp một công c
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -44,9 +44,10 @@ PicoClaw 支持多种聊天平台,使您的 Agent 能够连接到任何地方
```json
{
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -102,9 +103,10 @@ Telegram 侧保留的是命令菜单注册能力;通用命令的实际执行
```json
{
"channels": {
"channel_list": {
"discord": {
"enabled": true,
"type": "discord",
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -125,7 +127,7 @@ Telegram 侧保留的是命令菜单注册能力;通用命令的实际执行
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "mention_only": true }
}
@ -137,7 +139,7 @@ Telegram 侧保留的是命令菜单注册能力;通用命令的实际执行
```json
{
"channels": {
"channel_list": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
@ -166,9 +168,10 @@ PicoClaw 支持两种 WhatsApp 连接方式:
```json
{
"channels": {
"channel_list": {
"whatsapp": {
"enabled": true,
"type": "whatsapp",
"use_native": true,
"session_store_path": "",
"allow_from": []
@ -200,9 +203,10 @@ picoclaw auth weixin
(可选)在 `allow_from` 中填入你的微信用户 ID限制可以与机器人对话的用户
```json
{
"channels": {
"channel_list": {
"weixin": {
"enabled": true,
"type": "weixin",
"token": "YOUR_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
@ -230,9 +234,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"matrix": {
"enabled": true,
"type": "matrix",
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
@ -266,9 +271,10 @@ QQ 开放平台提供了一键创建 OpenClaw 兼容机器人的页面:
```json
{
"channels": {
"channel_list": {
"qq": {
"enabled": true,
"type": "qq",
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -309,9 +315,10 @@ QQ 开放平台提供了一键创建 OpenClaw 兼容机器人的页面:
```json
{
"channels": {
"channel_list": {
"slack": {
"enabled": true,
"type": "slack",
"bot_token": "xoxb-YOUR-BOT-TOKEN",
"app_token": "xapp-YOUR-APP-TOKEN",
"allow_from": []
@ -336,9 +343,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"irc": {
"enabled": true,
"type": "irc",
"server": "irc.libera.chat:6697",
"tls": true,
"nick": "picoclaw-bot",
@ -376,9 +384,10 @@ Bot 将连接到 IRC 服务器并加入指定的频道。
```json
{
"channels": {
"channel_list": {
"dingtalk": {
"enabled": true,
"type": "dingtalk",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
@ -411,9 +420,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"line": {
"enabled": true,
"type": "line",
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
@ -463,9 +473,10 @@ PicoClaw 通过 WebSocket/SDK 模式连接飞书 — 无需公网 Webhook URL
```json
{
"channels": {
"channel_list": {
"feishu": {
"enabled": true,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
@ -511,9 +522,10 @@ picoclaw auth wecom
```json
{
"channels": {
"channel_list": {
"wecom": {
"enabled": true,
"type": "wecom",
"bot_id": "YOUR_BOT_ID",
"secret": "YOUR_SECRET",
"websocket_url": "wss://openws.work.weixin.qq.com",
@ -549,9 +561,10 @@ OneBot 是 QQ 机器人的开放协议。PicoClaw 通过 WebSocket 连接任何
```json
{
"channels": {
"channel_list": {
"onebot": {
"enabled": true,
"type": "onebot",
"ws_url": "ws://127.0.0.1:8080",
"access_token": "",
"allow_from": []
@ -582,9 +595,10 @@ picoclaw gateway
```json
{
"channels": {
"channel_list": {
"maixcam": {
"enabled": true
"enabled": true,
"type": "maixcam"
}
}
}

View file

@ -622,9 +622,10 @@ PicoClaw 按协议族路由提供商:
"api_key": "gsk_xxx"
}
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
}

View file

@ -360,7 +360,7 @@ PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/l
```json
{
"version": 2,
"version": 3,
"model_list": [
{
"model_name": "glm-4.7",
@ -450,19 +450,22 @@ picoclaw agent -m "你好"
"model_name": "voice-gemini",
"echo_transcription": false
},
"channels": {
"channel_list": {
"telegram": {
"enabled": true,
"type": "telegram",
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"type": "discord",
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"type": "whatsapp",
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
@ -470,6 +473,7 @@ picoclaw agent -m "你好"
},
"feishu": {
"enabled": false,
"type": "feishu",
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
@ -478,6 +482,7 @@ picoclaw agent -m "你好"
},
"qq": {
"enabled": false,
"type": "qq",
"app_id": "",
"app_secret": "",
"allow_from": []

View file

@ -372,6 +372,7 @@ LLM 不会加载所有工具,而是获得一个轻量级搜索工具(使用
},
"slack": {
"enabled": true,
"type": "slack",
"command": "npx",
"args": [
"-y",

View file

@ -327,8 +327,13 @@ import (
)
func init() {
channels.RegisterFactory("telegram", func(cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
return NewTelegramChannel(cfg, b)
channels.RegisterFactory(config.ChannelTelegram, func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.TelegramSettings)
if !ok { return nil, channels.ErrSendFailed }
return NewTelegramChannel(bc, c, b)
})
}
```
@ -427,8 +432,13 @@ import (
)
func init() {
channels.RegisterFactory("matrix", func(cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
return NewMatrixChannel(cfg, b)
channels.RegisterFactory(config.ChannelMatrix, func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.MatrixSettings)
if !ok { return nil, channels.ErrSendFailed }
return NewMatrixChannel(bc, c, b)
})
}
```
@ -773,41 +783,59 @@ When the Agent finishes processing a message, Manager's `preSend` automatically:
### 3.5 Register Configuration and Gateway Integration
#### Add configuration in `pkg/config/config.go`
#### Add configuration entry
Channels now use a unified map-based configuration (`map[string]*config.Channel`).
Each channel entry stores common fields (`enabled`, `type`, `allow_from`, etc.) at
the top level, with channel-specific settings in the `settings` sub-key:
```json
{
"channels": {
"matrix": {
"enabled": true,
"type": "matrix",
"allow_from": ["@user:example.com"],
"settings": {
"home_server": "https://matrix.org",
"user_id": "@bot:example.com",
"access_token": "enc://..."
}
}
}
}
```
Secure fields (tokens, passwords, API keys) go into `.security.yml`:
```yaml
channels:
matrix:
access_token: "your-matrix-access-token"
```
Channel types must be registered in `channelSettingsFactory` in
`pkg/config/config_channel.go`:
```go
type ChannelsConfig struct {
var channelSettingsFactory = map[string]any{
// ... existing channels
Matrix MatrixChannelConfig `json:"matrix"`
}
type MatrixChannelConfig struct {
Enabled bool `json:"enabled"`
HomeServer string `json:"home_server"`
Token string `json:"token"`
AllowFrom []string `json:"allow_from"`
GroupTrigger GroupTriggerConfig `json:"group_trigger"`
Placeholder PlaceholderConfig `json:"placeholder"`
ReasoningChannelID string `json:"reasoning_channel_id"`
ChannelMatrix: (MatrixSettings{}),
}
```
#### Add entry in Manager.initChannels()
#### No Manager changes needed
```go
// In the initChannels() method of pkg/channels/manager.go
if m.config.Channels.Matrix.Enabled && m.config.Channels.Matrix.Token != "" {
m.initChannel("matrix", "Matrix")
}
```
The Manager uses `InitChannelList()` to validate types and decode settings,
then looks up factories by `bc.Type`. No per-channel entry needed in Manager —
just register the factory and the config entry.
> **Note**: If your channel has multiple modes (like WhatsApp Bridge vs Native), branch in initChannels based on config:
> **Note**: If your channel has multiple modes (like WhatsApp Bridge vs Native),
> register both types in `channelSettingsFactory` and branch on config:
> ```go
> if cfg.UseNative {
> m.initChannel("whatsapp_native", "WhatsApp Native")
> } else {
> m.initChannel("whatsapp", "WhatsApp")
> }
> // In config_channel.go:
> ChannelWhatsApp: (WhatsAppSettings{}),
> ChannelWhatsAppNative: (WhatsAppSettings{}),
> ```
#### Add blank import in Gateway
@ -947,10 +975,29 @@ channels.WithReasoningChannelID(id) // Set reasoning chain routing target
**File**: `pkg/channels/registry.go`
```go
type ChannelFactory func(cfg *config.Config, bus *bus.MessageBus) (Channel, error)
type ChannelFactory func(channelName, channelType string, cfg *config.Config, bus *bus.MessageBus) (Channel, error)
func RegisterFactory(name string, f ChannelFactory) // Called in sub-package init()
func getFactory(name string) (ChannelFactory, bool) // Called internally by Manager
func RegisterFactory(name string, f ChannelFactory) // Called in sub-package init()
func getFactory(name string) (ChannelFactory, bool) // Called internally by Manager
func GetRegisteredFactoryNames() []string // Returns all registered factory names
```
For convenience, `RegisterSafeFactory[S any]` provides automatic type-safe settings decoding:
```go
// Instead of manual GetDecoded() + type assertion:
channels.RegisterFactory(config.ChannelTelegram,
func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.TelegramSettings)
if !ok { return nil, ErrSendFailed }
return NewTelegramChannel(bc, c, b)
})
// You can use RegisterSafeFactory (same safety, less boilerplate):
channels.RegisterSafeFactory(config.ChannelTelegram, NewTelegramChannel)
```
The factory registry is protected by `sync.RWMutex` and registrations occur during `init()` phase (completed at process startup). Manager looks up factories by name in `initChannel()` and calls them.

View file

@ -327,8 +327,13 @@ import (
)
func init() {
channels.RegisterFactory("telegram", func(cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
return NewTelegramChannel(cfg, b)
channels.RegisterFactory(config.ChannelTelegram, func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.TelegramSettings)
if !ok { return nil, channels.ErrSendFailed }
return NewTelegramChannel(bc, c, b)
})
}
```
@ -427,8 +432,13 @@ import (
)
func init() {
channels.RegisterFactory("matrix", func(cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
return NewMatrixChannel(cfg, b)
channels.RegisterFactory(config.ChannelMatrix, func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (channels.Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.MatrixSettings)
if !ok { return nil, channels.ErrSendFailed }
return NewMatrixChannel(bc, c, b)
})
}
```
@ -772,41 +782,58 @@ if c.owner != nil && c.placeholderRecorder != nil {
### 3.5 注册配置和 Gateway 接入
#### 在 `pkg/config/config.go` 中添加配置
#### 添加配置入口
Channels 现在使用统一的 map 类型配置(`map[string]*config.Channel`)。
每个 channel 条目将通用字段(`enabled``type``allow_from` 等)放在顶层,
channel 特定的设置放在 `settings` 子键中:
```json
{
"channels": {
"matrix": {
"enabled": true,
"type": "matrix",
"allow_from": ["@user:example.com"],
"settings": {
"home_server": "https://matrix.org",
"user_id": "@bot:example.com",
"access_token": "enc://..."
}
}
}
}
```
安全字段token、密码、API 密钥)放入 `.security.yml`
```yaml
channels:
matrix:
access_token: "your-matrix-access-token"
```
Channel 类型必须在 `pkg/config/config_channel.go``channelSettingsFactory` 中注册:
```go
type ChannelsConfig struct {
var channelSettingsFactory = map[string]any{
// ... 现有 channels
Matrix MatrixChannelConfig `json:"matrix"`
}
type MatrixChannelConfig struct {
Enabled bool `json:"enabled"`
HomeServer string `json:"home_server"`
Token string `json:"token"`
AllowFrom []string `json:"allow_from"`
GroupTrigger GroupTriggerConfig `json:"group_trigger"`
Placeholder PlaceholderConfig `json:"placeholder"`
ReasoningChannelID string `json:"reasoning_channel_id"`
ChannelMatrix: (MatrixSettings{}),
}
```
#### 在 Manager.initChannels() 中添加入口
#### 无需修改 Manager
```go
// pkg/channels/manager.go 的 initChannels() 方法中
if m.config.Channels.Matrix.Enabled && m.config.Channels.Matrix.Token != "" {
m.initChannel("matrix", "Matrix")
}
```
Manager 使用 `InitChannelList()` 来验证类型和解码设置,
然后通过 `bc.Type` 查找工厂。不需要在 Manager 中添加每个 channel 的条目——
只需注册工厂和配置条目即可。
> **注意**:如果你的 channel 有多种模式(如 WhatsApp Bridge vs Native需要在 initChannels 中根据配置分支:
> **注意**:如果你的 channel 有多种模式(如 WhatsApp Bridge vs Native
> 在 `channelSettingsFactory` 中注册两种类型,并根据配置分支:
> ```go
> if cfg.UseNative {
> m.initChannel("whatsapp_native", "WhatsApp Native")
> } else {
> m.initChannel("whatsapp", "WhatsApp")
> }
> // 在 config_channel.go 中:
> ChannelWhatsApp: (WhatsAppSettings{}),
> ChannelWhatsAppNative: (WhatsAppSettings{}),
> ```
#### 在 Gateway 中添加 blank import
@ -946,10 +973,29 @@ channels.WithReasoningChannelID(id) // 设置思维链路由目标 channe
**文件**`pkg/channels/registry.go`
```go
type ChannelFactory func(cfg *config.Config, bus *bus.MessageBus) (Channel, error)
type ChannelFactory func(channelName, channelType string, cfg *config.Config, bus *bus.MessageBus) (Channel, error)
func RegisterFactory(name string, f ChannelFactory) // 子包 init() 中调用
func getFactory(name string) (ChannelFactory, bool) // Manager 内部调用
func RegisterFactory(name string, f ChannelFactory) // 子包 init() 中调用
func getFactory(name string) (ChannelFactory, bool) // Manager 内部调用
func GetRegisteredFactoryNames() []string // 返回所有已注册的工厂名称
```
为方便使用,`RegisterSafeFactory[S any]` 提供自动类型安全的设置解码:
```go
// 不使用 RegisterSafeFactory手动 GetDecoded() + 类型断言):
channels.RegisterFactory(config.ChannelTelegram,
func(channelName, channelType string, cfg *config.Config, b *bus.MessageBus) (Channel, error) {
bc := cfg.Channels[channelName]
decoded, err := bc.GetDecoded()
if err != nil { return nil, err }
c, ok := decoded.(*config.TelegramSettings)
if !ok { return nil, ErrSendFailed }
return NewTelegramChannel(bc, c, b)
})
// 使用 RegisterSafeFactory同等安全减少样板代码
channels.RegisterSafeFactory(config.ChannelTelegram, NewTelegramChannel)
```
工厂注册表使用 `sync.RWMutex` 保护,在 `init()` 阶段注册进程启动时完成。Manager 在 `initChannel()` 中通过名字查找工厂并调用它。

View file

@ -103,6 +103,16 @@ func NewBaseChannel(
allowList []string,
opts ...BaseChannelOption,
) *BaseChannel {
isEmpty := true
for _, s := range allowList {
if s != "" {
isEmpty = false
break
}
}
if isEmpty {
allowList = []string{}
}
bc := &BaseChannel{
config: config,
bus: bus,
@ -177,6 +187,12 @@ func (c *BaseChannel) Name() string {
return c.name
}
// SetName updates the channel name. Used by the manager after channel creation
// to ensure the name matches the config key (which may differ from the type).
func (c *BaseChannel) SetName(name string) {
c.name = name
}
func (c *BaseChannel) ReasoningChannelID() string {
return c.reasoningChannelID
}

View file

@ -25,7 +25,7 @@ import (
// It uses WebSocket for receiving messages via stream mode and API for sending
type DingTalkChannel struct {
*channels.BaseChannel
config config.DingTalkConfig
config *config.DingTalkSettings
clientID string
clientSecret string
streamClient *client.StreamClient
@ -36,7 +36,11 @@ type DingTalkChannel struct {
}
// NewDingTalkChannel creates a new DingTalk channel instance
func NewDingTalkChannel(cfg config.DingTalkConfig, messageBus *bus.MessageBus) (*DingTalkChannel, error) {
func NewDingTalkChannel(
bc *config.Channel,
cfg *config.DingTalkSettings,
messageBus *bus.MessageBus,
) (*DingTalkChannel, error) {
if cfg.ClientID == "" || cfg.ClientSecret.String() == "" {
return nil, fmt.Errorf("dingtalk client_id and client_secret are required")
}
@ -44,10 +48,10 @@ func NewDingTalkChannel(cfg config.DingTalkConfig, messageBus *bus.MessageBus) (
// Set the logger for the Stream SDK
dinglog.SetLogger(logger.NewLogger("dingtalk"))
base := channels.NewBaseChannel("dingtalk", cfg, messageBus, cfg.AllowFrom,
base := channels.NewBaseChannel("dingtalk", cfg, messageBus, bc.AllowFrom,
channels.WithMaxMessageLength(20000),
channels.WithGroupTrigger(cfg.GroupTrigger),
channels.WithReasoningChannelID(cfg.ReasoningChannelID),
channels.WithGroupTrigger(bc.GroupTrigger),
channels.WithReasoningChannelID(bc.ReasoningChannelID),
)
return &DingTalkChannel{

Some files were not shown because too many files have changed in this diff Show more