Skip to content

feat: add Discord bridge for NemoClaw agent chat - #68

Closed
BioInfo wants to merge 1 commit into
NVIDIA:mainfrom
BioInfo:feat/discord-bridge
Closed

feat: add Discord bridge for NemoClaw agent chat#68
BioInfo wants to merge 1 commit into
NVIDIA:mainfrom
BioInfo:feat/discord-bridge

Conversation

@BioInfo

@BioInfo BioInfo commented Mar 17, 2026

Copy link
Copy Markdown

This pull request adds Discord bridge support to NemoClaw, enabling users to interact with the OpenClaw agent through Discord.

Changes

  • scripts/discord-bridge.js: New Discord bot that forwards messages to the OpenClaw agent inside the sandbox, mirroring the existing Telegram bridge
  • scripts/start-services.sh: Updated service management to start Discord bridge when DISCORD_BOT_TOKEN is set
  • docs/deployment/set-up-discord-bridge.md: Complete setup guide for deploying the Discord bridge

Features

  • Forward Discord messages to OpenClaw agent with full session support
  • Optional channel restrictions via DISCORD_CHANNEL_ID environment variable
  • Optional user restrictions via ALLOWED_USER_IDS environment variable
  • Automatic message chunking for Discord's 2000-character message limit
  • Typing indicators shown while agent is processing
  • Concurrent run protection per user to prevent overlapping requests
  • SPDX headers and code style matching upstream standards

Setup

  1. Create a Discord bot via Discord Developer Portal
  2. Set the bot token:
    export DISCORD_BOT_TOKEN=<your-token>
    export NVIDIA_API_KEY=<your-api-key>
  3. Start services:
    nemoclaw start

See docs/deployment/set-up-discord-bridge.md for complete instructions.

Summary by CodeRabbit

  • New Features

    • Added a Discord bridge to forward messages between a Discord bot and the OpenClaw agent, with optional channel/user filters and service controls.
  • Documentation

    • Added a step-by-step guide for deploying and configuring the Discord bridge, startup, verification, and shutdown.
  • Chores

    • Adjusted Docker ignore rules so bridge build artifacts are included in Docker build context.

@wscurran

Copy link
Copy Markdown
Contributor

Thanks for adding the Discord bridge support, this will provide another channel for users to interact with their NemoClaw agents and expand the ways they can use our platform.

@wscurran wscurran added integration: discord Discord integration or channel behavior integration: telegram Telegram integration or channel behavior labels Mar 20, 2026
@cv

cv commented Mar 21, 2026

Copy link
Copy Markdown
Collaborator

Hey @BioInfo — a Discord bridge for agent chat is a cool idea! Wanted to let you know that main has been a moving target lately: we've added CI automation, landed new features, and done some restructuring. Before we dive into reviewing this, it would really help if you could rebase onto the latest main. That way we can see how it fits with everything that's landed since. Looking forward to checking it out!

@BioInfo
BioInfo force-pushed the feat/discord-bridge branch from 91db0fd to 29cf0ac Compare March 22, 2026 02:49
@coderabbitai

coderabbitai Bot commented Mar 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a Discord bridge: new bot script and launcher, updates service orchestration to run the bridge, documentation for setup, and a Docker ignore negation to include nemoclaw/dist/ in Docker build context.

Changes

Cohort / File(s) Summary
Docker Configuration
./.dockerignore
Added negation rule (!nemoclaw/dist/) so nemoclaw/dist/ is included in Docker build context despite a general /dist ignore.
Discord Bridge Runtime
scripts/discord-bridge.js, scripts/start-discord-bridge.sh
New Node.js Discord bot that forwards messages to an OpenClaw agent via SSH with per-user locks, message filtering, typing indicators, response chunking; new launcher loads token from pass and execs the bot.
Service Orchestration
scripts/start-services.sh
Added discord-bridge to start/stop/status logic and adjusted startup warnings to require at least one bridge token.
Documentation
docs/deployment/set-up-discord-bridge.md
New setup guide covering Discord app/bot creation, required env vars (DISCORD_BOT_TOKEN) and optional controls (DISCORD_CHANNEL_ID, ALLOWED_USER_IDS), running/verifying the bridge, and shutdown steps.

Sequence Diagram

