Skip to content

Fix: Update SendGrid webhook when client_id changes#616

Merged
dahagag merged 1 commit into
ascoderu:masterfrom
dahagag:fix/sendgrid-stale-webhook
Jun 1, 2026
Merged

Fix: Update SendGrid webhook when client_id changes#616
dahagag merged 1 commit into
ascoderu:masterfrom
dahagag:fix/sendgrid-stale-webhook

Conversation

@dahagag

@dahagag dahagag commented Jun 1, 2026

Copy link
Copy Markdown
Member

Problem

When a domain is re-registered or configuration changes generate a new client_id, inbound emails are rejected with unregistered_client errors. This happens because the SendGrid webhook URL still points to the old client ID, while the server expects the new one.

Root Cause

SetupSendgridMailbox._run() would exit early when it found an existing SendGrid mailbox, without checking if the webhook URL matched the current client_id. This caused a silent mismatch between:

  • What SendGrid knows (old webhook URL with stale client_id)
  • What the server expects (new client_id)

Impact

Production domains lose all inbound email after re-registration until manual SendGrid reconfiguration.

Solution

Modified SetupSendgridMailbox._run() to:

  1. GET existing SendGrid mailbox configuration
  2. Compare current webhook URL with expected URL (containing current client_id)
  3. PATCH the webhook if URLs mismatch, preserving spam_check and send_raw settings
  4. Skip update only when URL is already correct

Changes

  • Added http_patch import to sendgrid.py
  • Updated SetupSendgridMailbox._run() with URL comparison and PATCH logic
  • Updated test_skips_request_when_domain_already_exists to include JSON response in mock
  • Added test_updates_webhook_when_url_mismatches to verify PATCH behavior

Testing

✅ All SendGrid service tests pass
✅ Code formatted with yapf (column_limit=120)
✅ Validated with production domain reproduction (lokole-repro-20260601.lokole.ca)

Before Fix

if get_response.ok:
    self.log_debug('Mailbox %s already exists', domain)
    break  # ❌ Exits without checking URL

After Fix

if get_response.ok:
    existing_config = get_response.json()
    expected_url = INBOX_URL.format(client_id)
    current_url = existing_config.get('url', '')
    
    if current_url != expected_url:
        # ✅ Updates webhook with correct client_id
        http_patch(...)

Deployment Notes

After merge and PyPI release, this fix will automatically apply when SetupSendgridMailbox runs (typically during client registration or periodic sync). Affected domains will see log messages: "Updating stale webhook for {domain}".

When a domain is re-registered or configuration changes generate a new
client_id, SetupSendgridMailbox now updates the existing SendGrid inbound
parse webhook URL instead of silently skipping it. This prevents inbound
emails from being rejected with 'unregistered_client' errors.

Previously, if a mailbox already existed in SendGrid, the code would exit
early without checking if the webhook URL matched the current client_id.
This caused production domains to lose inbound mail after re-registration.

Changes:
- Added http_patch import to sendgrid.py
- Modified SetupSendgridMailbox._run() to compare existing webhook URL
  with expected URL
- When URLs mismatch, PATCH the webhook to update with correct client_id
- Preserves existing spam_check and send_raw settings during update
- Updated test_skips_request_when_domain_already_exists to mock JSON response
- Added test_updates_webhook_when_url_mismatches to verify PATCH behavior

Fixes inbound email loss bug reported for production domains.
@dahagag dahagag merged commit 793f8c8 into ascoderu:master Jun 1, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant