mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-24 16:54:43 +00:00
fix(slack): add catch-all event handler to prevent Slack auto-disabling Event Subscriptions
Without a catch-all handler, slack-bolt returns HTTP 404 for every unhandled bot event (user_change, user_huddle_changed, reaction_added, etc.) and never sends the Socket Mode ack. On active Slack workspaces where the app is subscribed to high-volume events, this produces a near-100% un-acked failure rate that crosses Slack's >95%/60-min threshold and triggers automatic disabling of the app's Event Subscriptions — silently killing all inbound event delivery. Place a catch-all re.compile(r".*") handler AFTER the specific event handlers so bolt's router matches those first. Truly unhandled events are silently acked (200) and logged at DEBUG. The failure rate stays near 0% regardless of which events the Slack app manifest subscribes to. Fixes #6572
This commit is contained in:
parent
c1529e58da
commit
93102e91cf
1 changed files with 40 additions and 0 deletions
|
|
@ -1751,6 +1751,46 @@ class SlackAdapter(BasePlatformAdapter):
|
|||
async def handle_assistant_thread_context_changed(event, say, body):
|
||||
await self._handle_assistant_thread_lifecycle_event(event, body)
|
||||
|
||||
# Catch-all no-op ack for any other subscribed event type that
|
||||
# Hermes has no listener for (e.g. user_change,
|
||||
# user_huddle_changed, member_joined_channel, channel_archive,
|
||||
# pin_added, etc.).
|
||||
#
|
||||
# Two reasons this must exist (issues #6572 and the Event
|
||||
# Subscriptions auto-disable failure mode):
|
||||
# 1. Correctness at scale: without a matching listener,
|
||||
# slack-bolt returns HTTP 404 for every unhandled event
|
||||
# envelope and never sends the Socket Mode ack. When the app
|
||||
# is subscribed to high-volume events (user_change fires on
|
||||
# every presence/status change for the whole org), the flood
|
||||
# of un-acked 404s pushes Slack's failure rate past its
|
||||
# 95%/60-min threshold and Slack auto-disables the app's
|
||||
# Event Subscriptions — silently killing ALL inbound
|
||||
# delivery until manually re-enabled.
|
||||
# 2. Noise: each unhandled envelope also logs a slack_bolt
|
||||
# "Unhandled request" WARNING, flooding gateway logs in
|
||||
# busy channels.
|
||||
#
|
||||
# Registered AFTER every named handler: bolt dispatches to the
|
||||
# first matching listener, so the named handlers above always
|
||||
# win and this only fires for truly unhandled types. The
|
||||
# envelope is acked with 200, keeping the failure rate near 0%
|
||||
# regardless of which events the Slack app manifest subscribes
|
||||
# to. A debug line preserves visibility into unknown event
|
||||
# types without per-message WARNING noise.
|
||||
@self._app.event(re.compile(r".*"))
|
||||
async def handle_unhandled_event(event, body, logger):
|
||||
logger.debug(
|
||||
"[Slack] Ignoring unhandled event type=%s (no listener "
|
||||
"registered; subscribed events not handled by Hermes can "
|
||||
"be removed from the Slack app manifest via "
|
||||
"`hermes slack manifest`)",
|
||||
(event or {}).get(
|
||||
"type",
|
||||
(body or {}).get("event", {}).get("type", "unknown"),
|
||||
),
|
||||
)
|
||||
|
||||
# Register slash command handler(s)
|
||||
#
|
||||
# Every gateway command from COMMAND_REGISTRY is a native Slack
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue