@@ -172,7 +172,20 @@ def _get_failure_script():
172172
173173
174174def _record_redirect_not_followed (app_id : str , status_code : int , endpoint : str ) -> int :
175- """Record a 3xx delivery without advancing the auto-disable clock."""
175+ """Record a 3xx delivery without advancing the auto-disable clock.
176+
177+ We send webhooks with ``follow_redirects=False`` so a redirect cannot escape
178+ the pinned destination IP, so a 3xx does mean the payload was not delivered.
179+ It does not mean the developer's host is down — the host answered — and the
180+ fix is a one-line URL change the developer can only make if they are told.
181+ Scoring it as an outage instead auto-disabled apps whose servers were up,
182+ with the reason recorded as an opaque ``HTTP 307``.
183+
184+ So a redirect notifies, repeatedly if it persists, and never disables. The
185+ accepted cost is that an app left permanently redirecting keeps failing
186+ delivery instead of being switched off; that is the developer's endpoint to
187+ fix, and it is recoverable, which the auto-disable was not.
188+ """
176189 if not app_id or not isinstance (app_id , str ) or not app_id .strip ():
177190 return ACTION_NONE
178191 clean_app_id = app_id .strip ()
@@ -337,7 +350,7 @@ def get_app_webhook_health(app_id: str, endpoint: Optional[str] = None) -> Optio
337350 clean_app_id = app_id .strip ()
338351 try :
339352 if endpoint :
340- clean_endpoint = endpoint .strip () if isinstance (endpoint , str ) and endpoint .strip () else endpoint
353+ clean_endpoint = endpoint .strip () if isinstance (endpoint , str ) and endpoint .strip () else ENDPOINT_REALTIME
341354 key = f'app_webhook_health:{ clean_app_id } :{ clean_endpoint } '
342355 data = cast (Dict [bytes , bytes ], r .hgetall (key ))
343356 if not data :
0 commit comments