Skip to content

feat(bots): support for gdm#4872

Open
miguel-nascimento wants to merge 3 commits into
mainfrom
miguel/bot-framework-gdm-support
Open

feat(bots): support for gdm#4872
miguel-nascimento wants to merge 3 commits into
mainfrom
miguel/bot-framework-gdm-support

Conversation

@miguel-nascimento

@miguel-nascimento miguel-nascimento commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for bot GDM
Requires #4860 & #4866

@vercel

vercel Bot commented Jan 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
river-sample-app Ready Ready Preview, Comment Jan 16, 2026 3:46am

Review with Vercel Agent

@cursor

cursor Bot commented Jan 15, 2026

Copy link
Copy Markdown

PR Summary

Introduces GDM channel support across the bot SDK and docs.

  • Core: Route messages to GDM streams via make_GDMChannelPayload_Message; createBasePayload now discriminates channel type with isDm/isGdm and spaceId (undefined for DMs/GDMs)
  • Types: Refactor BasePayload as a discriminated union (adds isGdm), factoring common fields into BaseStreamPayload
  • Tipping: Treat GDM like DM for sendTip (checks isGDMChannelStreamId), requiring AccountModules for private-channel tips
  • Docs: Update AGENTS.md (bot and examples) to document DM vs GDM behavior, payload shape, and usage patterns; remove "no GDM support" gotcha
  • Changeset: Patch release for @towns-protocol/bot noting GDM message support

Written by Cursor Bugbot for commit c0bba50. This will update automatically on new commits. Configure here.

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Group DM (GDM) stream support to the bot by treating GDM channels equivalently to DMs across payload creation, message sending, and DM-specific logic. Imports GDM payload constructor and updates documentation to reflect combined DM/GDM handling without space context.

Changes

Cohort / File(s) Summary
Changelog
.changeset/bumpy-cameras-jam.md
Patch version bump with note: "added support for sending messages in GDM streams."
Bot GDM Support
packages/bot/src/bot.ts
Imports make_GDMChannelPayload_Message; treats GDM streams as DMs in isDm checks, payload creation, space context resolution, and DM-tip validation flows. Adds GDM branching in sendMessage to construct event payloads.
Documentation Update
packages/examples/bot-quickstart/AGENTS.md
Updates BasePayload discriminated union to use spaceId: undefined (vs. null) for isDm = true; updates type safety notes and example usage to differentiate DM/GDM from space channels via isDMChannelStreamId and isGDMChannelStreamId helpers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • sergekh2
  • texuf
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding GDM (Group DM) support to the bot framework.
Description check ✅ Passed The description clearly states the PR adds bot GDM support and notes required dependencies, directly relating to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch miguel/bot-framework-gdm-support


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab3b5ad and 5fd0c87.

📒 Files selected for processing (3)
  • .changeset/bumpy-cameras-jam.md
  • packages/bot/src/bot.ts
  • packages/examples/bot-quickstart/AGENTS.md
🧰 Additional context used
📓 Path-based instructions (8)
packages/examples/bot-quickstart/**/AGENTS.md

📄 CodeRabbit inference engine (packages/examples/bot-quickstart/CLAUDE.md)

Document agent configurations and behaviors in AGENTS.md

Files:

  • packages/examples/bot-quickstart/AGENTS.md
**/*.{ts,tsx,js,jsx,yaml,yml,sol,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

All non-Go files must pass Prettier formatting, run bun run prettier:fix to automatically format TypeScript, JavaScript, YAML, Solidity, and other supported files

Files:

  • packages/examples/bot-quickstart/AGENTS.md
  • packages/bot/src/bot.ts
packages/bot/{.env*,.env.sample,**/*bot*.{ts,tsx,js},**/setup*.{ts,tsx,js},**/config*.{ts,tsx,js}}

📄 CodeRabbit inference engine (packages/bot/AGENTS.md)

Verify APP_PRIVATE_DATA is valid and base64 encoded for bot authentication

Files:

  • packages/bot/src/bot.ts
packages/bot/{.env*,.env.sample,**/*bot*.{ts,tsx,js},**/setup*.{ts,tsx,js}}

📄 CodeRabbit inference engine (packages/bot/AGENTS.md)

Verify JWT_SECRET is correctly configured for webhook security token validation

Files:

  • packages/bot/src/bot.ts
packages/bot/**/*bot*.{ts,tsx,js}