sequenceDiagram
    actor User as Discord User
    participant Bot as Discord Bot
    participant SSH as SSH / nemoClaw host
    participant Agent as OpenClaw Agent

    User->>Bot: Send message (DM, mention, or channel)
    Bot->>Bot: Apply guild/channel/user filters
    alt Accepted
        Bot->>Bot: Acquire per-user lock
        Bot->>Bot: Create sessionId (discord-<userId>)
        Bot->>SSH: Spawn SSH running "nemoclaw-start openclaw agent ..." with message & sessionId
        Bot->>Bot: Start typing indicator
        SSH->>Agent: Execute agent in sandbox
        Agent-->>SSH: Return stdout/stderr
        SSH-->>Bot: Return combined output (filtered)
        alt Success
            Bot->>Bot: Split output into ≤1950-char chunks
            Bot->>User: Reply with first chunk
            Bot->>User: Send remaining chunks
        else Error
            Bot->>User: Reply with error/truncated stderr
        end
        Bot->>Bot: Stop typing indicator and release lock
    else Rejected
        Bot->>Bot: Ignore message
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 I hopped a message over wires and keys,
Sent it through SSH, watched the agent sneeze,
Locks kept my pathways tidy, chunks fit the chat,
Discord and sandbox met — I balanced on a mat,
NemoClaw hums along; I nibble a celebratory carrot.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding Discord bridge functionality to enable NemoClaw agent chat via Discord.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (3)
scripts/discord-bridge.js (1)

20-20: Unused import.

execSync is imported but never used in this file.

