Skip to main content

webhook

Attribute Macro webhook 

Source
#[webhook]
Expand description

Marks a function as a webhook handler.

Webhooks are HTTP endpoints for receiving external events (e.g., from Stripe, GitHub). They support signature validation, idempotency, and bypass authentication middleware.

§Attributes

  • path = "/webhooks/stripe" - URL path (required)
  • signature = WebhookSignature::hmac_sha256("Header", "SECRET_ENV") - Signature validation
  • idempotency = "header:X-Request-Id" - Idempotency key source
  • timeout = "30s" - Request timeout

§Signature Validation

Use WebhookSignature helper for common patterns:

  • WebhookSignature::hmac_sha256("X-Hub-Signature-256", "GITHUB_SECRET") - GitHub
  • WebhookSignature::hmac_sha256("X-Stripe-Signature", "STRIPE_SECRET") - Stripe
  • WebhookSignature::hmac_sha1("X-Signature", "SECRET") - Legacy SHA1

§Idempotency

Specify source as "header:Header-Name" or "body:$.json.path":

  • "header:X-GitHub-Delivery" - From header
  • "body:$.id" - From JSON body field

§Example

#[forge::webhook(
    path = "/webhooks/github",
    signature = WebhookSignature::hmac_sha256("X-Hub-Signature-256", "GITHUB_SECRET"),
    idempotency = "header:X-GitHub-Delivery",
)]
pub async fn github_webhook(ctx: &WebhookContext, payload: Value) -> Result<WebhookResult> {
    let event_type = ctx.header("X-GitHub-Event").unwrap_or("unknown");
    ctx.dispatch_job("process_github_event", &payload).await?;
    Ok(WebhookResult::Accepted)
}

#[forge::webhook(path = "/webhooks/stripe", timeout = "60s")]
pub async fn stripe_webhook(ctx: &WebhookContext, payload: Value) -> Result<WebhookResult> {
    // Process Stripe event
    Ok(WebhookResult::Ok)
}