Configuration du Support Slack en local
Slack est SaaS uniquement, donc « local » signifie un espace de travail Slack + une app jetables dont OAuth et les événements atteignent votre ordinateur portable. Le job contient une idée non évidente qui évite presque tous les obstacles : OAuth connect et le webhook d'événements ont des besoins de reachabilité opposés, donc vous les pointez vers des endroits différents.
- OAuth connect est médiatisé par le navigateur. Votre navigateur suit la redirection, donc
localhostest accessible. Aucun tunnel nécessaire. - Inbound events (Slack POSTant des messages pour devenir des tickets) sont server-to-server depuis le cloud de Slack. Slack ne peut pas atteindre
localhost, donc celui-ci a besoin d'un tunnel public.
Gardez la totalité de l'app et le flux OAuth sur localhost, et pointez uniquement Event Subscriptions (et Interactivity) vers le tunnel. Cela contourne aussi les limites de débit du tunnel gratuit, puisque le tunnel n'porte alors que les POSTs d'événements à faible volume de Slack plutôt que la totalité de la SPA.
Ceci est la variante conversations/SupportHog du guide générique
Slack local setup guide ; ce guide couvre l'app PostHog Desktop / notifications Slack (SLACK_APP_*, /integrations/slack/callback). Conversations utilise ses propres identifiants SUPPORT_SLACK_* et routes /api/conversations/v1/slack/*, mais les mécaniques de tunnel et SITE_URL sont identiques.
The endpoints
Tous sous products/conversations/backend/api/urls.py, préfixés /api/conversations/ :
| Route | Purpose | Reachability |
|---|---|---|
v1/slack/authorize |
returns the Slack OAuth URL (auth-gated) | browser (localhost) |
v1/slack/callback |
OAuth redirect target; built from SITE_URL, no forced https |
browser (localhost) |
v1/slack/events |
inbound event webhook | Slack's servers (tunnel) |
v1/slack/interactivity |
interactive component callbacks | Slack's servers (tunnel) |
Le callback requiert une session authentifiée sur n'importe quelle origine vers laquelle SITE_URL se résout, car le cookie de session est par-origine. Gardez SITE_URL sur localhost et connectez-vous là, et le callback conserve votre session.
Step 1 — credentials
SUPPORT_SLACK_APP_CLIENT_ID, SUPPORT_SLACK_APP_CLIENT_SECRET, et SUPPORT_SLACK_SIGNING_SECRET sont des paramètres dynamiques django-constance (posthog/settings/dynamic_settings.py) qui ciblent par défaut la variable d'env correspondante. Un id client vide produit « Support Slack OAuth client ID is not configured ». Mettez les valeurs de votre app Slack dans .env.local (gitignored) et redémarrez le backend :
SUPPORT_SLACK_APP_CLIENT_ID=<client id>
SUPPORT_SLACK_APP_CLIENT_SECRET=<client secret>
SUPPORT_SLACK_SIGNING_SECRET=<signing secret>
Constance stocke les valeurs en DB, et une valeur stockée surcharge le défaut env. Si elle se lit toujours comme non configurée après un redémarrage, vérifiez /admin/constance/config/ pour une valeur stockée vide et définez-la là à la place.
Step 2 — the Slack app
À api.slack.com/apps, créez une app dans un espace de travail jetable, puis :
- App Home → activez un bot user (donnez-lui un nom d'affichage). Sans cela, l'installation échoue avec « requesting permission to install a bot ... but it's not currently configured with a bot ».
- OAuth & Permissions → Bot Token Scopes — le flux demande ces scopes (depuis
SUPPORTHOG_SLACK_SCOPESdansproducts/conversations/backend/api/slack_oauth.py) :channels:history,channels:read,chat:write,chat:write.customize,files:read,files:write,groups:history,groups:read,reactions:read,users:read,users:read.email. Les attachments nécessitent les deux scopesfiles:dans les deux directions, donc un espace de travail installé sans eux affiche une bannière « reconnect » dans les paramètres de support. - OAuth & Permissions → Redirect URLs — ajoutez
http://localhost:8010/api/conversations/v1/slack/callbacket Save. Si Slack refuse une URL localhost en http simple, utilisez l'URL du tunnel pour le callback aussi et connectez-vous une fois sur l'origine du tunnel (voir references/troubleshooting.md). - Copiez le Client ID, Client Secret, et Signing Secret depuis Basic Information dans
.env.local(Step 1).
Step 3 — tunnel for inbound events
Exécutez n'importe quel tunnel HTTPS pointé vers Caddy sur 8010, réécrivant l'en-tête Host upstream vers localhost (le Caddy dev répond uniquement pour l'host localhost ; sans la réécriture vous obtenez un 200 vide et une page blanche) :
ngrok http --host-header=localhost 8010
# or, free with no rate limit:
cloudflared tunnel --url http://localhost:8010 --http-host-header localhost
Vérifiez qu'il atteint Django, pas juste Caddy :
curl -sS https://<tunnel-host>/_preflight | head -c 120 # want JSON, server: granian
Puis dans l'app Slack, définissez Event Subscriptions → Request URL (et Interactivity → Request URL si vous testez les boutons) à https://<tunnel-host>/api/conversations/v1/slack/events (et .../interactivity). Slack envoie un challenge url_verification synchrone à la sauvegarde, donc le backend doit être active ; le handler l'echo automatiquement.
La Request URL seule ne fait que passer la vérification ; elle ne livre rien jusqu'à ce que vous vous abonniez aux événements. Sous Event Subscriptions → Subscribe to bot events, ajoutez les événements que le backend traite (SUPPORT_EVENT_TYPES dans products/conversations/backend/api/slack_events.py) :
app_mentionmessage.channels(etmessage.groupspour les canaux privés), tous deux arrivant comme l'événementmessageinternereaction_addedmember_joined_channel,member_left_channel
Réinstallez l'app après avoir changé les scopes/événements pour que les nouveaux grants prennent effet.
Step 4 — connect and test
Parcourez l'app à http://localhost:8010, connectez-vous, allez dans les paramètres Support, et connectez Slack. Le round-trip OAuth se termine sur localhost. Puis invitez le bot dans un canal de votre espace de travail dev et postez un message ; il devrait arriver comme un ticket, et une réponse du ticket devrait poster en retour au thread.
Pour les modes d'échec qui méritent d'être reconnus (écran blanc, « Network error », incompatibilité de redirection, routage régional), voir references/troubleshooting.md.