2 Commits
Author SHA1 Message Date
Syed Osama Ali Shah 6f91b937c1 fix(slack): don't double-emit trailing text on odd number of ``` fences (#1436)
extractCodeBlocks split on "```" and treated every odd-indexed part as a
closed code block. With an odd number of fences (>=3), Split returns an even
number of parts, so the final segment -- which follows an unpaired opening
fence and must stay literal -- landed on an odd index and was both emitted as
a \x00CB\x00 placeholder (later restored as ```seg```) AND re-appended
verbatim by the trailing len(parts)%2==0 block. The segment was therefore
duplicated in the rendered Slack message (and blocks gained a spurious entry).
Unclosed trailing fences are common in streamed LLM output.

Exclude the final unpaired part from the paired-scan loop. Add a regression
test covering the closed-block-then-unpaired-fence case.
2026-07-15 00:54:17 +07:00
Duc Nguyen 137a986d4f feat(channels): add Slack channel (#83)
* feat(channels): add Slack channel via Socket Mode (#37)

Implement Slack integration using Socket Mode (xapp-/xoxb- tokens):
- Event-driven messaging via app_mention + message events
- Policy checks: open, pairing, allowlist, disabled (DM + group)
- Thread participation with configurable TTL
- Markdown-to-mrkdwn formatting pipeline
- Streaming support (edit-in-place + native ChatStreamer)
- SSRF-protected file downloads
- Debounce, dedup, reactions, group history context
- 170 unit tests (format, helpers, stream, SSRF)

Fix BaseChannel.HandleMessage allowlist to also check chatID,
enabling group allowlist with channel IDs across all channels.

Closes #37

* feat(slack): add file/media support and edit-to-mention handling

- Wire inbound file download into handleMessage (images, audio, documents)
- Add media.go with resolveMedia, classifyMime, buildMediaTags
- Extract shared ExtractDocumentContent to channels/media_utils.go (DRY with Telegram)
- Support file_share and message_changed subtypes
- Handle edit-to-mention: respond when user edits old message to add @bot
- Add MediaMaxBytes config field (default 20MB)
- Fix debounce media accumulation (was silently dropping files)
- Add 60s HTTP client timeout on file downloads
- Refactor downloadFile signature for slack.File compatibility
2026-03-09 07:02:37 +07:00