Skip to content

fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam#31580

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
arkyu2077:fix/issue-28660-feishu-typing-notifications
Mar 3, 2026
Merged

fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam#31580
Takhoffman merged 2 commits intoopenclaw:mainfrom
arkyu2077:fix/issue-28660-feishu-typing-notifications

Conversation

@arkyu2077
Copy link
Contributor

Problem

The typing keepalive loop calls addTypingIndicator() every 3 seconds, which makes a fresh messageReaction.create API call each time. Feishu treats each re-add as a new reaction event and fires a push notification to the user.

This means the longer a response takes (e.g., during tool calls), the more duplicate notifications the user receives — one every 3 seconds.

Root Cause

Unlike Telegram/Discord where typing status expires after ~5 seconds and needs refreshing, Feishu reactions persist until explicitly removed via messageReaction.delete. The keepalive mechanism is unnecessary for Feishu and actively harmful.

Fix

Skip the keepalive re-add in the reply dispatcher's start() callback when a reaction already exists (typingState.reactionId is set). The initial reaction is still added on first call, and properly removed via stop() when the reply completes.

Changes

  • extensions/feishu/src/reply-dispatcher.ts: Guard keepalive re-adds with typingState?.reactionId check

Closes #28660

@openclaw-barnacle openclaw-barnacle bot added channel: feishu Channel integration: feishu size: XS labels Mar 2, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR fixes notification spam in Feishu by preventing unnecessary typing indicator re-adds. The fix adds a guard condition that skips the keepalive re-add when a reaction already exists (typingState?.reactionId is set).

Key Changes:

  • Added guard in reply-dispatcher.ts to check if typingState?.reactionId exists before re-adding typing indicator
  • Preserves initial reaction add and proper cleanup via stop callback
  • Platform-specific fix: unlike Telegram/Discord where typing expires, Feishu reactions persist until explicitly removed

Technical Analysis:

  • The keepalive loop calls start() every 3 seconds via createTypingCallbacks
  • Without the fix, each call made a fresh messageReaction.create API call, triggering notifications
  • The fix allows the first call to add the reaction, but subsequent keepalive calls skip the re-add
  • If the first call fails (returning reactionId: null), subsequent calls will retry correctly
  • The reaction is properly removed when the reply completes via the stop() callback

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is surgically precise, addressing only the notification spam issue without affecting other functionality. The guard condition is well-placed after existing validation checks, handles edge cases correctly (retry on failure), and includes clear documentation. The change is platform-specific and appropriate for Feishu's persistent reaction behavior.
  • No files require special attention

Last reviewed commit: 3388fe6

yuxh1996 and others added 2 commits March 2, 2026 17:37
…ication spam

The typing keepalive loop calls addTypingIndicator() every 3 seconds,
which creates a new messageReaction.create API call each time. Feishu
treats each re-add as a new reaction event and fires a push notification,
causing users to receive repeated notifications while waiting for a
response.

Unlike Telegram/Discord where typing status expires after a few seconds,
Feishu reactions persist until explicitly removed. Skip the keepalive
re-add when a reaction already exists (reactionId is set) since there
is no need to refresh it.

Closes openclaw#28660
@Takhoffman Takhoffman force-pushed the fix/issue-28660-feishu-typing-notifications branch from 3388fe6 to 7ca7ab0 Compare March 3, 2026 01:11
@Takhoffman Takhoffman merged commit 46df7e2 into openclaw:main Mar 3, 2026
9 checks passed
@Takhoffman
Copy link
Contributor

Merged after rebase + verification.

Verification run:

  • CI=true pnpm install --frozen-lockfile
  • pnpm build
  • pnpm check
  • pnpm test:macmini

Notes:

  • Added changelog entry for typing keepalive suppression behavior.
  • All checks passed locally before merge.

dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…ication spam (openclaw#31580)

* fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam

The typing keepalive loop calls addTypingIndicator() every 3 seconds,
which creates a new messageReaction.create API call each time. Feishu
treats each re-add as a new reaction event and fires a push notification,
causing users to receive repeated notifications while waiting for a
response.

Unlike Telegram/Discord where typing status expires after a few seconds,
Feishu reactions persist until explicitly removed. Skip the keepalive
re-add when a reaction already exists (reactionId is set) since there
is no need to refresh it.

Closes openclaw#28660

* Changelog: note Feishu typing keepalive suppression

---------

Co-authored-by: yuxh1996 <yuxh1996@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…ication spam (openclaw#31580)

* fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam

The typing keepalive loop calls addTypingIndicator() every 3 seconds,
which creates a new messageReaction.create API call each time. Feishu
treats each re-add as a new reaction event and fires a push notification,
causing users to receive repeated notifications while waiting for a
response.

Unlike Telegram/Discord where typing status expires after a few seconds,
Feishu reactions persist until explicitly removed. Skip the keepalive
re-add when a reaction already exists (reactionId is set) since there
is no need to refresh it.

Closes openclaw#28660

* Changelog: note Feishu typing keepalive suppression

---------

Co-authored-by: yuxh1996 <yuxh1996@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
smthfoxy pushed a commit to smthfoxy/openclaw that referenced this pull request Mar 4, 2026
…g re-adds

The openclaw#31580 fix correctly avoided re-adding typing reactions (which triggered
duplicate push notifications per openclaw#28660). However, skipping re-adds entirely
caused the Feishu client to stop displaying the typing animation after a short
period, even though the reaction remained on the message.

Fix: on keepalive ticks, remove the existing reaction first, then re-add it.
This refreshes the visual typing indicator without triggering duplicate
notification pushes (since the reaction is removed before being re-added,
Feishu treats it as a new reaction rather than a duplicate).

Add regression test: verify that the second onReplyStart call (keepalive)
triggers a remove-then-add cycle instead of being skipped.
smthfoxy pushed a commit to smthfoxy/openclaw that referenced this pull request Mar 4, 2026
…g re-adds

The openclaw#31580 fix correctly avoided re-adding typing reactions (which triggered
duplicate push notifications per openclaw#28660). However, skipping re-adds entirely
caused the Feishu client to stop displaying the typing animation after a short
period, even though the reaction remained on the message.

Fix: on keepalive ticks, remove the existing reaction first, then re-add it.
This refreshes the visual typing indicator without triggering duplicate
notification pushes (since the reaction is removed before being re-added,
Feishu treats it as a new reaction rather than a duplicate).

Add regression test: verify that the second onReplyStart call (keepalive)
triggers a remove-then-add cycle instead of being skipped.
smthfoxy pushed a commit to smthfoxy/openclaw that referenced this pull request Mar 4, 2026
…g re-adds

The openclaw#31580 fix correctly avoided re-adding typing reactions (which triggered
duplicate push notifications per openclaw#28660). However, skipping re-adds entirely
caused the Feishu client to stop displaying the typing animation after a short
period, even though the reaction remained on the message.

Fix: on keepalive ticks, remove the existing reaction first, then re-add it.
This refreshes the visual typing indicator without triggering duplicate
notification pushes (since the reaction is removed before being re-added,
Feishu treats it as a new reaction rather than a duplicate).

Add regression test: verify that the second onReplyStart call (keepalive)
triggers a remove-then-add cycle instead of being skipped.
smthfoxy pushed a commit to smthfoxy/openclaw that referenced this pull request Mar 4, 2026
…g re-adds

The openclaw#31580 fix correctly avoided re-adding typing reactions (which triggered
duplicate push notifications per openclaw#28660). However, skipping re-adds entirely
caused the Feishu client to stop displaying the typing animation after a short
period, even though the reaction remained on the message.

Fix: on keepalive ticks, remove the existing reaction first, then re-add it.
This refreshes the visual typing indicator without triggering duplicate
notification pushes (since the reaction is removed before being re-added,
Feishu treats it as a new reaction rather than a duplicate).

Race safety: use a `typingStopped` flag to prevent start() from restoring
state after stop() has run. After each async gap in start(), recheck the flag
and clean up any freshly-added reaction if stop() fired concurrently. This
closes the window where an orphaned reaction could stick on the message
permanently.

Add regression tests:
- Verify keepalive triggers remove-then-add cycle
- Verify stop()-during-add cleans up the orphaned reaction
- Verify start() is a no-op once stop() has been called
smthfoxy pushed a commit to smthfoxy/openclaw that referenced this pull request Mar 4, 2026
…g re-adds

The openclaw#31580 fix correctly avoided re-adding typing reactions (which triggered
duplicate push notifications per openclaw#28660). However, skipping re-adds entirely
caused the Feishu client to stop displaying the typing animation after a short
period, even though the reaction remained on the message.

Fix: on keepalive ticks, remove the existing reaction first, then re-add it.
This refreshes the visual typing indicator without triggering duplicate
notification pushes (since the reaction is removed before being re-added,
Feishu treats it as a new reaction rather than a duplicate).

Race safety:
- `typingStopped` flag prevents start() from restoring state after stop().
- `startChain` promise serializes concurrent start() calls so fire-and-forget
  keepalive ticks don't interleave and orphan reactions under high latency.
- stop() awaits startChain before cleanup, closing the window where an
  in-flight add could outlive the stop.
- After each async gap in start(), recheck typingStopped and clean up any
  freshly-added reaction if stop() fired concurrently.

Add regression tests:
- Verify keepalive triggers remove-then-add cycle
- Verify stop()-during-add cleans up the orphaned reaction
- Verify start() is a no-op once stop() has been called
AytuncYildizli pushed a commit to AytuncYildizli/openclaw that referenced this pull request Mar 4, 2026
…ication spam (openclaw#31580)

* fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam

The typing keepalive loop calls addTypingIndicator() every 3 seconds,
which creates a new messageReaction.create API call each time. Feishu
treats each re-add as a new reaction event and fires a push notification,
causing users to receive repeated notifications while waiting for a
response.

Unlike Telegram/Discord where typing status expires after a few seconds,
Feishu reactions persist until explicitly removed. Skip the keepalive
re-add when a reaction already exists (reactionId is set) since there
is no need to refresh it.

Closes openclaw#28660

* Changelog: note Feishu typing keepalive suppression

---------

Co-authored-by: yuxh1996 <yuxh1996@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…ication spam (openclaw#31580)

* fix(feishu): skip typing indicator keepalive re-adds to prevent notification spam

The typing keepalive loop calls addTypingIndicator() every 3 seconds,
which creates a new messageReaction.create API call each time. Feishu
treats each re-add as a new reaction event and fires a push notification,
causing users to receive repeated notifications while waiting for a
response.

Unlike Telegram/Discord where typing status expires after a few seconds,
Feishu reactions persist until explicitly removed. Skip the keepalive
re-add when a reaction already exists (reactionId is set) since there
is no need to refresh it.

Closes openclaw#28660

* Changelog: note Feishu typing keepalive suppression

---------

Co-authored-by: yuxh1996 <yuxh1996@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feishu: typing indicator keepalive causes repeated push notifications

2 participants