📄 CodeRabbit inference engine (packages/bot/AGENTS.md)

packages/bot/**/*bot*.{ts,tsx,js}: Implement event handlers (onMessage, onSlashCommand, onReaction, onTip, onChannelJoin, onMessageEdit, onRedaction) to respond to Towns events
Design interactions to work with single, isolated events since the bot framework is completely stateless with no message history or thread context
Store conversation context externally (database or in-memory) if multi-step interactions or conversation flows are needed
Use Map/Set for in-memory caching only when bot runs continuously and can be restarted, otherwise use persistent storage like SQLite, PostgreSQL, or Redis
Implement onMessage handler to respond to any non-slash-command messages including mentions, replies, and threads
Check event.isMentioned flag before responding to mentions, do not rely on parsing message text for bot mentions
Note that threadId and replyId fields only contain IDs, not original message content - store context externally if needed
Register slash command handlers using bot.onSlashCommand(commandName, handler) - they do not trigger onMessage
Implement onReaction handler to respond to emoji reactions on messages, noting that original message content is not accessible
Implement onMessageEdit handler to detect when users edit messages and track edit history if needed
Implement onRedaction/onEventRevoke handler to clean up related data when messages are deleted
Use handler.removeEvent() to delete bot's own messages, and handler.adminRemoveEvent() for admin message deletion which requires Permission.Redact
Implement onTip handler to respond to cryptocurrency tips on messages with access to sender, receiver, amount, and currency
Implement onChannelJoin/onChannelLeave handlers to respond to user membership changes
Use sendInteractionRequest with type 'form' to send buttons and interactive forms to users
Implement onInteractionResponse handler to process button clicks and form submissions from interactive messages
Use sendInteractionRequest with type 'transaction' to p...

Files:

  • packages/bot/src/bot.ts
packages/bot/{.env*,.env.sample,**/*bot*.{ts,tsx,js},**/config*.{ts,tsx,js}}

📄 CodeRabbit inference engine (packages/bot/AGENTS.md)

Set forwarding setting to ALL_MESSAGES or MENTIONS_REPLIES_REACTIONS based on bot needs - bot may not receive all message types otherwise

Files:

  • packages/bot/src/bot.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/**/*.{ts,tsx}: Follow existing patterns in /packages/ for SDK development with TypeScript
Use proper TypeScript types, especially for blockchain interactions in SDK development
Follow existing patterns for client-server communication in TypeScript SDK

Files:

  • packages/bot/src/bot.ts
packages/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Implement proper error handling and validation in TypeScript/JavaScript code

Files:

  • packages/bot/src/bot.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/AGENTS.md:0-0
Timestamp: 2026-01-09T20:07:46.087Z
Learning: Applies to packages/examples/bot-quickstart/**/*.{ts,tsx} : Use discriminated union type based on `isDm` property for BasePayload to narrow `spaceId` type safety in TypeScript.
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/**/*bot*.{ts,tsx,js} : Implement event handlers (onMessage, onSlashCommand, onReaction, onTip, onChannelJoin, onMessageEdit, onRedaction) to respond to Towns events

Applied to files:

  • .changeset/bumpy-cameras-jam.md
  • packages/bot/src/bot.ts
📚 Learning: 2026-01-09T20:07:46.087Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/AGENTS.md:0-0
Timestamp: 2026-01-09T20:07:46.087Z
Learning: Applies to packages/examples/bot-quickstart/**/*.{ts,tsx} : Use discriminated union type based on `isDm` property for BasePayload to narrow `spaceId` type safety in TypeScript.

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
  • packages/bot/src/bot.ts
📚 Learning: 2026-01-09T20:07:46.087Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/AGENTS.md:0-0
Timestamp: 2026-01-09T20:07:46.087Z
Learning: Applies to packages/examples/bot-quickstart/**/*.{ts,tsx} : Use `eventId` from base payload as `threadId` or `replyId` when responding to events to maintain conversation context.

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
  • packages/bot/src/bot.ts
📚 Learning: 2026-01-09T20:07:46.087Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/AGENTS.md:0-0
Timestamp: 2026-01-09T20:07:46.087Z
Learning: Applies to packages/examples/bot-quickstart/**/*.{ts,tsx} : Always use `<@{userId}>` format for mentions in message content AND include `mentions` array in `sendMessage` options - not `username` format.

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
  • packages/bot/src/bot.ts
📚 Learning: 2025-11-25T08:44:41.031Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/CLAUDE.md:0-0
Timestamp: 2025-11-25T08:44:41.031Z
Learning: Applies to packages/examples/bot-quickstart/**/AGENTS.md : Document agent configurations and behaviors in AGENTS.md

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/**/*bot*.{ts,tsx,js} : Note that threadId and replyId fields only contain IDs, not original message content - store context externally if needed

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
  • packages/bot/src/bot.ts
📚 Learning: 2025-11-25T08:44:29.555Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/CLAUDE.md:0-0
Timestamp: 2025-11-25T08:44:29.555Z
Learning: Applies to packages/bot/**/AGENTS.md : All agent configurations and specifications should be documented in AGENTS.md

Applied to files:

  • packages/examples/bot-quickstart/AGENTS.md
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/{.env*,.env.sample,**/*bot*.{ts,tsx,js},**/config*.{ts,tsx,js}} : Set forwarding setting to ALL_MESSAGES or MENTIONS_REPLIES_REACTIONS based on bot needs - bot may not receive all message types otherwise

Applied to files:

  • packages/bot/src/bot.ts
📚 Learning: 2026-01-09T20:07:46.087Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/examples/bot-quickstart/AGENTS.md:0-0
Timestamp: 2026-01-09T20:07:46.087Z
Learning: Applies to packages/examples/bot-quickstart/**/*.{ts,tsx} : Add `paid` property to command definitions with price in USDC (e.g., `{ name: 'generate', description: 'Generate AI content', paid: { price: '$0.20' } }`) to create paid slash commands.

Applied to files:

  • packages/bot/src/bot.ts
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/**/*bot*.{ts,tsx,js} : Implement onChannelJoin/onChannelLeave handlers to respond to user membership changes

Applied to files:

  • packages/bot/src/bot.ts
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/**/*bot*.{ts,tsx,js} : Implement onTip handler to respond to cryptocurrency tips on messages with access to sender, receiver, amount, and currency

Applied to files:

  • packages/bot/src/bot.ts
📚 Learning: 2026-01-01T22:40:32.583Z
Learnt from: CR
Repo: towns-protocol/towns PR: 0
File: packages/bot/AGENTS.md:0-0
Timestamp: 2026-01-01T22:40:32.583Z
Learning: Applies to packages/bot/**/*bot*.{ts,tsx,js} : Implement onMessageEdit handler to detect when users edit messages and track edit history if needed

Applied to files:

  • packages/bot/src/bot.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Multinode_Ent
  • GitHub Check: Common_CI
  • GitHub Check: Go_Tests
  • GitHub Check: Multinode
  • GitHub Check: Multinode_Ent_Legacy
  • GitHub Check: Cursor Bugbot
  • GitHub Check: XChain_Integration
🔇 Additional comments (7)
packages/bot/src/bot.ts (5)

55-58: LGTM - GDM payload import added correctly.

Import aligns with its usage at line 2151 for constructing GDM channel payloads.


2145-2157: LGTM - GDM channel payload construction.

Correctly extends the message payload branching to handle GDM streams alongside DM and regular channel streams. The error message at line 2154 is accurate since only these three stream types are supported.


2635-2635: LGTM - DM check extended for tips.

GDM streams correctly treated as DMs for tip validation, consistent with the overall design.


3050-3055: LGTM - Space ID resolution updated.

Correctly returns undefined for both DM and GDM streams since neither have a space context.


3057-3087: LGTM - BasePayload creation handles GDM.

The isDm flag now correctly reflects both DM and GDM streams, and spaceId is appropriately set to undefined for these cases. This aligns with the discriminated union type definition at lines 387-419. Based on learnings, this follows the recommended pattern of using isDm property for narrowing spaceId type safety.

packages/examples/bot-quickstart/AGENTS.md (1)

18-55: LGTM - Documentation accurately reflects GDM support.

Clear explanation that isDm: true covers both DMs and GDMs, with practical example showing how to differentiate using isDMChannelStreamId and isGDMChannelStreamId helpers. As per coding guidelines, this properly documents agent configurations and behaviors.

.changeset/bumpy-cameras-jam.md (1)

1-5: LGTM - Appropriate changeset.

Patch version bump is correct for this backward-compatible feature addition.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Comment thread packages/bot/src/bot.ts Outdated
Comment thread packages/examples/bot-quickstart/AGENTS.md Outdated
@blacksmith-sh

This comment has been minimized.

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