hermes - 💡(How to fix) Fix [Feature]: Route Telegram forum topic lifecycle events through the plugin dispatch pipeline

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix / Workaround

Telegram forum supergroups deliver topic lifecycle events (forum_topic_created, forum_topic_edited, forum_topic_closed, forum_topic_reopened) as service messages — they carry no .text and no media. None of the existing handler filters (filters.TEXT, filters.COMMAND, filters.LOCATION, filters.PHOTO | VIDEO | ...) match them, so python-telegram-bot silently drops these updates before they reach any part of the hermes dispatch pipeline.

This makes it impossible for plugins using pre_gateway_dispatch to react to topic lifecycle events. Common use cases:

  • Automatically provisioning a kanban board or project workspace when a forum topic is created
  • Archiving resources when a topic is closed
  • Renaming associated state when a topic is edited
  • Restoring state when a topic is reopened

This gives plugins access to raw_message.forum_topic_created, .forum_topic_edited, .forum_topic_closed, .forum_topic_reopened, and .message_thread_id via the pre_gateway_dispatch hook — letting them handle topic events without touching platform code.

Code Example

self._app.add_handler(TelegramMessageHandler(
    filters.StatusUpdate.FORUM_TOPIC_CREATED |
    filters.StatusUpdate.FORUM_TOPIC_EDITED |
    filters.StatusUpdate.FORUM_TOPIC_CLOSED |
    filters.StatusUpdate.FORUM_TOPIC_REOPENED,
    self._handle_forum_topic_event
))

---

async def _handle_forum_topic_event(self, update, context):
    if not update.message:
        return
    event = self._build_message_event(update.message, MessageType.TEXT, update_id=update.update_id)
    await self.handle_message(event)
RAW_BUFFERClick to expand / collapse

Problem or Use Case

Telegram forum supergroups deliver topic lifecycle events (forum_topic_created, forum_topic_edited, forum_topic_closed, forum_topic_reopened) as service messages — they carry no .text and no media. None of the existing handler filters (filters.TEXT, filters.COMMAND, filters.LOCATION, filters.PHOTO | VIDEO | ...) match them, so python-telegram-bot silently drops these updates before they reach any part of the hermes dispatch pipeline.

This makes it impossible for plugins using pre_gateway_dispatch to react to topic lifecycle events. Common use cases:

  • Automatically provisioning a kanban board or project workspace when a forum topic is created
  • Archiving resources when a topic is closed
  • Renaming associated state when a topic is edited
  • Restoring state when a topic is reopened

Today there is no way to handle any of these events from a plugin without modifying telegram.py directly — a file that belongs to the platform adapter and gets overwritten on hermes update.

Proposed Solution

Register a dedicated MessageHandler for StatusUpdate.FORUM_TOPIC_CREATED | FORUM_TOPIC_EDITED | FORUM_TOPIC_CLOSED | FORUM_TOPIC_REOPENED inside _setup_handlers(), and add a _handle_forum_topic_event() method that routes the service message through the standard handle_message() path — the same path used by _handle_command().

self._app.add_handler(TelegramMessageHandler(
    filters.StatusUpdate.FORUM_TOPIC_CREATED |
    filters.StatusUpdate.FORUM_TOPIC_EDITED |
    filters.StatusUpdate.FORUM_TOPIC_CLOSED |
    filters.StatusUpdate.FORUM_TOPIC_REOPENED,
    self._handle_forum_topic_event
))
async def _handle_forum_topic_event(self, update, context):
    if not update.message:
        return
    event = self._build_message_event(update.message, MessageType.TEXT, update_id=update.update_id)
    await self.handle_message(event)

This gives plugins access to raw_message.forum_topic_created, .forum_topic_edited, .forum_topic_closed, .forum_topic_reopened, and .message_thread_id via the pre_gateway_dispatch hook — letting them handle topic events without touching platform code.

Alternatives Considered

Route to internal config-persistence methods instead (as in PR #5488): this bakes specific behavior (persisting topics to config.yaml) into the platform adapter. The plugin-dispatch approach keeps the adapter unopinionated and lets any plugin decide what to do with topic events.

Poll getUpdates from the plugin directly: impossible — the gateway already consumes the update queue, so a plugin polling the same token would race and miss events.

Access telegram_adapter._app from the plugin to register handlers: works but uses a private undocumented attribute with no stability guarantee, and runs into initialization race conditions.

Feature Type

Gateway / messaging improvement

Scope

Small (single file, < 50 lines)

Contribution

  • I'd like to implement this myself and submit a PR

Implemented in PR #21458.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Feature]: Route Telegram forum topic lifecycle events through the plugin dispatch pipeline