Proposed fix
-const { execSync, spawn } = require("child_process");
+const { spawn } = require("child_process");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/discord-bridge.js` at line 20, Remove the unused import execSync from
the require call at the top of scripts/discord-bridge.js; update the
destructuring to only import spawn (i.e., change const { execSync, spawn } =
require("child_process") to only include spawn) so there is no unused symbol
left in the module.
docs/deployment/set-up-discord-bridge.md (2)

72-72: Passive voice detected.

"The Discord bridge starts only when..." uses passive construction. Rewrite in active voice.

Proposed fix
-The Discord bridge starts only when the `DISCORD_BOT_TOKEN` environment variable is set.
+The `start` command launches the Discord bridge only when you set the `DISCORD_BOT_TOKEN` environment variable.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-discord-bridge.md` at line 72, Rewrite the passive
sentence to active voice: replace "The Discord bridge starts only when the
`DISCORD_BOT_TOKEN` environment variable is set." with an active construction
that names the actor (e.g., "The application starts the Discord bridge only when
you set the `DISCORD_BOT_TOKEN` environment variable" or "We start the Discord
bridge only when the `DISCORD_BOT_TOKEN` environment variable is set"). Ensure
the environment variable name `DISCORD_BOT_TOKEN` remains unchanged.

87-88: Multiple sentences on one line.

This line contains two sentences. Per formatting rules, use one sentence per line to make diffs readable.

Proposed fix
-You can either mention the bot directly in a channel or send a direct message.
-The bridge forwards the message to the OpenClaw agent inside the sandbox and returns the agent response.
+You can either mention the bot directly in a channel or send a direct message.
+The bridge forwards the message to the OpenClaw agent inside the sandbox.
+The agent response is returned to the channel.

Note: Also rewrote to active voice ("The agent response is returned" → split into active statements).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-discord-bridge.md` around lines 87 - 88, Split the
two-sentence line into separate lines so each sentence is on its own line and
rewrite to active voice; replace the single line containing "You can either
mention the bot directly in a channel or send a direct message. The bridge
forwards the message to the OpenClaw agent inside the sandbox and returns the
agent response." with three lines like: "You can either mention the bot directly
in a channel or send a direct message." "The bridge forwards the message to the
OpenClaw agent inside the sandbox." "The agent returns a response to the
bridge." to satisfy one-sentence-per-line formatting and avoid passive phrasing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/deployment/set-up-discord-bridge.md`:
- Around line 118-121: Change the bottom section heading "Related Topics" to
"Next Steps" in this markdown file; locate the header line that currently reads
"## Related Topics" and replace it with "## Next Steps" while keeping the
existing bullet links (the deploy-to-remote-gpu.md and ../reference/commands.md
entries) unchanged so the navigation and links remain intact.
- Line 21: The H1 heading "Set Up the Discord Bridge" does not match the
frontmatter key title.page ("Set Up the NemoClaw Discord Bridge for Remote Agent
Chat"); update the H1 heading at the top of the document to exactly match the
title.page value so they are identical (ensure the line that begins with "#" is
replaced with "# Set Up the NemoClaw Discord Bridge for Remote Agent Chat").

In `@scripts/start-discord-bridge.sh`:
- Line 3: The current single-line export of DISCORD_BOT_TOKEN masks the exit
status of `pass show api-keys/nemoclaw-discord-token`; run the command first
into a temporary variable (e.g. token="$(pass show
api-keys/nemoclaw-discord-token 2>/dev/null | head -1)"), check the command's
exit status and/or whether token is empty, and only then export
DISCORD_BOT_TOKEN="$token" or abort with a clear error and non-zero exit;
reference the DISCORD_BOT_TOKEN export and the `pass show
api-keys/nemoclaw-discord-token` invocation when making the change.
- Line 11: The script start-discord-bridge.sh uses a hardcoded absolute path in
the exec call which breaks portability; change the exec invocation to compute
the discord-bridge.js path relative to the script's directory (use the script
dir resolution technique used in start-services.sh) and then exec node with that
constructed path instead of /home/bioinfo/...; update the exec line referencing
discord-bridge.js so it derives the script directory (e.g., via a DIR or
SCRIPT_DIR variable computed from $0) and joins it with
../scripts/discord-bridge.js before calling node.

In `@scripts/start-services.sh`:
- Around line 148-152: The Discord bridge start is missing the SANDBOX_NAME env
var so discord-bridge.js may not receive the same sandbox as Telegram; update
the start_service invocation for the discord-bridge (the start_service
discord-bridge block that runs node "$REPO_DIR/scripts/discord-bridge.js") to
pass SANDBOX_NAME="$SANDBOX_NAME" in the environment like the Telegram bridge
does, ensuring discord-bridge.js reads the intended sandbox value.

---

Nitpick comments:
In `@docs/deployment/set-up-discord-bridge.md`:
- Line 72: Rewrite the passive sentence to active voice: replace "The Discord
bridge starts only when the `DISCORD_BOT_TOKEN` environment variable is set."
with an active construction that names the actor (e.g., "The application starts
the Discord bridge only when you set the `DISCORD_BOT_TOKEN` environment
variable" or "We start the Discord bridge only when the `DISCORD_BOT_TOKEN`
environment variable is set"). Ensure the environment variable name
`DISCORD_BOT_TOKEN` remains unchanged.
- Around line 87-88: Split the two-sentence line into separate lines so each
sentence is on its own line and rewrite to active voice; replace the single line
containing "You can either mention the bot directly in a channel or send a
direct message. The bridge forwards the message to the OpenClaw agent inside the
sandbox and returns the agent response." with three lines like: "You can either
mention the bot directly in a channel or send a direct message." "The bridge
forwards the message to the OpenClaw agent inside the sandbox." "The agent
returns a response to the bridge." to satisfy one-sentence-per-line formatting
and avoid passive phrasing.

In `@scripts/discord-bridge.js`:
- Line 20: Remove the unused import execSync from the require call at the top of
scripts/discord-bridge.js; update the destructuring to only import spawn (i.e.,
change const { execSync, spawn } = require("child_process") to only include
spawn) so there is no unused symbol left in the module.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9f5ed6cb-f458-4025-8eb1-8201867a0027

📥 Commits

Reviewing files that changed from the base of the PR and between 845f2cd and 29cf0ac.

📒 Files selected for processing (5)
  • .dockerignore
  • docs/deployment/set-up-discord-bridge.md
  • scripts/discord-bridge.js
  • scripts/start-discord-bridge.sh
  • scripts/start-services.sh

Comment thread docs/deployment/set-up-discord-bridge.md Outdated
Comment thread docs/deployment/set-up-discord-bridge.md Outdated
Comment thread scripts/start-discord-bridge.sh Outdated
Comment thread scripts/start-discord-bridge.sh Outdated
Comment thread scripts/start-services.sh
@BioInfo
BioInfo force-pushed the feat/discord-bridge branch from 29cf0ac to 01f3662 Compare March 22, 2026 03:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
docs/deployment/set-up-discord-bridge.md (3)

24-24: Use active voice in the intro sentence.

“The Discord bridge is an auxiliary service managed by nemoclaw start.” is passive. Rewrite this sentence in active voice.

As per coding guidelines, "Active voice required. Flag passive constructions."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-discord-bridge.md` at line 24, Rewrite the passive
intro sentence "The Discord bridge is an auxiliary service managed by `nemoclaw
start`." into active voice by making the subject perform the action; for
example, change it to something like "`nemoclaw start` manages the Discord
bridge as an auxiliary service" or "`nemoclaw start` starts and manages the
Discord bridge," and replace the original sentence in the document.

100-100: Use present tense instead of future tense.

“The bot will only respond...” should be rewritten in present tense to match the docs voice rules.

As per coding guidelines, "Present tense. Flag future tense ('will') in descriptions of current behavior."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-discord-bridge.md` at line 100, Change the sentence
"The bot will only respond to messages in the specified channel." to present
tense; replace "will only respond" with "only responds" so the line reads "The
bot only responds to messages in the specified channel." Update the exact
sentence in the docs where that text appears (search for the quoted phrase) to
match the project's present-tense voice.

26-29: Add an introductory sentence under each H2 before lists.

The sections Prerequisites, Add the Bot to Your Server, and Next Steps start directly with lists. Add one short introductory sentence under each heading before list items.

As per coding guidelines, "Sections use H2 and H3, each starting with an introductory sentence."

Also applies to: 40-49, 119-121

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-discord-bridge.md` around lines 26 - 29, Add a single
short introductory sentence under each H2 heading that currently begins directly
with a list (specifically "Prerequisites", "Add the Bot to Your Server", "Next
Steps" and the other H2 blocks around lines 40-49 and 119-121) so each H2 is
followed by one brief sentence summarizing the section before the bullet points;
edit the Markdown around those headings to insert a one-line intro (e.g.,
"Before you begin, ensure the following:" style) so every H2 is immediately
followed by an introductory sentence per the documentation guidelines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/deployment/set-up-discord-bridge.md`:
- Line 24: Rewrite the passive intro sentence "The Discord bridge is an
auxiliary service managed by `nemoclaw start`." into active voice by making the
subject perform the action; for example, change it to something like "`nemoclaw
start` manages the Discord bridge as an auxiliary service" or "`nemoclaw start`
starts and manages the Discord bridge," and replace the original sentence in the
document.
- Line 100: Change the sentence "The bot will only respond to messages in the
specified channel." to present tense; replace "will only respond" with "only
responds" so the line reads "The bot only responds to messages in the specified
channel." Update the exact sentence in the docs where that text appears (search
for the quoted phrase) to match the project's present-tense voice.
- Around line 26-29: Add a single short introductory sentence under each H2
heading that currently begins directly with a list (specifically
"Prerequisites", "Add the Bot to Your Server", "Next Steps" and the other H2
blocks around lines 40-49 and 119-121) so each H2 is followed by one brief
sentence summarizing the section before the bullet points; edit the Markdown
around those headings to insert a one-line intro (e.g., "Before you begin,
ensure the following:" style) so every H2 is immediately followed by an
introductory sentence per the documentation guidelines.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a430c416-4dd7-404f-a46f-cc8df13d0d26

📥 Commits

Reviewing files that changed from the base of the PR and between 29cf0ac and 01f3662.

📒 Files selected for processing (5)
  • .dockerignore
  • docs/deployment/set-up-discord-bridge.md
  • scripts/discord-bridge.js
  • scripts/start-discord-bridge.sh
  • scripts/start-services.sh
✅ Files skipped from review due to trivial changes (2)
  • .dockerignore
  • scripts/discord-bridge.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/start-discord-bridge.sh
  • scripts/start-services.sh

Add Discord bridge support to NemoClaw, mirroring the existing Telegram
bridge functionality. Users can now interact with the OpenClaw agent
through Discord messages.

Changes:
- Add scripts/discord-bridge.js: Discord bot that forwards messages to
  the OpenClaw agent inside the sandbox
- Update scripts/start-services.sh: Add Discord bridge service
  management alongside Telegram bridge
- Add docs/deployment/set-up-discord-bridge.md: Complete setup guide
  for Discord bridge deployment

Features:
- Forward Discord messages to OpenClaw agent
- Support optional channel restrictions via DISCORD_CHANNEL_ID
- Support optional user restrictions via ALLOWED_USER_IDS
- Automatic message chunking for Discord 2000-char limit
- Typing indicators during agent processing
- Concurrent run protection per user

Signed-off-by: Justin Johnson <jhjohnsn@gmail.com>
@BioInfo
BioInfo force-pushed the feat/discord-bridge branch from 01f3662 to 0eb9794 Compare March 22, 2026 03:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
scripts/discord-bridge.js (3)

189-189: Consider handling login failures.

client.login() returns a Promise that rejects on authentication failure (invalid token, network issues). Currently, a failure results in an unhandled rejection.

Proposed fix
-client.login(TOKEN);
+client.login(TOKEN).catch((err) => {
+  console.error(`Failed to login: ${err.message}`);
+  process.exit(1);
+});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/discord-bridge.js` at line 189, client.login(TOKEN) can reject
(invalid token/network) and currently causes an unhandled promise rejection;
wrap the login in a promise handler or an async try/catch (e.g., await
client.login(TOKEN) inside an async IIFE) and on failure log the error (include
error details) and exit with a non-zero code (process.exit(1)); ensure you
reference the same client.login and TOKEN symbols so the rejection is caught and
handled gracefully.

136-139: Consider initial typing call placement.

Line 139 sends an immediate typing indicator, but it's placed after the setInterval setup. While functionally correct, consider moving the immediate call before setInterval for clearer intent, or remove the duplicate since setInterval with an immediate first call pattern isn't being used.

Minor readability nit—no functional issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/discord-bridge.js` around lines 136 - 139, The immediate call to
msg.channel.sendTyping() is placed after creating typingInterval which reduces
clarity; either remove the duplicate call or move the immediate
msg.channel.sendTyping() before const typingInterval = setInterval(...) so the
pattern "send once immediately, then every 5s" is explicit; update the code
around typingInterval and the two msg.channel.sendTyping() calls to implement
one of these two options for clearer intent.

21-21: Unused import.

The path module is imported but never used in this file.

 const { Client, GatewayIntentBits, Partials } = require("discord.js");
 const { spawn } = require("child_process");
-const path = require("path");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/discord-bridge.js` at line 21, The file imports the Node 'path'
module via the const path = require("path") statement but never uses it; remove
that unused import to clean up the module (or if path functionality is intended,
replace/remove usages accordingly). Locate the require("path") binding (the
const path variable) in scripts/discord-bridge.js and delete the line, or
alternatively implement the intended path usage where referenced; ensure no
other code refers to the removed symbol and run lint/tests to confirm.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/discord-bridge.js`:
- Line 189: client.login(TOKEN) can reject (invalid token/network) and currently
causes an unhandled promise rejection; wrap the login in a promise handler or an
async try/catch (e.g., await client.login(TOKEN) inside an async IIFE) and on
failure log the error (include error details) and exit with a non-zero code
(process.exit(1)); ensure you reference the same client.login and TOKEN symbols
so the rejection is caught and handled gracefully.
- Around line 136-139: The immediate call to msg.channel.sendTyping() is placed
after creating typingInterval which reduces clarity; either remove the duplicate
call or move the immediate msg.channel.sendTyping() before const typingInterval
= setInterval(...) so the pattern "send once immediately, then every 5s" is
explicit; update the code around typingInterval and the two
msg.channel.sendTyping() calls to implement one of these two options for clearer
intent.
- Line 21: The file imports the Node 'path' module via the const path =
require("path") statement but never uses it; remove that unused import to clean
up the module (or if path functionality is intended, replace/remove usages
accordingly). Locate the require("path") binding (the const path variable) in
scripts/discord-bridge.js and delete the line, or alternatively implement the
intended path usage where referenced; ensure no other code refers to the removed
symbol and run lint/tests to confirm.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f7292aef-6d6b-4e39-8c52-694a40878073

📥 Commits

Reviewing files that changed from the base of the PR and between 01f3662 and 0eb9794.

📒 Files selected for processing (5)
  • .dockerignore
  • docs/deployment/set-up-discord-bridge.md
  • scripts/discord-bridge.js
  • scripts/start-discord-bridge.sh
  • scripts/start-services.sh
✅ Files skipped from review due to trivial changes (1)
  • .dockerignore
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/start-discord-bridge.sh

@wscurran

Copy link
Copy Markdown
Contributor

Thanks for building this, @BioInfo — Discord support was a real gap and this PR was a solid first take. Discord integration is now handled differently on main: bot tokens are injected directly into the sandbox environment (#601) and network access is managed via the discord policy preset, rather than an external bridge script. The discord-bridge.js approach has been superseded by that architecture. Closing as superseded, and thanks for the detailed implementation — it helped establish the feature's scope.

@wscurran wscurran closed this Apr 16, 2026
@wscurran wscurran added area: integrations Third-party service integration behavior feature PR adds or expands user-visible functionality and removed enhancement: feature labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: integrations Third-party service integration behavior feature PR adds or expands user-visible functionality integration: discord Discord integration or channel behavior integration: telegram Telegram integration or channel behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants