关于 setting-up-support-slack-locally
为 SupportHog 本地开发环境连接临时 Slack 工作区的设置指南。它将浏览器 OAuth 保留在 localhost,并通过公网隧道接收 Slack 事件。
主要功能
- 01分离 OAuth 与事件网络路径
- 02配置 Slack 应用凭据和权限范围
- 03通过隧道接收事件与交互回调
- 04订阅支持的 Slack 事件
- 05测试消息转为支持工单
适用场景
- 01本地开发 Slack 支持集成
- 02验证频道消息创建工单
- 03测试工单回复发送到 Slack 线程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill setting-up-support-slack-locally安装后在 Claude Code 中输入/setting-up-support-slack-locally确认已加载。
附带文件references/troubleshooting.md
详细介绍
在本地设置 Support Slack
Slack 仅提供 SaaS 服务,因此“本地”指的是一个临时 Slack 工作区和应用,其 OAuth 和事件请求会发送到你的笔记本电脑。关键在于一个不太显而易见的做法,可以避开几乎所有障碍:OAuth 连接和事件 Webhook 对可访问性的要求相反,因此要将它们指向不同的位置。
- OAuth 连接通过浏览器进行。浏览器会跟随重定向,因此可以访问
localhost。无需隧道。 - 入站事件(Slack 发送 POST 请求,让消息变成工单)是 Slack 云端发起的服务器到服务器请求。Slack 无法访问
localhost,因此这部分需要公共隧道。
让整个应用和 OAuth 流程都使用 localhost,只将 Event Subscriptions(以及 Interactivity)指向隧道。这样也能避开免费隧道的速率限制,因为隧道只承载 Slack 低流量的事件 POST 请求,而不是整个 SPA。
这是通用 Slack 本地设置指南 的 conversations/SupportHog 变体;该指南介绍的是 PostHog Desktop / 通知 Slack 应用(SLACK_APP_*、/integrations/slack/callback)。Conversations 使用自己的 SUPPORT_SLACK_* 凭据和 /api/conversations/v1/slack/* 路由,但隧道和 SITE_URL 的机制相同。
端点
所有端点均位于 products/conversations/backend/api/urls.py 下,前缀为 /api/conversations/:
| 路由 | 用途 | 可访问方 |
|---|---|---|
v1/slack/authorize | 返回 Slack OAuth URL(需要通过身份验证) | 浏览器(localhost) |
v1/slack/callback | OAuth 重定向目标;根据 SITE_URL 生成,不强制使用 https | 浏览器(localhost) |
v1/slack/events | 入站事件 Webhook | Slack 服务器(隧道) |
v1/slack/interactivity | 交互式组件回调 | Slack 服务器(隧道) |
回调要求在 SITE_URL 解析到的源站上有经过身份验证的会话,因为会话 Cookie 按源站区分。将 SITE_URL 保持为 localhost 并在该地址登录,回调就能保留你的会话。
第 1 步 — 凭据
SUPPORT_SLACK_APP_CLIENT_ID、SUPPORT_SLACK_APP_CLIENT_SECRET 和 SUPPORT_SLACK_SIGNING_SECRET 是 django-constance 动态设置(posthog/settings/dynamic_settings.py),默认使用相应的环境变量。客户端 ID 为空时会显示“Support Slack OAuth client ID is not configured”。将 Slack 应用的值写入 .env.local(已加入 gitignore),然后重启后端:
SUPPORT_SLACK_APP_CLIENT_ID=<client id>
SUPPORT_SLACK_APP_CLIENT_SECRET=<client secret>
SUPPORT_SLACK_SIGNING_SECRET=<signing secret>
Constance 会将值存储在数据库中,已存储的值会覆盖环境变量默认值。如果重启后仍显示未配置,请检查 /admin/constance/config/ 中是否有空的已存储值,并在那里设置。
第 2 步——Slack 应用
在 api.slack.com/apps 创建一个应用,使用临时工作区,然后:
- App Home → 启用机器人用户(为其设置显示名称)。否则安装会失败,并显示“requesting permission to install a bot ... but it's not currently configured with a bot”。
- OAuth & Permissions → Bot Token Scopes——授权流程会请求以下权限(来自
products/conversations/backend/api/slack_oauth.py中的SUPPORTHOG_SLACK_SCOPES):channels:history、channels:read、chat:write、chat:write.customize、files:read、files:write、groups:history、groups:read、reactions:read、users:read、users:read.email。附件的收发都需要两个files:权限,因此未授予这两个权限的工作区安装后,会在支持设置中显示“重新连接”横幅。 - OAuth & Permissions → Redirect URLs——添加
http://localhost:8010/api/conversations/v1/slack/callback并保存。如果 Slack 拒绝纯 HTTP 的 localhost URL,也将隧道 URL 用作回调 URL,并在隧道源站上登录一次(参见 references/troubleshooting.md)。 - 将 Basic Information 中的 Client ID、Client Secret 和 Signing Secret 复制到
.env.local(第 1 步)。
第 3 步——用于接收传入事件的隧道
运行任意 HTTPS 隧道,将其指向 Caddy 的 8010 端口,并将上游 Host 标头改写为 localhost(开发环境中的 Caddy 只响应 localhost 主机;不改写的话会返回空的 200,页面一片空白):
ngrok http --host-header=localhost 8010
# or, free with no rate limit:
cloudflared tunnel --url http://localhost:8010 --http-host-header localhost
确认请求到达的是 Django,而不只是 Caddy:
curl -sS https://<tunnel-host>/_preflight | head -c 120 # want JSON, server: granian
然后在 Slack 应用中,将 Event Subscriptions → Request URL(如果要测试按钮,也设置 Interactivity → Request URL)设为 https://<tunnel-host>/api/conversations/v1/slack/events(以及 .../interactivity)。
Slack 保存设置时会同步发送 url_verification 挑战,因此后端必须已启动;处理程序会自动回传该挑战。
仅设置 Request URL 只能通过验证;订阅事件后才会收到事件。在
Event Subscriptions → Subscribe to bot events 下,添加后端处理的事件(products/conversations/backend/api/slack_events.py 中的 SUPPORT_EVENT_TYPES):
app_mentionmessage.channels(私密频道还需message.groups),两者都会作为内部的message事件到达reaction_addedmember_joined_channel、member_left_channel
更改权限或事件后,重新安装应用,使新的授权生效。
第 4 步——连接并测试
访问 http://localhost:8010,登录,进入支持设置,然后连接 Slack。OAuth 往返流程会在 localhost 上完成。接着将机器人邀请到开发工作区中的一个频道并发布消息;它应作为工单收到,从工单回复的内容也应发回对应的线程。
有关值得识别的故障模式(白屏、“Network error”、重定向不匹配、区域路由),请参见 references/troubleshooting.md。