fix: 修复飞书配置层级问题,确保 dmPolicy 正确生效
- 修复 configureFeishuAccount 函数,同时设置顶层和账户级配置 - 原因:default 账户不会合并 accounts.default 的覆盖值 - 新增 --allow-from 和 --group-policy 参数 - 默认 dmPolicy 改为 allowlist(安全优先) - 更新 SKILL.md 文档,添加配置层级说明 - 新增 FIXES.md 记录修复详情
This commit is contained in:
99
FIXES.md
Normal file
99
FIXES.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# agent-creator-with-binding 修复说明
|
||||
|
||||
## 修复的问题
|
||||
|
||||
### 问题 1:配置层级错误导致 dmPolicy 不生效
|
||||
|
||||
**原因:**
|
||||
- Skill 只在 `channels.feishu.accounts.<accountId>` 中设置 `dmPolicy` 和 `allowFrom`
|
||||
- OpenClaw 的 `getLarkAccount` 函数在处理 `accountId === "default"` 时,**不会合并** `accounts.default` 中的覆盖值
|
||||
- 导致 default 账户读取不到 dmPolicy 配置,始终使用默认的 `pairing` 模式
|
||||
|
||||
**表现:**
|
||||
- 用户已在配置中设置 `dmPolicy: allowlist`
|
||||
- 但机器人仍然回复配对提示,而不是拒绝访问
|
||||
|
||||
**修复:**
|
||||
```javascript
|
||||
// 如果是第一个账户或 default 账户,设置顶层配置
|
||||
if (isFirstAccount || isDefaultBot) {
|
||||
config.channels.feishu.dmPolicy = options.dmPolicy || 'allowlist';
|
||||
config.channels.feishu.allowFrom = options.allowFrom || ['*'];
|
||||
config.channels.feishu.groupPolicy = options.groupPolicy || 'open';
|
||||
config.channels.feishu.groupAllowFrom = options.groupAllowFrom || [];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 正确的配置结构
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"feishu": {
|
||||
"enabled": true,
|
||||
"appId": "cli_a93dc207e1f89bcb",
|
||||
"appSecret": "xxx",
|
||||
|
||||
"dmPolicy": "allowlist",
|
||||
"allowFrom": ["ou_xxx", "ou_yyy"],
|
||||
"groupPolicy": "open",
|
||||
"groupAllowFrom": [],
|
||||
|
||||
"accounts": {
|
||||
"default": {
|
||||
"appId": "cli_a93dc207e1f89bcb",
|
||||
"appSecret": "xxx",
|
||||
"dmPolicy": "allowlist",
|
||||
"allowFrom": ["ou_xxx", "ou_yyy"]
|
||||
},
|
||||
"coding-expert-bot": {
|
||||
"appId": "cli_a9320c94f23a1bd6",
|
||||
"appSecret": "yyy",
|
||||
"dmPolicy": "allowlist",
|
||||
"allowFrom": ["ou_xxx", "ou_yyy"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 新增参数
|
||||
|
||||
- `--allow-from`: 白名单用户,逗号分隔(如:`ou_xxx,ou_yyy`)
|
||||
- `--group-policy`: 群聊策略:open/allowlist/disabled(默认 open)
|
||||
|
||||
---
|
||||
|
||||
## 默认行为变更
|
||||
|
||||
| 参数 | 修复前默认值 | 修复后默认值 | 说明 |
|
||||
|------|-------------|-------------|------|
|
||||
| `--dm-policy` | `open` | `allowlist` | 安全优先,默认白名单模式 |
|
||||
| `--allow-from` | `['*']` | 从顶层配置继承 | 确保一致性 |
|
||||
|
||||
---
|
||||
|
||||
## 验证方法
|
||||
|
||||
```bash
|
||||
# 1. 创建新 Agent 后检查配置
|
||||
openclaw agents list --bindings
|
||||
|
||||
# 2. 查看飞书配置
|
||||
cat ~/.openclaw/openclaw.json | jq '.channels.feishu | {dmPolicy, allowFrom, accounts}'
|
||||
|
||||
# 3. 测试机器人响应
|
||||
# 向机器人发送消息,确认不会收到配对提示(如果已配置 allowlist)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `/home/admin/.openclaw/workspace/skills/agent-creator-with-binding/index.js` - 主要修复
|
||||
- `/home/admin/.openclaw/workspace/skills/agent-creator-with-binding/SKILL.md` - 文档更新
|
||||
48
SKILL.md
48
SKILL.md
@@ -149,10 +149,56 @@ openclaw skills run agent-creator-with-binding -- \
|
||||
| --account-id | ❌ | 飞书账户 ID(现有机器人时需要) |
|
||||
| --chat-id | ❌ | 群聊 ID(群聊绑定时需要) |
|
||||
| --bot-name | ❌ | 机器人名称 |
|
||||
| --dm-policy | ❌ | DM 策略:open/pairing/allowlist |
|
||||
| --dm-policy | ❌ | DM 策略:allowlist/open/pairing(默认 allowlist) |
|
||||
| --allow-from | ❌ | 白名单用户,逗号分隔(如:ou_xxx,ou_yyy) |
|
||||
| --group-policy | ❌ | 群聊策略:open/allowlist/disabled(默认 open) |
|
||||
| --skip-confirm | ❌ | 跳过确认 |
|
||||
| --skip-restart | ❌ | 跳过重启 |
|
||||
|
||||
## 配置层级说明
|
||||
|
||||
**⚠️ 重要:** 飞书配置必须同时设置顶层和账户级配置!
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"feishu": {
|
||||
// ★ 顶层配置(必须设置!)
|
||||
// 原因:default 账户不会合并 accounts.default 的覆盖值
|
||||
"dmPolicy": "allowlist",
|
||||
"allowFrom": ["ou_xxx", "ou_yyy"],
|
||||
"groupPolicy": "open",
|
||||
"groupAllowFrom": [],
|
||||
|
||||
"accounts": {
|
||||
// 账户级配置(可覆盖顶层设置)
|
||||
"default": {
|
||||
"appId": "cli_xxx",
|
||||
"appSecret": "xxx",
|
||||
"dmPolicy": "allowlist", // 继承顶层或覆盖
|
||||
"allowFrom": ["ou_xxx"] // 继承顶层或覆盖
|
||||
},
|
||||
"bot-other": {
|
||||
"appId": "cli_yyy",
|
||||
"appSecret": "yyy",
|
||||
"dmPolicy": "open" // 可独立设置
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**修复前的问题:**
|
||||
- 只在 `accounts.<accountId>` 中设置 dmPolicy
|
||||
- `default` 账户读取不到配置(代码 bug)
|
||||
- 导致配对提示而不是拒绝访问
|
||||
|
||||
**修复后的行为:**
|
||||
- 自动设置顶层 `channels.feishu.dmPolicy`
|
||||
- 同时设置账户级配置(可覆盖)
|
||||
- 确保所有账户(包括 default)正确继承
|
||||
|
||||
## 配置变更
|
||||
|
||||
执行后会修改:
|
||||
|
||||
66
index.js
66
index.js
@@ -379,19 +379,44 @@ function configureFeishuAccount(options) {
|
||||
|
||||
const config = loadConfig();
|
||||
|
||||
// 确保 channels.feishu.accounts 存在
|
||||
// 确保 channels.feishu 结构存在
|
||||
if (!config.channels) config.channels = {};
|
||||
if (!config.channels.feishu) config.channels.feishu = { enabled: true };
|
||||
if (!config.channels.feishu.accounts) config.channels.feishu.accounts = {};
|
||||
|
||||
// 添加账户
|
||||
// ★ 重要:顶层配置必须设置 dmPolicy 和 allowFrom
|
||||
// 原因:当 accountId === "default" 时,getLarkAccount 不会合并 accounts.default 的覆盖值
|
||||
// 所以顶层 channels.feishu 必须有 dmPolicy 和 allowFrom,确保 default 账户正确继承
|
||||
|
||||
// 如果是第一个账户或者是 default 账户,设置顶层配置
|
||||
const isDefaultBot = options.accountId === 'default' || options.accountId.startsWith('bot-');
|
||||
const existingAccounts = Object.keys(config.channels.feishu.accounts);
|
||||
const isFirstAccount = existingAccounts.length === 0;
|
||||
|
||||
if (isFirstAccount || isDefaultBot) {
|
||||
// 设置顶层 dmPolicy 和 allowFrom(默认 allowlist,白名单用户)
|
||||
config.channels.feishu.dmPolicy = options.dmPolicy || 'allowlist';
|
||||
config.channels.feishu.allowFrom = options.allowFrom || ['*'];
|
||||
config.channels.feishu.groupPolicy = options.groupPolicy || 'open';
|
||||
config.channels.feishu.groupAllowFrom = options.groupAllowFrom || [];
|
||||
log.success(`已设置顶层飞书配置:dmPolicy=${config.channels.feishu.dmPolicy}`);
|
||||
}
|
||||
|
||||
// 添加账户级配置
|
||||
config.channels.feishu.accounts[options.accountId] = {
|
||||
appId: options.appId,
|
||||
appSecret: options.appSecret,
|
||||
botName: options.botName || `${options.agentName}机器人`,
|
||||
dmPolicy: options.dmPolicy || 'open',
|
||||
allowFrom: ['*'],
|
||||
enabled: true
|
||||
enabled: true,
|
||||
domain: 'feishu',
|
||||
connectionMode: 'websocket',
|
||||
requireMention: true,
|
||||
streaming: true,
|
||||
// 账户级配置可以覆盖顶层设置
|
||||
dmPolicy: options.dmPolicy || config.channels.feishu.dmPolicy || 'allowlist',
|
||||
allowFrom: options.allowFrom || config.channels.feishu.allowFrom || ['*'],
|
||||
groupPolicy: options.groupPolicy || config.channels.feishu.groupPolicy || 'open',
|
||||
groupAllowFrom: options.groupAllowFrom || config.channels.feishu.groupAllowFrom || []
|
||||
};
|
||||
|
||||
if (saveConfig(config)) {
|
||||
@@ -582,7 +607,24 @@ async function interactiveMode() {
|
||||
|
||||
options.accountId = await question(`账户 ID(默认:bot-${agentId}): `) || `bot-${agentId}`;
|
||||
options.botName = await question(`机器人名称(默认:${agentName}机器人): `) || `${agentName}机器人`;
|
||||
options.dmPolicy = await question(`DM 策略(open/pairing/allowlist,默认 open): `) || 'open';
|
||||
|
||||
// DM 策略
|
||||
console.log('\nDM 策略说明:');
|
||||
console.log(' - allowlist: 仅允许白名单用户私聊(推荐,安全)');
|
||||
console.log(' - open: 允许所有用户私聊');
|
||||
console.log(' - pairing: 需要配对码才能访问');
|
||||
const dmPolicy = await question(`DM 策略(allowlist/open/pairing,默认 allowlist): `) || 'allowlist';
|
||||
options.dmPolicy = dmPolicy;
|
||||
|
||||
// 白名单用户(仅当 allowlist 时需要)
|
||||
if (dmPolicy === 'allowlist') {
|
||||
console.log('\n白名单用户说明:');
|
||||
console.log(' - 输入用户 open_id(格式:ou_xxx)');
|
||||
console.log(' - 多个用户用逗号分隔');
|
||||
console.log(' - 留空则允许所有人(不推荐)');
|
||||
const allowFromInput = await question('白名单用户(逗号分隔,默认:*): ') || '*';
|
||||
options.allowFrom = allowFromInput.split(',').map(s => s.trim()).filter(Boolean);
|
||||
}
|
||||
} else {
|
||||
// 列出飞书账户供选择
|
||||
log.info('可用飞书账户:');
|
||||
@@ -600,7 +642,8 @@ async function interactiveMode() {
|
||||
options.appSecret = appSecret;
|
||||
options.accountId = await question(`账户 ID(默认:bot-${agentId}): `) || `bot-${agentId}`;
|
||||
options.botName = await question(`机器人名称(默认:${agentName}机器人): `) || `${agentName}机器人`;
|
||||
options.dmPolicy = 'open';
|
||||
options.dmPolicy = 'allowlist';
|
||||
options.allowFrom = ['*'];
|
||||
} else {
|
||||
accountIds.forEach((id, index) => {
|
||||
console.log(` ${index + 1}. ${id} (${accounts[id].botName || '未命名'})`);
|
||||
@@ -742,7 +785,9 @@ ${colors.bold}选项:${colors.reset}
|
||||
--account-id <id> 飞书账户 ID
|
||||
--chat-id <id> 群聊 ID(群聊绑定时需要)
|
||||
--bot-name <name> 机器人名称
|
||||
--dm-policy <policy> DM 策略:open/pairing/allowlist
|
||||
--dm-policy <policy> DM 策略:allowlist/open/pairing(默认 allowlist)
|
||||
--allow-from <users> 白名单用户,逗号分隔(如:ou_xxx,ou_yyy)
|
||||
--group-policy <policy> 群聊策略:open/allowlist/disabled(默认 open)
|
||||
--skip-confirm 跳过确认
|
||||
--skip-restart 跳过重启
|
||||
|
||||
@@ -789,7 +834,10 @@ ${colors.bold}示例:${colors.reset}
|
||||
appSecret: options.appsecret,
|
||||
accountId: options.accountid || `bot-${options.agentid}`,
|
||||
botName: options.botname,
|
||||
dmPolicy: options.dmpolicy || 'open',
|
||||
dmPolicy: options.dmpolicy || 'allowlist',
|
||||
allowFrom: options.allowfrom ? options.allowfrom.split(',').map(s => s.trim()) : undefined,
|
||||
groupPolicy: options.grouppolicy || 'open',
|
||||
groupAllowFrom: options.groupallowfrom ? options.groupallowfrom.split(',').map(s => s.trim()) : undefined,
|
||||
chatId: options.chatid
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user