feat(triggers): add GitLab, PagerDuty, and Zendesk webhook triggers#5150
Conversation
Add webhook trigger support for three integrations that previously had blocks but no triggers: - GitLab: push, merge request, issue, pipeline, comment, and all-events. Verifies the X-Gitlab-Token secret token; filters by object_kind. - PagerDuty: incident triggered/acknowledged/resolved/escalated/reassigned and all-events. Verifies X-PagerDuty-Signature (HMAC-SHA256 over raw body, comma-separated rotation); idempotency on event id. - Zendesk: ticket created/status changed/comment added/priority changed and all-events. Verifies X-Zendesk-Webhook-Signature (base64 HMAC-SHA256 over timestamp+body); idempotency on event id. Register GitLab's X-Gitlab-Event-UUID delivery header for webhook idempotency dedup.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview GitLab, PagerDuty, and Zendesk blocks now set Trigger definitions are registered for GitLab (push, MR, issue, pipeline, comment, catch-all), PagerDuty (incident lifecycle + catch-all), and Zendesk (ticket created/status/comment/priority + catch-all), each with shared utils for event mapping, UI fields, and workflow outputs. New webhook provider handlers implement provider-specific auth (GitLab Registry wires Reviewed by Cursor Bugbot for commit 04ab0b0. Configure here. |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fd4de8d. Configure here.
Greptile SummaryAdds webhook trigger support for GitLab, PagerDuty, and Zendesk — three providers that already had action blocks but no inbound trigger capability. Each provider gets a full set of event-specific triggers plus a catch-all webhook trigger, auto-registration of the webhook on deploy/teardown on undeploy, and correct signature verification.
Confidence Score: 5/5Safe to merge — all three new webhook integrations use correct, provider-documented signature schemes, timestamp guards where required, and consistent auto-registration/cleanup patterns. The auth paths are correct for each provider (plain-token compare for GitLab, HMAC with rotation for PagerDuty, timestamped HMAC for Zendesk), idempotency headers and IDs are wired properly, and the deploy/undeploy subscription lifecycle handles failure cases with orphan-cleanup logic. Previously flagged items from earlier review rounds have been addressed. The remaining open items are cosmetic duplication and a trivial missing guard that do not affect runtime correctness. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Provider as GitLab / PagerDuty / Zendesk
participant Sim as Sim Webhook Handler
participant Auth as verifyAuth
participant Match as matchEvent
participant Idem as IdempotencyService
participant WF as Workflow Engine
Note over Provider,Sim: Inbound webhook delivery
Provider->>Sim: "POST /webhook/{id} + signature headers"
Sim->>Auth: verifyAuth(request, rawBody, providerConfig)
alt GitLab
Auth-->>Sim: safeCompare(X-Gitlab-Token, secret)
else PagerDuty
Auth-->>Sim: "HMAC-SHA256 over rawBody, any v1= part matches"
else Zendesk
Auth-->>Sim: timestamp freshness check + HMAC-SHA256 over timestamp+body
end
Sim->>Idem: deduplicate(X-Gitlab-Event-UUID / event.id / body.id)
Idem-->>Sim: "new | duplicate"
Sim->>Match: matchEvent(body, triggerId)
Match-->>Sim: "true (event type matches) | false (skip)"
Sim->>WF: formatInput → execute workflow
Note over Provider,Sim: On deploy / undeploy
Sim->>Provider: createSubscription (PAT / API key)
Provider-->>Sim: externalId + signingSecret
Sim->>Provider: deleteSubscription(externalId) on undeploy
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Provider as GitLab / PagerDuty / Zendesk
participant Sim as Sim Webhook Handler
participant Auth as verifyAuth
participant Match as matchEvent
participant Idem as IdempotencyService
participant WF as Workflow Engine
Note over Provider,Sim: Inbound webhook delivery
Provider->>Sim: "POST /webhook/{id} + signature headers"
Sim->>Auth: verifyAuth(request, rawBody, providerConfig)
alt GitLab
Auth-->>Sim: safeCompare(X-Gitlab-Token, secret)
else PagerDuty
Auth-->>Sim: "HMAC-SHA256 over rawBody, any v1= part matches"
else Zendesk
Auth-->>Sim: timestamp freshness check + HMAC-SHA256 over timestamp+body
end
Sim->>Idem: deduplicate(X-Gitlab-Event-UUID / event.id / body.id)
Idem-->>Sim: "new | duplicate"
Sim->>Match: matchEvent(body, triggerId)
Match-->>Sim: "true (event type matches) | false (skip)"
Sim->>WF: formatInput → execute workflow
Note over Provider,Sim: On deploy / undeploy
Sim->>Provider: createSubscription (PAT / API key)
Provider-->>Sim: externalId + signingSecret
Sim->>Provider: deleteSubscription(externalId) on undeploy
Reviews (9): Last reviewed commit: "docs(triggers): note GitLab tag_push onl..." | Re-trigger Greptile |
|
@greptile review |
Greptile SummaryAdds webhook trigger support for GitLab, PagerDuty, and Zendesk — three integrations that previously had blocks but no inbound trigger capability. Each follows the existing manual-registration pattern (user pastes the signing secret, no fragile auto-create calls).
Confidence Score: 4/5The three new integrations are well-structured and follow the established provider pattern; the only issues are a dead function parameter and a minor inconsistency in the Zendesk body guard. The signature verification logic for all three providers is correct, the event-matching maps align with documented payload shapes, and idempotency is wired up consistently. The apps/sim/triggers/gitlab/utils.ts (unused triggerLabel parameter) and apps/sim/lib/webhooks/providers/zendesk.ts (missing body guard in validateZendeskSignature). Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant P as Provider<br/>(GitLab/PagerDuty/Zendesk)
participant W as Webhook Route
participant R as Provider Registry
participant H as Provider Handler
participant I as Idempotency Service
participant Q as Execution Queue
P->>W: "POST /webhook/{id}"
W->>R: getHandler(provider)
R-->>W: gitlabHandler / pagerdutyHandler / zendeskHandler
W->>H: verifyAuth(secret, headers, rawBody)
alt Signature valid
H-->>W: null (pass)
else Invalid
H-->>W: 401 Unauthorized
end
W->>H: matchEvent(triggerId, body)
alt Event matches trigger
H-->>W: true
else No match
H-->>W: false (skip)
end
W->>I: checkIdempotency(x-gitlab-event-uuid / event.id / body.id)
alt Not a duplicate
I-->>W: proceed
W->>H: formatInput(body, headers)
H-->>W: "{ input: { ... } }"
W->>Q: enqueue execution
else Duplicate
I-->>W: skip (already processed)
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant P as Provider<br/>(GitLab/PagerDuty/Zendesk)
participant W as Webhook Route
participant R as Provider Registry
participant H as Provider Handler
participant I as Idempotency Service
participant Q as Execution Queue
P->>W: "POST /webhook/{id}"
W->>R: getHandler(provider)
R-->>W: gitlabHandler / pagerdutyHandler / zendeskHandler
W->>H: verifyAuth(secret, headers, rawBody)
alt Signature valid
H-->>W: null (pass)
else Invalid
H-->>W: 401 Unauthorized
end
W->>H: matchEvent(triggerId, body)
alt Event matches trigger
H-->>W: true
else No match
H-->>W: false (skip)
end
W->>I: checkIdempotency(x-gitlab-event-uuid / event.id / body.id)
alt Not a duplicate
I-->>W: proceed
W->>H: formatInput(body, headers)
H-->>W: "{ input: { ... } }"
W->>Q: enqueue execution
else Duplicate
I-->>W: skip (already processed)
end
|
…protection Address review feedback: - Add paramVisibility: 'user-only' to the webhookSecret fields for GitLab, PagerDuty, and Zendesk so signing secrets are scoped to the credential owner and not exposed to workspace collaborators (repo convention). - Reject Zendesk deliveries whose signed timestamp is more than 5 minutes from now, closing a replay window once an event id ages out of the idempotency cache. The X-Zendesk-Webhook-Signature-Timestamp header is ISO-8601, so it is parsed with Date.parse (matches the Slack handler's skew-check convention).
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c2e7e01. Configure here.
Replace the manual-registration model with automatic webhook creation on deploy and cleanup on undeploy, via createSubscription/deleteSubscription on each provider handler: - GitLab: POST /projects/:id/hooks with a Personal Access Token; generates the secret token (stored for X-Gitlab-Token verification) and enables only the event flags for the selected trigger. Deletes the hook on undeploy. - PagerDuty: POST /webhook_subscriptions (account-scoped) with a REST API key; captures delivery_method.secret (returned only on create) for X-PagerDuty-Signature verification. Deletes the subscription on undeploy. - Zendesk: POST /api/v2/webhooks with native event subscriptions, then GET /webhooks/:id/signing_secret for X-Zendesk-Webhook-Signature verification. Deletes the webhook on undeploy. Trigger config now collects the provider credentials (user-only) instead of a pasted signing secret; the signing secret is generated or fetched and stored in providerConfig by the orchestration layer (no route/deploy changes).
|
@greptile review |
|
@cursor review |
…desk orphans Address review feedback on the auto-registration changes: - verifyAuth now rejects (401) when webhookSecret is absent for GitLab, PagerDuty, and Zendesk. Since the secret is generated/fetched during auto-registration and stored before the webhook can receive deliveries, a missing secret indicates misconfiguration and must fail closed rather than skip signature verification. Adds an opt-in requireSecret flag to createHmacVerifier (default off, preserving behavior for other providers). - Zendesk createSubscription now deletes the just-created webhook if the follow-up signing-secret fetch fails, avoiding an orphaned subscription in Zendesk when setup cannot complete.
|
@greptile review |
|
@cursor review |
Extend the orphan-prevention fix to the remaining providers. When a create call succeeds but post-create validation fails, the created webhook is now deleted before throwing: - GitLab: if the create response can't be parsed for its hook id, the hook is located by its URL and deleted. - PagerDuty: if the subscription response lacks an id or signing secret, the subscription is deleted (by id when known, otherwise located by URL). Both cleanups are best-effort and never throw.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 7db4ca8. Configure here.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 04ab0b0. Configure here.
|
@greptile review |
Summary
X-Gitlab-Tokensecret token; filters byobject_kind.X-PagerDuty-Signature(HMAC-SHA256 over the raw body, handles comma-separated rotation signatures); dedups on event id.X-Zendesk-Webhook-Signature(base64 HMAC-SHA256 overtimestamp + body); dedups on event id.X-Gitlab-Event-UUIDdelivery header for webhook idempotency.All three use the manual-registration model (user creates the webhook in the provider UI, pastes the signing secret) consistent with the existing GitHub trigger — no fragile auto-create API calls. Every signature scheme, event string, and payload field was verified against the providers' live docs.
Type of Change
Testing
Tested manually:
bun run type-checkpasses; idempotency + provider handler tests pass. Output schema ↔formatInputalignment verified for all triggers. First real delivery from each provider is the standard post-merge smoke test.Checklist