Skip to main content

Crate webhooksmith

Crate webhooksmith 

Source
Expand description

Webhook delivery for Rust backed by Postgres or SQLite.

HMAC-SHA256 signing, exponential backoff retry, dead letter queue, idempotent sends, event-type filtering, circuit breaker, and SSRF protection — all backed by your existing database. No Redis, no external queue service.

§Quick start

use webhooksmith::WebhookEngine;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let engine = WebhookEngine::builder()
        .database_url("postgres://user:pass@localhost/mydb")
        .build()
        .await?;

    engine.migrate().await?;

    let endpoint = engine
        .register("https://partner.example.com/webhooks", "your-signing-secret")
        .await?;

    engine.send("order.created", json!({"id": 1001}), endpoint.id).await?;

    // Blocks until the process exits; use run_graceful() for signal handling
    engine.run().await;
}

§Transactional outbox

Write your business data and the webhook event in the same database transaction. If the transaction rolls back, the event never exists.

ⓘ
let mut tx = engine.pool().begin().await?;

// Your business logic — use any sqlx query here
sqlx::query!("INSERT INTO orders (id) VALUES ($1)", order_id)
    .execute(&mut *tx).await?;

// Only queued if this transaction commits
engine.send_in_tx("order.created", json!({"id": order_id}), endpoint_id, &mut tx).await?;

tx.commit().await?;

§Features

FeatureDescription
postgres (default)Full transactional outbox using SELECT FOR UPDATE SKIP LOCKED
sqliteSqliteEngine — same API, no Postgres required

§See also

Re-exports§

pub use model::is_private_host;
pub use model::is_private_ip;
pub use engine::WebhookEngine;
pub use error::HooksmithError;
pub use error::Result;
pub use model::DeliveryAttempt;
pub use model::Endpoint;
pub use model::EventStatus;
pub use model::NewEndpoint;
pub use model::QueueStats;
pub use model::UpdateEndpoint;
pub use model::WebhookEvent;
pub use model::event_matches_filter;
pub use worker::DeliveryWorker;
pub use worker::SsrfSafeDnsResolver;
pub use sqlite_engine::SqliteEngine;

Modules§

backends
engine
error
model
retry
signing
sqlite_engine
SQLite-backed WebhookEngine.
worker