feat(webhooks): per-form scope, delivery status, Discord URL guard#197
Merged
Conversation
Follow-up to the Discord webhook format, addressing two customer reports. Per-form webhooks: a webhook can now be scoped to a single form instead of the whole guild. A new nullable Webhook.formId (null = every form) is matched in enqueueWebhooks against the event's form, so a guild can route each form to its own endpoint or Discord channel. The add form gains a "Form scope" selector (default: all forms) and each row shows its scope. Delivery visibility: the webhooks page now shows each endpoint's last delivery outcome (delivered / failed with the error / pending), so a hook that isn't logging can be diagnosed instead of failing silently. Discord URL guard: pasting a Discord webhook URL while leaving the generic JSON format is now rejected with a clear message. That combination posts a raw signed body Discord rejects, which is the most likely reason a test submission "didn't log". Schema: Webhook.formId (+ FK, index) and a (webhook_id, created_at) index for the latest-delivery lookup (+ migration). Localized in all 7 languages. Shared tests for the guard and form scope (92). Typecheck, lint, test, build green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the Discord webhook format (#196), driven by two customer reports:
1. Per-form webhooks (the "different webhook per form" ask)
A webhook can now be scoped to a single form instead of the whole guild. New nullable
Webhook.formId(null = every form, the existing behaviour) is matched inenqueueWebhooksagainst the event's form, so a guild can route each form to its own endpoint or Discord channel. The add form gains a Form scope selector (default: all forms) and each row shows its scope.2. Why "it didn't log" — two fixes
Schema
Webhook.formId(+ FKON DELETE CASCADE, index) and a(webhook_id, created_at DESC)index for the latest-delivery lookup. Migration applies via the deployprisma migrate deploy.Localized in all 7 languages. Added shared tests for the guard and the form scope (shared 92). Typecheck, lint, tests and build all green.
Note
The most probable cause of the customer's issue is the JSON-format-plus-Discord-URL combination, now blocked at validation. If their hook was a correct generic JSON endpoint, the new "last delivery" line on the page will show the actual failure (bad URL, non-2xx, timeout).