troubleshooting.md 6.94 KB

Feishu/Lark 故障排除指南

常见问题速查

1. 用户 @ 机器人但无回复

症状:用户在飞书 @ 机器人或私聊,但机器人没有回复

检查步骤:

  1. Gateway 是否运行?

    hermes gateway status
    # 应显示:✓ Gateway is running (PID: xxxx)
    
  2. 飞书是否连接?

    tail -20 ~/.hermes/logs/gateway.log | grep "feishu"
    # 应看到:
    # - "Connecting to feishu..."
    # - "[Feishu] Connected in websocket mode"
    # - "Gateway running with X platform(s)"
    
  3. 用户是否授权?

    tail -50 ~/.hermes/logs/gateway.log | grep "Unauthorized"
    # 如果看到:"Unauthorized user: xxx on feishu"
    # 解决:设置 GATEWAY_ALLOW_ALL_USERS=true 或执行配对授权
    
  4. 应用是否启用机器人能力?

  5. 登录 https://open.feishu.cn/app

  6. 选择应用 -> 应用能力 -> 机器人

  7. 确保"启用机器人"已开启

解决方案:

# 方案 1:允许所有用户(开发环境)
echo "GATEWAY_ALLOW_ALL_USERS=true" >> ~/.hermes/.env

# 方案 2:手动授权用户
# 用户首次使用会收到配对码,执行:
hermes pairing approve feishu <PAIRING_CODE>

# 重启 Gateway
hermes gateway restart

2. Gateway 启动失败

症状:执行 hermes gateway run 后立即退出

常见错误:

错误 A:权限问题

PermissionError: [Errno 13] Permission denied: '/data/data/com.termux/files/home/.hermes/gateway.lock'

解决:

# 修复权限
chmod 777 ~/.hermes/
rm -f ~/.hermes/gateway.lock

# 或使用 --replace 参数
hermes gateway run --replace

错误 B:日志目录问题

OSError: [Errno 30] Read-only file system: '/.hermes'

解决(Termux 环境):

# 创建日志目录到 /sdcard
mkdir -p /sdcard/.hermes/logs

# 删除旧目录并创建链接
rm -rf ~/.hermes/logs
ln -s /sdcard/.hermes/logs ~/.hermes/logs

# 重新启动
hermes gateway run

错误 C:端口冲突

OSError: [Errno 98] Address already in use

解决:

# 查找并杀死旧进程
ps aux | grep hermes | grep gateway
kill <PID>

# 或使用 --replace
hermes gateway run --replace

3. DNS 解析失败

症状:无法连接飞书服务器,出现 DNS 错误

错误示例:

dial tcp: lookup accounts.feishu.cn: no such host
dial tcp: lookup open.feishu.cn: no such host

检查:

# 检查 DNS 配置
cat /data/data/com.termux/files/usr/etc/resolv.conf

# 测试 DNS 解析
nslookup open.feishu.cn
ping open.feishu.cn

解决方案:

# 方案 1:配置 DNS
echo "nameserver 8.8.8.8
nameserver 114.114.114.114" > /data/data/com.termux/files/usr/etc/resolv.conf

# 方案 2:添加 hosts
echo "198.18.0.87 accounts.feishu.cn" >> /data/data/com.termux/files/usr/etc/hosts
echo "198.18.0.87 open.feishu.cn" >> /data/data/com.termux/files/usr/etc/hosts

# 方案 3:使用 IP 直接访问(临时)
curl -H "Host: open.feishu.cn" https://198.18.0.87/open-apis/auth/v3/tenant_access_token/internal

4. 消息发送失败(错误 9499)

症状:API 返回 {"code":9499,"msg":"Bad Request"}

原因:content 字段格式错误

错误示例:

# ❌ 错误:直接传递 dict
message_data = {
    "receive_id": "oc_xxxxxx",
    "msg_type": "text",
    "content": {"text": "Hello"}  # 错误!
}

正确示例:

import json

# ✅ 正确:content 必须是 JSON 字符串
message_data = {
    "receive_id": "oc_xxxxxx",
    "msg_type": "text",
    "content": json.dumps({"text": "Hello"})  # 正确!
}

# 发送时
json.dumps(message_data)  # 整个消息是 JSON,content 是嵌套的 JSON 字符串

完整 Python 示例:

import json
import urllib.request

APP_ID = "cli_xxxxxxxxxxxxxxxx"
APP_SECRET="your...n
# 获取 token
token_data = json.dumps({"app_id": APP_ID, "app_secret": APP_SECRET}).encode('utf-8')
token_req = urllib.request.Request(
    'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
    data=token_data,
    headers={'Content-Type': 'application/json'},
    method='POST'
)
with urllib.request.urlopen(token_req, timeout=30) as response:
    token_result = json.loads(response.read().decode('utf-8'))
    TOKEN=token_...n
# 发送消息(注意 content 是 JSON 字符串)
message_data = {
    "receive_id": "oc_xxxxxx",
    "msg_type": "text",
    "content": json.dumps({"text": "Hello"})  # ✅ 正确
}

msg_req = urllib.request.Request(
    'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
    data=json.dumps(message_data).encode('utf-8'),
    headers={
        'Authorization': f'Bearer {TOKEN}',
        'Content-Type': 'application/json'
    },
    method='POST'
)
with urllib.request.urlopen(msg_req, timeout=30) as response:
    result = json.loads(response.read().decode('utf-8'))
    print(result)

5. 卡片消息格式错误

症状:发送卡片消息失败,错误提示 table 相关

错误示例:

{
  "tag": "table",
  "headers": [...],  // ❌ 错误!table 不支持 headers
  "rows": [...]
}

正确示例:

{
  "tag": "table",
  "columns": [  // ✅ 正确!使用 columns
    {"tag": "text", "text": "列1", "width": "auto", "weight": 1},
    {"tag": "text", "text": "列2", "width": "auto", "weight": 1}
  ],
  "rows": [
    [{"tag": "text", "text": "数据1"}, {"tag": "text", "text": "数据2"}]
  ]
}

6. 用户 @ 了错误的机器人

症状:用户说 "我在飞书里 @ 你了",但日志中没有收到消息

原因:群里可能有多个机器人,用户 @ 了另一个机器人

检查:

# 查看机器人列表
lark contact user search --query "机器人"

# 或查看应用信息
curl -H "Authorization: Bearer <TOKEN>" \
  https://open.feishu.cn/open-apis/bot/v3/info

解决:

  1. 告诉用户正确的机器人名称
  2. 在群里发送消息说明正确的机器人
  3. 建议用户私聊正确的机器人

调试技巧

查看 Gateway 实时日志

# 前台运行(查看实时日志)
hermes gateway run

# 或查看日志文件
tail -f ~/.hermes/logs/gateway.log

测试飞书连接

# 获取 token
curl -s -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal \
  -H "Content-Type: application/json" \
  -d '{"app_id":"cli_xxxxxxxxxxxxxxxx","app_secret":"xxxxxx"}'

# 获取机器人信息
curl -H "Authorization: Bearer <TOKEN>" \
  https://open.feishu.cn/open-apis/bot/v3/info

# 获取群聊列表
curl -H "Authorization: Bearer <TOKEN>" \
  "https://open.feishu.cn/open-apis/im/v1/chats?page_size=20"

检查配置

# 查看所有配置
hermes config show

# 查看飞书特定配置
hermes config show | grep -A 10 "feishu"

# 查看环境变量
cat ~/.hermes/.env | grep FEISHU

参考