Skip to content

Add Slack support via unified entry point with symmetric adapter pattern#25

Closed
Copilot wants to merge 6 commits intomainfrom
copilot/add-slack-support
Closed

Add Slack support via unified entry point with symmetric adapter pattern#25
Copilot wants to merge 6 commits intomainfrom
copilot/add-slack-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 22, 2026

Adds Slack as a supported platform alongside Discord using a symmetric adapter pattern. Both platforms now use the same architecture — commands are fully decoupled from Discord.js and receive messages through platform-specific adapters. A single npm start auto-detects which platforms to run based on environment variables, supporting Discord only, Slack only, or both simultaneously.

Approach

A unified index.js entry point loads commands once, then starts whichever platforms have tokens configured. Platform-specific logic is encapsulated in lib/platforms/discord.js and lib/platforms/slack.js. Commands export only { commandName, execute } and have no dependency on Discord.js events.

// Unified entry point starts platforms based on env vars
const startups = [];
if (discordEnabled) startups.push(startDiscord({ commands, db }));
if (slackEnabled) startups.push(startSlack({ commands, db }));
await Promise.all(startups);

Changes

  • lib/adapters/discord.jsDiscordMessageAdapter class (thin wrapper for architectural consistency)
  • lib/adapters/slack.jsSlackMessageAdapter class + embedToBlocks converter (Discord EmbedBuilder → Slack Block Kit)
  • lib/platforms/discord.js — Discord platform startup logic (client setup, message listener, reminder daemon)
  • lib/platforms/slack.js — Slack platform startup logic (@slack/bolt Socket Mode, message listener, reminder daemon)
  • index.js — Unified entry point that auto-detects and starts Discord, Slack, or both simultaneously
  • All 25 command files — Removed Events import and name/once properties, decoupling from discord.js event system
  • package.json@slack/bolt dependency
  • README.md / docs/getting-started.md — Updated docs showing unified usage for Discord, Slack, or both; Docker examples
  • 6 pre-existing lint fixes — Fixed no-useless-assignment errors in commands and lib files

Config

Variable Required Notes
AVA_DISCORD_TOKEN Yes (Discord) Discord bot token
AVA_SLACK_BOT_TOKEN Yes (Slack) xoxb- bot token
AVA_SLACK_APP_TOKEN Yes (Slack) xapp- app-level token for Socket Mode
AVA_SLACK_SIGNING_SECRET No Only needed for HTTP mode
# Discord only
AVA_DISCORD_TOKEN=<token> npm start

# Slack only
AVA_SLACK_BOT_TOKEN=<bot-token> AVA_SLACK_APP_TOKEN=<app-token> npm start

# Both simultaneously
AVA_DISCORD_TOKEN=<token> AVA_SLACK_BOT_TOKEN=<bot-token> AVA_SLACK_APP_TOKEN=<app-token> npm start

The Docker image works for all configurations — just pass the relevant env vars:

docker run -e AVA_DISCORD_TOKEN="<token>" -e AVA_SLACK_BOT_TOKEN="<bot-token>" -e AVA_SLACK_APP_TOKEN="<app-token>" circa10a/ava
Original prompt

Make a PR addressing the one ope issue which is to also support slack in addition to discord. All existing commands should work the same way as the discord implementation and ideally use the same logic. Documentation should also be updated


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 22, 2026 02:29
- Add @slack/bolt dependency for Slack integration
- Create SlackMessageAdapter to normalize Slack events to Discord message interface
- Create slack.js entry point with Socket Mode support
- Add start:slack npm script
- Add Slack reminder daemon
- Update README.md and getting-started.md with Slack setup instructions

Co-authored-by: circa10a <21261388+circa10a@users.noreply.github.com>
Co-authored-by: circa10a <21261388+circa10a@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for Slack alongside Discord Add Slack support via message adapter pattern Feb 22, 2026
Copilot AI requested a review from circa10a February 22, 2026 02:32
Comment thread slack.js Outdated
}

// Listen for messages starting with the ava prefix
app.message(new RegExp(`^${avaPrefix}`, 'i'), async ({ message, client }) => {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compiling regex on every message is fairly CPU intensive. This isn't great

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 61de5ec — the regex is now pre-compiled once as a module-level constant (avaPrefixRegex) in both slack.js and index.js, instead of being created on every message.

Comment thread lib/adapters/slack.js
@@ -0,0 +1,139 @@
import logger from '../logger/logger.js';
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have a slack adapter, we should replace the existing architecture to leverage a "discord" adapter also

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 61de5ec — created lib/adapters/discord.js with a DiscordMessageAdapter and refactored index.js to use the same adapter dispatch pattern as slack.js. Both entry points are now symmetric: load commands → listen for prefix → wrap with adapter → dispatch. Also removed Events import and name/once properties from all 25 command files to fully decouple them from discord.js.

@circa10a
Copy link
Copy Markdown
Owner

@copilot address open comments and resolve issues in CI

…le regex, fix lint errors

- Create lib/adapters/discord.js with DiscordMessageAdapter
- Refactor index.js to use adapter pattern matching slack.js architecture
- Pre-compile regex in both slack.js and index.js (no per-message compilation)
- Remove Events import from all 25 command files (decouple from discord.js)
- Fix 6 pre-existing no-useless-assignment lint errors in commands and lib files

Co-authored-by: circa10a <21261388+circa10a@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 22, 2026

@copilot address open comments and resolve issues in CI

Addressed both review comments and fixed CI in 61de5ec:

  • Pre-compiled regex (no per-message compilation)
  • Created Discord adapter + refactored index.js to symmetric adapter pattern
  • Removed discord.js Events coupling from all 25 command files
  • Fixed all 6 pre-existing no-useless-assignment lint errors that were failing CI

Copilot AI changed the title Add Slack support via message adapter pattern Add Slack support via symmetric message adapter pattern Feb 22, 2026
Copilot AI requested a review from circa10a February 22, 2026 17:18
Comment thread package.json Outdated
"lint": "eslint .",
"fix-lint": "eslint . --fix",
"start": "node --no-deprecation ./index.js",
"start:slack": "node --no-deprecation ./slack.js",
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can not run both simultaneously? What about the docker image?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0672c98. index.js is now a unified entry point that auto-detects platforms based on which env vars are set. A single npm start runs Discord, Slack, or both simultaneously. The Docker image needs no CMD override — just pass the relevant env vars:

# Both platforms simultaneously
docker run -e AVA_DISCORD_TOKEN="<token>" -e AVA_SLACK_BOT_TOKEN="<bot-token>" -e AVA_SLACK_APP_TOKEN="<app-token>" circa10a/ava

Removed the separate slack.js entry point and start:slack script. Platform logic extracted into lib/platforms/discord.js and lib/platforms/slack.js.

Copilot AI and others added 2 commits March 3, 2026 21:47
…multaneously

- Refactor index.js to auto-detect platforms based on which env vars are set
- Extract platform logic into lib/platforms/discord.js and lib/platforms/slack.js
- Remove separate slack.js entry point and start:slack script
- Docker image works for all configs via env vars alone (no CMD override)
- Update README and docs to show unified usage

Co-authored-by: circa10a <21261388+circa10a@users.noreply.github.com>
Co-authored-by: circa10a <21261388+circa10a@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 3, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • discord.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node index.js (dns block)
  • slack.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add Slack support via symmetric message adapter pattern Add Slack support via unified entry point with symmetric adapter pattern Mar 3, 2026
Copilot AI requested a review from circa10a March 3, 2026 21:49
@circa10a circa10a closed this Mar 4, 2026
@circa10a circa10a deleted the copilot/add-slack-support branch March 4, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants