Files
suaveplan/packages/communication/messaging/sms-providers/src/messagebird/messagebird.md
2026-05-27 23:29:53 +01:00

3.0 KiB

MessageBird — @suaveplan/sms-providers

(no submodules)

Purpose

Real MessageBird SMS provider implementing SmsProvider from @suaveplan/sms. POSTs to /messages with Authorization: AccessKey <key>; status fetched via GET /messages/{id}. Inbound webhook signature verification follows the MessageBird Signed Webhooks v2 (Messagebird-Signature-Jwt) spec — a JWT HS256 carrying iat/exp/nbf/payload_hash claims; the verifier checks the timestamp window (default ±5 minutes), re-MACs the canonical header.payload, and constant-time compares the base64url-decoded signature.

The class holds no in-flight state and routes every HTTP call through the injectable FetchLike seam. Tests stand up a node:http server on a random port and inject a fetch adapter that points at it.

Features

  • AccessKey auth header per MessageBird's documented scheme.
  • JSON body with recipients[], originator, body.
  • Status mapping covers scheduled / sent / buffered / delivered / expired / delivery_failed.
  • JWT HS256 webhook verifier with iat / exp / nbf window enforcement and optional payload_hash cross-check.
  • Injectable nowMs + toleranceMs so tests pin the clock and the production deployment can widen the freshness window if needed.
  • parseInbound discriminates between inbound messages and DLRs, recognising the standard CTIA opt-out keywords.
  • OTel — send_total + send_duration_ms + signature_failures_total + webhook_verify_duration_ms.

Usage: Basic

import { MessageBirdProvider } from "@suaveplan/sms-providers";

const mb = new MessageBirdProvider({ accessKey: "test_…" });
await mb.send({ to: "+15551234567", from: "Suaveplan", body: "hi" });

Usage: Advanced

import { MessageBirdProvider } from "@suaveplan/sms-providers";

const mb = new MessageBirdProvider({ accessKey: "live_…" });
const ok = await mb.verifyWebhookSignature(
    "<header>.<payload>.<sig>",
    "shared-signing-key",
    { bodyHashHex: "<sha256-hex>", nowMs: Date.now(), toleranceMs: 60_000 }
);

API Reference

Symbol Kind Notes
MessageBirdProvider class Implements SmsProvider.
send(message, options?) method POST /messages, returns SmsDeliveryReport.
getStatus(id) method GET /messages/{id}.
mapStatus(raw) method Canonical mapping.
verifyWebhookSignature(token, signingKey, options?) method JWT HS256 verifier; throws SIGNATURE_INVALID on failure.
parseInbound(body) method Discriminates into InboundSmsEvent.

Implementation Notes

The verifier handles both standard Base-64 and base64url (-/_ → +//) inputs because MessageBird's JWT uses the URL-safe variant. payload_hash is checked only when both the JWT carries it and the caller supplies a bodyHashHex; missing on either side is treated as "skip" so callers can disable the body binding when their proxy strips bodies.