Discord Activities
Discord Activities 允许 agent 向当前 Discord 频道发布一个交互式、自包含的 HTML widget。消息包含一个 Open widget 按钮;点击它会在 Discord 内启动 widget。
该功能默认关闭。show_widget 仍然是核心拥有的工具之一。当存在 channels.discord.activities 并且客户端密钥解析成功时,Discord Activity 路由、启动按钮处理程序和当前频道展示器会在该工具背后变得可用。如果没有该配置块,针对公共 Activity 前缀的请求与未注册路由无法区分。不存在 Discord 专用的 widget 工具或别名。
先决条件¶
- 一个现有的 OpenClaw Discord 机器人
- 一个可访问 OpenClaw 网关的公共 HTTPS 主机名
- 为机器人的 Discord 应用配置 Activities 和 OAuth2 的权限
任何 HTTPS 反向代理或隧道均可。命名的 Cloudflare Tunnel 可提供稳定主机名,而无需直接暴露网关端口。
# ~/.cloudflared/config.yml
tunnel: openclaw-discord
credentials-file: /home/you/.cloudflared/TUNNEL-ID.json
ingress:
- hostname: openclaw.example.com
service: http://127.0.0.1:18789
- service: http_status:404
cloudflared tunnel login
cloudflared tunnel create openclaw-discord
cloudflared tunnel route dns openclaw-discord openclaw.example.com
cloudflared tunnel run openclaw-discord
保持普通网关身份验证启用。只有 Activity 前缀是公共的,并且插件自身会验证 OAuth、Activity 实例成员身份、频道绑定、会话和一次性文档能力。
设置¶
1. 通过 HTTPS 暴露网关
启动你的隧道或反向代理,并在添加 Activities 配置后验证 https://openclaw.example.com/discord/activity/ 能到达网关。将示例主机名替换为你自己的主机名。
2. 在 Discord 中启用 Activities
在 Discord 开发者门户 中打开现有的机器人应用。打开 Activities,启用 Activities,并创建 URL 映射:
- 前缀:
ROOT(/) - 目标:
openclaw.example.com/discord/activity
目标是公共主机名加上 /discord/activity,末尾不带斜杠。
3. 复制 OAuth2 客户端密钥
在开发者门户中打开 OAuth2。Discord 要求至少一个重定向 URI,因此如果应用尚未配置,请添加本地占位符,例如回环地址;Embedded App SDK 会处理 Activity 返回流程。复制或重置应用客户端密钥。将其视为凭据:不要将其粘贴到聊天、日志或已提交的配置文件中。
4. 配置 OpenClaw
在应提供 widget 的 Discord 账户中添加一个配置块:
{
channels: {
discord: {
token: "${DISCORD_BOT_TOKEN}",
activities: {
clientSecret: "${DISCORD_CLIENT_SECRET}",
// Optional. Defaults to the bot application ID learned at startup.
applicationId: "YOUR_DISCORD_APPLICATION_ID",
},
},
},
}
当设置了 DISCORD_CLIENT_SECRET 时,可以从该配置块中省略 clientSecret。该配置块本身必须存在才能选择加入。
普通 Discord 访问设置仍然独立。例如,allowFrom 仍控制谁可以向 agent 发送私信;它不控制谁可以打开已发布在频道中的 widget。
5. 验证和测试
配置更改遵循 热重载。如果你更改了其服务环境以提供客户端密钥,请重启 Gateway。在 Discord 对话中,要求 agent 显示一个交互式 widget。agent 会调用 show_widget;在已发布的消息上点击 Open widget。
Core 在将 widget 文档交给 Discord 之前会对其进行验证和包装。展示器接受最多 48 KiB 的 HTML 源,存储规范组合文档,并始终将 Activity 按钮标记为 Open widget。由于仪表盘状态仍由核心拥有,标准的 show_widget 固定、名称、选项卡、大小、框架、排序和能力字段仍然可用。当 Discord 是唯一可用的展示路由时,不会提供已注册的非 HTML widget 类型。
安全模型¶
- OAuth 会在返回 widget 元数据之前识别 Discord 用户。
- Discord 的 Get Activity Instance API 必须确认 OAuth 用户存在于当前 Activity 实例中。实例频道必须与发布 widget 的频道匹配。
- 所有被 Discord 允许进入该频道的人都可以打开其中的 widget。若要缩小受众范围,请使用 Discord 频道权限。OpenClaw 命令和私信允许列表不会授予或移除对已发布频道内容的访问权限。
- OAuth 会话在 15 分钟后过期。Widget 文档能力在 60 秒后过期,且仅可使用一次。
- Widget 在七天后过期,每个 Discord 插件实例最多保留 64 个。
- Widget HTML 由你的 agent 编写,应被视为可信内容。不要嵌入你不希望有缺陷的 widget 暴露的机密。
- Widget 可以在其自身的嵌套框架内导航。
sandbox="allow-scripts"iframe 会阻止顶层导航、弹出窗口和同源访问。其内容安全策略允许共享的 widget CDN 脚本、样式表和字体,同时阻止 API 连接和其他外部资源。这些控制措施属于纵深防御,而不是针对编写该 widget 的 agent 的安全边界。 - 当 Activities 被禁用或其所需的账户凭据不可用时,路由在内部仍保持注册,但
/discord/activity下的公共请求会保持未处理,并返回正常的 404。
启用后,公共 Activity 外壳和令牌交换路由可通过你的隧道访问。它们不会在没有有效 OAuth 会话和一次性文档能力的情况下暴露 widget HTML。
故障排除¶
Activity 显示“Gateway offline”¶
- 确认隧道正在运行,并路由到网关的实际绑定端口
- 确认开发者门户目标包含
/discord/activity - 确认 热重载 已应用 OpenClaw 配置;如果你更改了其服务环境,请重启 Gateway
- 确认 Discord 机器人令牌和 Activities 客户端密钥都在运行中的网关中解析成功;不完整的凭据会使
/discord/activity在外部隐藏在正常的 404 之后
Discord 打开空白页面或报告 blocked:csp¶
- 验证 URL 映射使用
ROOT,并且没有添加第二个/discord/activity段 - 确认 shell、
shell.js和 SDK 模块都通过 Discord 代理返回 - 检查 gateway 日志中
/discord/activity/下的请求
Widget API 连接会被阻止。请嵌入 widget 所需的数据和图片。脚本、样式表和字体可以使用共享 widget CDN 允许列表;当 CDN 资源无法加载时,请同时检查 widget 的资源 URL 和 Discord 的代理行为。
“小部件不可用”¶
从智能体发布按钮的频道启动该按钮。OpenClaw 会在点击时于服务端跟踪启动记录,因此即使 Discord 省略或损坏按钮的自定义 ID,新的启动记录也可以解析出确切的 widget。当自定义 ID 和启动记录都无法解析时,OpenClaw 会打开该频道中最近发布的实时 widget。旧 widget 仍可通过保留其自定义 ID 的按钮访问。
“无法在此频道启动 Activities”¶
Discord 不会从论坛式频道启动 Activities。OpenClaw 会拒绝在那里投递 Activity 组件,而不是发布一个无法工作的按钮。请改为从普通文本频道请求 widget。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw