channels.discord.activities 存在且客户端密钥可解析时,OpenClaw 才会注册 Activity HTTP 路由、show_widget 代理工具以及启动按钮处理程序。已弃用的 discord_widget 别名在一个版本周期内仍可用。
前提条件
- 一个已存在的 OpenClaw Discord 机器人
- 一个可公开访问、能够连接到 OpenClaw 网关的 HTTPS 主机名
- 有权限为该机器人的 Discord 应用配置 Activities 和 OAuth2
设置
1
通过 HTTPS 暴露网关
启动你的隧道或反向代理,并在添加 Activities 配置后验证
https://openclaw.example.com/discord/activity/ 能够访问到网关。将示例主机名替换为你自己的。2
在 Discord 中启用 Activities
在 Discord 开发者门户 中打开现有的 bot 应用。打开 Activities,启用 Activities,并创建一个 URL 映射:
- prefix:
ROOT(/) - target:
openclaw.example.com/discord/activity
/discord/activity,末尾没有斜杠。3
复制 OAuth2 客户端密钥
在开发者门户中打开 OAuth2。Discord 至少要求一个重定向 URI,因此如果应用还没有,请添加一个本地占位符,例如 loopback 地址;Embedded App SDK 会处理 Activity 返回流程。复制或重置应用的客户端密钥。请将其视为凭证:不要把它粘贴到聊天、日志或已提交的配置文件中。
4
配置 OpenClaw
向应该提供 widgets 的 Discord 账号添加一个块:当
DISCORD_CLIENT_SECRET 已设置时,你可以从该块中省略 clientSecret。但该块本身必须保留,以启用此功能。正常的 Discord 访问设置仍然是分开的。例如,allowFrom 仍然控制谁可以给 agent 发送私信;它不控制谁可以打开已经发布在频道中的 widget。5
重启并测试
重启网关。在 Discord 对话中,让 agent 显示一个交互式 widget。agent 会调用
show_widget;点击已发布消息上的 Open widget。安全模型
- 在返回小组件元数据之前,OAuth 会先识别 Discord 用户。
- Discord 的 Get Activity Instance API 必须确认 OAuth 用户当前存在于该 Activity 实例中。实例频道必须与发布小组件的频道一致。
- Discord 允许进入该频道的所有人都可以打开其小组件。要缩小受众范围,请使用 Discord 频道权限。OpenClaw 命令和 DM 白名单不会授予或移除对已发布频道内容的访问权限。
- OAuth 会话在 15 分钟后过期。小组件文档能力在 60 秒后过期,并且只能使用一次。
- 小组件在七天后过期,每个 Discord 插件实例最多保留 64 个。
- 小组件 HTML 由你的代理编写,应被视为受信任内容。不要嵌入你不希望有缺陷的小组件暴露的秘密信息。
- 小组件可以在其自身的嵌套框架内导航。
sandbox="allow-scripts"的 iframe 会阻止顶级导航、弹出窗口以及同源访问,而其内容安全策略会阻止网络连接和外部资源。这些控制属于纵深防御,不是针对编写该小组件的代理的安全边界。 - 当 Activities 被禁用时,
/discord/activity根本不会注册。
故障排除
活动显示“网关离线”
- 确认隧道正在运行,并且路由到了网关的实际绑定端口
- 确认 Developer Portal 目标包含
/discord/activity - 在更改 Discord 或 OpenClaw 配置后重启网关
- 检查网关日志中是否有关于缺少 Activities client secret 的单行警告
Discord 打开空白页面或报告 blocked:csp
- 验证 URL 映射使用了
ROOT,且没有额外添加第二个/discord/activity段 - 确认 shell、
shell.js和 SDK 模块都通过 Discord 代理返回 - 检查网关日志中
/discord/activity/下的请求