feat(channel): add Slack and localize channel plugins - #5
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 93c2d4aefb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e669283a5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa8c4c65d5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7ec9bedc1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7ec9bedc1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (const file of event.files ?? []) { | ||
| if (ctx.abortSignal.aborted) return; | ||
| const filePath = await downloadSlackFile(file, config.botToken, ctx.logger, { | ||
| signal: ctx.abortSignal, | ||
| }); |
There was a problem hiding this comment.
Cap aggregate Slack attachment downloads
When one allowed Slack message contains multiple attachments, the new 100 MiB limit is reset for every downloadSlackFile call while all completed files remain on disk until the entire loop finishes. A message with N individually valid files can therefore consume N × 100 MiB and keep the handler busy for N × 60 seconds, so the per-file fix still permits substantial disk exhaustion; enforce a total byte/file-count or whole-message timeout and clean up once that aggregate limit is reached.
Useful? React with 👍 / 👎.
| const handle = async ({ event, ack }: SlackEventArgs) => { | ||
| await ack(); | ||
| if (ctx.abortSignal.aborted) return; |
There was a problem hiding this comment.
Catch Slack acknowledgement failures
When the socket closes while an event is being acknowledged, or its WebSocket send otherwise rejects, ack() fails before execution enters this handler's try block. The Socket Mode client dispatches these async listeners through an event emitter without awaiting their returned promises, so this becomes an unhandled rejection instead of the logged handler failure and can terminate the Node host; include acknowledgement in the error boundary.
Useful? React with 👍 / 👎.
| const isDm = isDirectMessage(event); | ||
| const allowed = isDm | ||
| ? (event.user !== undefined && config.allowedIds.has(event.user)) || | ||
| config.allowedIds.has(event.channel) | ||
| : config.allowedIds.has(event.channel); |
There was a problem hiding this comment.
Filter unaddressed channel events before processing
When a channel ID is allowlisted, every message.channels or message.groups event passes this check regardless of whether the bot was mentioned. An ordinary top-level channel post therefore reaches the attachment-download and identity-binding path before the host can reject the eventual payload with mentionedBot: false, violating the documented mention-only behavior and making unrelated channel files consume the plugin's disk and network; reject unaddressed channel events before these side effects while preserving any explicitly supported active-thread replies.
Useful? React with 👍 / 👎.
Feishu, Slack, and Telegram currently expose fixed-language configuration, status, authentication, and command text. Register plugin-owned catalogs for en, es, ja, ko, zh-CN, and zh-TW and return deferred SDK messages across these surfaces. Direct platform notices translate at delivery; raw error diagnostics remain separate.
Slack inbound attachments are limited to 100 MiB per file and 60 seconds per download. Size metadata and Content-Length provide early rejection, streaming byte counts enforce the limit even when metadata is missing or incorrect, and cancellation removes partial files. Completed downloads are also cleaned up when delivery is cancelled or fails before the host accepts them. A token-only configuration can connect to Slack and return setup IDs; delivery remains blocked until the sender or channel is allowlisted. Update the configuration form, six locale catalogs, and setup guide accordingly.
Slack startup checks cancellation before and after authentication and connection, preventing a late socket from surviving shutdown. Download filenames stay within filesystem limits while retaining their extensions; valid HTML attachments are accepted while login pages remain rejected. Explicit DM threads use separate sessions, while unthreaded DM session keys stay unchanged.
Validate catalogs before publication, embed only name/description translations in the store registry, and include every registered locale file in release archives. Registry generation and release staging also compare source pluginMessage fallbacks with every catalog, so a placeholder renamed only in code fails publication even when the language files agree with each other. Document the literal-key/fallback convention and support SDK import aliases and namespace imports without executing plugin code. Resolve calls by lexical binding so parameters, local variables, catch bindings, and hoisted declarations can safely shadow SDK import names.
Includes the three existing, unmerged Slack implementation/documentation commits from the closed PR #3 because that remote base branch no longer exists. Plugin localization follows in separate commits. StackChan work is excluded.
Companion SDK/host change: https://github.com/marswaveai/cola/pull/5182
Validation:
Post-merge release steps: