Skip to content

feat: telegram group topics support (message_thread_id) #509#512

Open
netandreus wants to merge 11 commits intolaurentenhoor:mainfrom
netandreus:feat/topic-for-project
Open

feat: telegram group topics support (message_thread_id) #509#512
netandreus wants to merge 11 commits intolaurentenhoor:mainfrom
netandreus:feat/topic-for-project

Conversation

@netandreus
Copy link
Copy Markdown

This change adds Telegram forum topic support so DevClaw can treat each topic in a supergroup as a distinct binding: notifications and gateway agent runs stay in the correct thread, and projects can be registered or linked per topic instead of sharing one context for the whole chat.

Behavior for DMs and groups without topics is unchanged (message_thread_id is absent in those cases).

Closes:

Contains:

What changed

Data model and resolution

  • Extended Channel with optional messageThreadId (aligned with the Telegram Bot API naming).
  • Introduced scoped channel keys via resolveProjectChannelScope() and topic-aware resolveProjectSlug() / getProject() in lib/projects/io.ts:
    • Exact match on channel + channelId + accountId + topic wins.
    • If no topic-specific channel matches, falls back to a chat-level registration (no messageThreadId), preserving existing setups.
  • Migrated legacy topicId on disk to messageThreadId and stripped topicId on save (covered in tests).

Notifications

  • resolveNotifyChannel() now returns messageThreadId when the selected channel entry has one.
  • notify() forwards messageThreadId into the Telegram runtime sendMessage path so pipeline/dispatch alerts land in the same topic as the bound project.

Dispatch and worker runs

  • dispatchTask passes a notifyTarget (chat + channel + account + optional messageThreadId) into sendToAgent.
  • sendToAgent maps that to gateway agent params (to, channel, accountId, threadId) so the worker session receives messageThreadId injection for tools—matching how OpenClaw routes Telegram forum threads.

Tools and admin UX

  • channel_link / project_register: optional messageThreadId to bind a project to a specific forum topic.
  • Task tools, work_finish, health, sync_labels, project_status, etc.: optional messageThreadId when resolving the project from a Telegram chat so the correct slug is chosen in multi-topic groups.

How to use it

  1. Enable Topics on a Telegram supergroup and note each topic’s message_thread_id (e.g. from incoming updates or Bot API payloads).
  2. Register or link a project with channel="telegram", the group channelId, and messageThreadId set to that topic’s id.
  3. Optional: use notify:telegram:<name> (or channel index) labels on issues so routing picks the channel entry that includes the topic id.

Tests

  • lib/projects/projects.test.ts: legacy topicIdmessageThreadId migration and resolveProjectSlug with messageThreadId.

Run:

npx tsx --test lib/projects/projects.test.ts

Also shipped on this branch

These landed together with the topic work (same merge target):

  • Notifications: issueComplete event when an issue is closed.
  • Fix #508: more reliable work_finish slot matching (case-insensitive session key comparison) and consistent use of project.slug for session keys.
  • Build: local jsonResult helper in lib/json-result.ts for robust plugin-sdk interop.
  • Dependencies: package-lock.json refresh (Node 22–aligned install).

If you prefer a PR that only contains the Telegram topic commits, cherry-pick or rebase onto the base branch before opening the PR.

MestreY0d4-Uninter and others added 11 commits March 9, 2026 10:14
Adds optional messageThreadId parameter through the notification chain:
Channel type -> resolveNotifyChannel -> notify -> sendMessage -> Telegram API.

This enables per-topic routing in Telegram forum groups, where each project
can have notifications sent to a specific forum topic instead of the main chat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a new "issueComplete" notification event type that fires when an issue
is closed via the CLOSE_ISSUE completion action. This provides visibility
into the final delivery milestone of the pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…name

When a project is registered with a mixed-case name (e.g. 'UpMoltWork'),
the session key was built using project.name, resulting in keys like:
  agent:main:subagent:UpMoltWork-developer-junior-annabelle

However, the gateway stores and looks up session keys case-sensitively,
and new sessions are created with lowercase keys. This mismatch caused
the heartbeat to not find the active session, consider the worker dead,
and re-dispatch — resulting in workers being restarted every heartbeat cycle.

Fix: use project.slug (which is always lowercase) to build the session key.
Falls back to project.name.toLowerCase() for safety.

Fixes: worker restart loop on projects with mixed-case names
…nish tool. Updated the logic for finding active slots to ensure case-insensitive comparison of session keys, enhancing the accuracy of slot matching for the current session.
This update introduces support for the optional messageThreadId parameter across various project resolution functions and tools, enabling topic-aware routing for Telegram channels. Key changes include:

- New function `resolveProjectChannelScope` for building stable scope keys.
- Updates to `resolveProjectSlug` and `getProject` to handle scoped inputs.
- Migration logic for normalizing legacy topic fields in projects.
- Adjustments in admin tools to accommodate messageThreadId for channel linking, un-linking, and listing.

These enhancements improve the flexibility and accuracy of project management within chat environments, particularly for Telegram forum topics.
This update introduces the `notifyTarget` parameter in the dispatch and agent communication processes, allowing for more precise routing of messages to specific Telegram channels and topics. Key changes include:

- Addition of `notifyTarget` in the `dispatchTask` and `sendToAgent` functions.
- Implementation of `applyNotifyRoutingToGatewayParams` to handle the new routing logic.
- Updates to project migration logic to ensure legacy topic fields are correctly normalized.

These enhancements improve the flexibility of message delivery within Telegram environments, particularly for forum topics.
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.

Developer worker could not complete the task through work_finish

1 participant