Conversation
Every human message posted in a tracked Discord thread is echoed as a reply under the Slack announcement, so the conversation can be followed from Slack. This needs the Web API, not the webhook. Threaded replies are addressed by the parent message's ts, and an Incoming Webhook answers "ok" without ever returning one — Slack's own docs point to the Events API or conversations.history to recover it. chat.postMessage returns it directly. - SlackApiClient posts through chat.postMessage with a bot token, reads the ok/error field inside the 200 body rather than trusting the status, and serialises posts ~1s apart to respect the per-channel rate limit. - SlackThreadMap persists discord_thread_id -> slack_ts in SQLite inside the Docker volume, so a redeploy does not orphan live threads. Purged at 30d. - The webhook stays as a fallback: with no bot token the bot still announces threads, just without mirroring, so a deploy without the token is not a regression. Skipped when mirroring: bots (the bot's own LLM answers are long, and Slack should carry the human conversation) and a forum post's opening message, which is already the body of the announcement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
crstian19
marked this pull request as draft
August 20, 2026 13:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Qué hace
Cada mensaje humano de un hilo vigilado se replica como respuesta bajo el anuncio en Slack, de modo que la conversación se sigue entera desde ahí.
Por qué hace falta el bot token
Las respuestas en hilo se direccionan con el
tsdel mensaje padre, y un Incoming Webhook respondeoksin devolverlo nunca. La doc de Slack lo dice explícitamente:chat.postMessagelo devuelve directamente, así que la migración no es preferencia sino requisito.Piezas
SlackApiClient—chat.postMessagecon bot token. Lee elok/errordentro del cuerpo 200 en lugar de fiarse del status (la Web API reporta los fallos ahí), no reintenta errores permanentes comonot_in_channel, y serializa los envíos con ~1 s de separación para respetar el límite por canal.bot/thread_map.py— persistediscord_thread_id → slack_tsen SQLite dentro del volumen de Docker, para que un redespliegue no deje huérfanos los hilos vivos. Purga a los 30 días.Qué no se replica
Los mensajes de bots (las respuestas del LLM son largas; Slack lleva la conversación humana) y el mensaje inicial de un post de foro, que ya es el cuerpo del anuncio.
Verificación
thread_tsen las respuestas, errores dentro de un 200, reintento sólo enratelimited, escapado, adjuntos, y los cuatro casos que se descartan.tsguardado → respuesta colgada del hilo, con el mensaje del bot y el inicial correctamente ignorados.ruff checkyruff format --checklimpios.Configuración nueva
🤖 Generated with Claude Code