openclaw - ✅(Solved) Fix Feature: Expose Feishu bot added/removed events as hook events [1 pull requests, 1 participants]

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…
GitHub stats
openclaw/openclaw#62056Fetched 2026-04-08 03:09:36
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

When a Feishu bot is added to or removed from a group chat, OpenClaw already receives and processes the im.chat.member.bot.added_v1 and im.chat.member.bot.deleted_v1 events from the Feishu Event Subscription API. However, these events are only logged internally and not exposed to the hook system.

Root Cause

When a Feishu bot is added to or removed from a group chat, OpenClaw already receives and processes the im.chat.member.bot.added_v1 and im.chat.member.bot.deleted_v1 events from the Feishu Event Subscription API. However, these events are only logged internally and not exposed to the hook system.

Fix Action

Fixed

PR fix notes

PR #62331: fix(speech-core): send Weixin TTS as voice notes

Description (problem / solution / changelog)

Summary

  • Problem: openclaw-weixin replies with synthesized audio as a regular file instead of a voice-note payload.
  • Why it matters: Weixin users do not receive TTS in the native voice-message format that the channel expects.
  • What changed: added openclaw-weixin to the speech-core voice-note channel allowlist and covered it with a focused regression test.
  • What did NOT change (scope boundary): no Feishu hook work, no broader channel routing changes, and no provider behavior changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #61191
  • Related #62056
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: speech-core only treated a fixed set of channels as voice-note-capable, and openclaw-weixin was missing from that set.
  • Missing detection / guardrail: there was no regression test covering voice-note routing for the Weixin channel id.
  • Contributing context (if known): TTS routing used the same hardcoded allowlist in both synthesis target selection and outbound payload shaping.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/speech-core/src/tts.test.ts
  • Scenario the test should lock in: openclaw-weixin chooses the voice-note path while non-voice-note channels still use the regular audio-file path.
  • Why this is the smallest reliable guardrail: the bug is a channel allowlist decision in shared TTS routing logic, so a focused unit test on that branch point is enough to catch regressions.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Weixin TTS replies now mark compatible synthesized audio as voice notes instead of regular file attachments.

Diagram (if applicable)

N/A

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): openclaw-weixin
  • Relevant config (redacted): default speech-core routing

Steps

  1. Trigger speech-core TTS for a reply targeting openclaw-weixin.
  2. Observe the routing decision used for synthesis and outbound payload shaping.
  3. Compare with a non-voice-note channel such as discord.

Expected

  • openclaw-weixin uses the voice-note path.
  • Non-voice-note channels continue to use regular audio files.

Actual

  • Before this patch, openclaw-weixin fell through to the regular audio-file path.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: ran pnpm test extensions/speech-core/src/tts.test.ts and pnpm check; confirmed the post-rebase diff only touches extensions/speech-core/src/tts.ts and extensions/speech-core/src/tts.test.ts.
  • Edge cases checked: non-voice-note channel ids and null channel ids still return false from the routing helper.
  • What you did not verify: live Weixin delivery against a connected account.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: another channel id alias could exist outside the current normalization path.
    • Mitigation: the fix goes through the existing normalized ChannelId helper and keeps the decision logic centralized in one helper.

Changed files

  • extensions/speech-core/src/tts.test.ts (added, +13/-0)
  • extensions/speech-core/src/tts.ts (modified, +14/-4)

Code Example

"im.chat.member.bot.added_v1": async (data) => {
    const event = parseFeishuBotAddedEventPayload(data);
    log(`feishu[${accountId}]: bot added to chat ${event.chat_id}`);
}
RAW_BUFFERClick to expand / collapse

Summary

When a Feishu bot is added to or removed from a group chat, OpenClaw already receives and processes the im.chat.member.bot.added_v1 and im.chat.member.bot.deleted_v1 events from the Feishu Event Subscription API. However, these events are only logged internally and not exposed to the hook system.

Current Behavior

In the Feishu monitor, the events are handled with a simple log:

"im.chat.member.bot.added_v1": async (data) => {
    const event = parseFeishuBotAddedEventPayload(data);
    log(`feishu[${accountId}]: bot added to chat ${event.chat_id}`);
}

No hook event is fired, so user-space hooks cannot react to these events.

Desired Behavior

Expose two new hook event types:

  • channel:feishu:bot-added — fired when the bot is added to a group chat
  • channel:feishu:bot-removed — fired when the bot is removed from a group chat

Event context should include:

  • chatId: the group chat ID
  • chatName: group name (if available)
  • accountId: the Feishu account ID
  • timestamp: event timestamp

Use Case

As an agent operator, I want to:

  1. Automatically notify the admin when the bot is added to or removed from a group
  2. Update workspace config files (e.g., group registry) when group membership changes
  3. Remove the need for periodic polling (heartbeat-based group list checks via /open-apis/im/v1/chats) which consumes tokens and API quota every 15 minutes

Currently I have to poll the Feishu chat list API on every heartbeat to detect group changes. With hook events, this could be fully event-driven and zero-cost.

Environment

  • OpenClaw: 2026.4.5 (3e72c03)
  • Channel: Feishu
  • OS: macOS (Darwin arm64)

extent analysis

TL;DR

To fix the issue, modify the existing event handlers for im.chat.member.bot.added_v1 and im.chat.member.bot.deleted_v1 events to fire the new hook events channel:feishu:bot-added and channel:feishu:bot-removed with the required event context.

Guidance

  • Identify the existing event handlers for im.chat.member.bot.added_v1 and im.chat.member.bot.deleted_v1 events and modify them to include the logic for firing the new hook events.
  • Ensure the new hook events include the required event context: chatId, chatName, accountId, and timestamp.
  • Update the event handlers to handle any potential errors or edge cases when firing the new hook events.
  • Verify that the new hook events are being fired correctly by adding logging or debugging statements to the modified event handlers.

Example

"im.chat.member.bot.added_v1": async (data) => {
    const event = parseFeishuBotAddedEventPayload(data);
    log(`feishu[${accountId}]: bot added to chat ${event.chat_id}`);
    // Fire the new hook event
    await hookManager.fire('channel:feishu:bot-added', {
        chatId: event.chat_id,
        chatName: event.chat_name,
        accountId: accountId,
        timestamp: Date.now(),
    });
}

Notes

The exact implementation details may vary depending on the specific requirements and constraints of the OpenClaw system and the Feishu Event Subscription API.

Recommendation

Apply a workaround by modifying the existing event handlers to fire the new hook events, as this will allow for the desired behavior without requiring a full upgrade or rewrite of the system.

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