Skip to content

EventSubWebhook: Support Reusing Existing Subscriptions After Restart #353

@mgerhold

Description

@mgerhold

Summary

If EventSubWebhook.unsubscribe_on_stop = False, Twitch keeps webhook subscriptions across restarts. The fact that the library exposes unsubscribe_on_stop = False strongly suggests that preserving (and re-attaching to) existing subscriptions across restarts is an intended, supported use case. After restarting the process, incoming events for those existing subscription IDs are dropped with:

received event for unknown subscription with ID <sub_id>

because _callbacks is empty in the new process and the library has no supported way to re-register callbacks for existing subscription IDs.

Steps to Reproduce

  • Start EventSubWebhook(...).
  • Set eventsub.unsubscribe_on_stop = False.
  • Create a subscription (e.g. await eventsub.listen_stream_online(broadcaster_id, cb)).
  • Restart the process.
  • Trigger the event again.

Actual Behavior

Webhook receives the event, but EventSubWebhook.__handle_callback() can’t route it because sub_id is not in self._callbacks.

Expected Behavior

Provide a supported way to “adopt” existing Helix EventSub subscriptions after restart (re-register callback + event type for known subscription_ids) so events are dispatched without recreating subscriptions.

Current Workaround

Query Helix get_eventsub_subscriptions() on startup and then call private methods:

  • _add_callback(subscription_id, callback, event)
  • _activate_callback(subscription_id)

This works but is brittle (private API + typing ignores).

Proposed Addition

Add a public API to register an existing subscription ID locally, e.g.:

def register_existing_subscription(
    self,
    subscription_id: str,
    event: type,
    callback: Callable[[Any], Awaitable[None]],
    *,
    activate: bool = True,
) -> None:
    ...

Internally this would just store the (subscription_id -> callback, event type) mapping in the local _callbacks table (as done during _subscribe), and—if activate=True—mark it as active immediately so incoming webhook events for that subscription ID are dispatched without waiting for a new challenge or making any Helix API call.

Offer to Contribute

Happy to open a PR with the API + docs/tests if you agree with this direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions