Hookway

Send Sentry issue alerts to Discord

Use a Sentry internal integration to send signed webhooks to Hookway. Sentry alert rules select when to notify; Hookway verifies the request, filters issue alerts, formats a summary and queues delivery to a Discord webhook.

Start with the complete configuration. For another destination, use the builder's Sentry webhook template or the ingress template, then connect its envelope output to your own nodes. An inserted template requires an explicit protection-store choice. Complete configurations are also in the builder's Examples tab.

Configure Sentry and Discord

  1. Create a webhook in your Discord channel's integration settings and copy its complete URL. Treat the URL as a credential.

  2. Expose Hookway over HTTPS, with /webhooks/sentry routed to its webhook port. Keep the separate metrics port private. A development tunnel can expose your local webhook port for testing.

  3. In Sentry, open Settings → Developer Settings → Custom Integrations and create an internal integration named Hookway. Set its Webhook URL to https://YOUR-HOOKWAY-HOST/webhooks/sentry, enable Alert Rule Action, and grant Issue & Event: Read. Navigation labels can vary by Sentry version.

  4. Save and copy the integration's Client Secret into SENTRY_CLIENT_SECRET. Use the Client Secret, not the generated API token or a project DSN. Hookway does not need a Sentry API token for this flow.

  5. Set DISCORD_WEBHOOK_URL to the complete Discord webhook URL and set HOOKWAY_API_KEY for metrics. Start Hookway using the example:

    # Set the three environment variables securely before running these commands.
    go run ./cmd/hookway validate --config examples/sentry-discord.yaml
    go run ./cmd/hookway --config examples/sentry-discord.yaml
    
  6. Create an issue alert rule in Sentry, for example A new issue is created, optionally filtered to production. Add Send a notification via an integration and select Hookway. Choose the rule's notification frequency in Sentry. Issue lifecycle or raw error subscriptions are unnecessary for this recipe.

See Sentry's internal integration documentation and issue alert payload. This setup uses an internal integration within one organization; there is no public-app installation or OAuth exchange.

Try a signed fixture locally

With Hookway running and SENTRY_CLIENT_SECRET available in this terminal, run from the repository root. This posts the synthetic fixture to Hookway and, if accepted, sends a real message to the configured Discord channel:

python3 - <<'PY'
import hashlib
import hmac
import os
from pathlib import Path
import urllib.request

body = Path('examples/fixtures/sentry-issue-alert.json').read_bytes()
signature = hmac.new(os.environ['SENTRY_CLIENT_SECRET'].encode(), body, hashlib.sha256).hexdigest()
request = urllib.request.Request(
    'http://localhost:8080/webhooks/sentry', data=body, method='POST',
    headers={'Content-Type': 'application/json',
             'Sentry-Hook-Resource': 'event_alert',
             'Sentry-Hook-Signature': signature},
)
with urllib.request.urlopen(request, timeout=5) as response:
    print(response.status, response.read().decode())
PY

The message resembles:

Sentry: ReferenceError: checkout is not defined
Rule: New production issue
Project: storefront · Environment: production · Level: error
https://sentry.io/organizations/example/issues/123/events/0123456789abcdef0123456789abcdef/

One internal integration and webhook endpoint can serve multiple projects in the same Sentry organization. Select the integration in each project's alert rule, or use an organization-wide alert with All Projects when available in your Sentry UI. Your Sentry rules choose which new errors, escalations or regressions notify Discord.

The formatter uses a project name or slug from the payload, falling back to the project slug in Sentry's event API URL. It does not need an enrichment API call or a hardcoded project-ID list. If no readable project is available, it shows unknown project. It skips placeholder titles such as ? and <untitled>, then tries the event message, log entry, exception details and issue title. Environment comes from event.environment or its environment tag. Missing optional fields use readable fallbacks, and a missing human-facing web_url omits the link. Field limits keep the message below Discord's 2,000-character content limit, markdown in values is escaped, and allowed_mentions.parse is empty. The flow sends selected summary fields only, excluding user records, request contents and stack traces.

Authentication, acknowledgements and failures

The secret reference uses the existing refresh/rotation-overlap support. Environment changes require updating the running process's environment (normally by restarting it). Use a mounted-file secret reference for rotation without a process restart. Neither the secret nor Discord URL belongs in committed YAML.

Verify a live delivery

After deploying this version and configuring the integration, send a Sentry test notification if available, or generate a fresh test issue that matches your rule. Confirm the Sentry webhook log shows a timely 202 and exactly one message reaches the intended Discord channel. Check its title, rule, project, environment and clickable event link. A synthetic fixture's example link is not a live issue.

If no message arrives, check Sentry's delivery log first, then Hookway's signature failures, filter outcomes, queue/delivery metrics and Discord response status. A 202 proves queue admission, not Discord receipt. Local stub tests do not verify your public routing, account permissions or channel configuration.