Twilio status callbacks
Twilio fires status callbacks for every SMS as it moves through their system. We verify, dedup, store, and use these for delivery confirmation + failure alerts.
Statuses received
queued→sending→sent(Twilio side)delivered(carrier accepted)failed/undelivered(carrier rejected)
Webhook handler
/webhook/twilio/status (src/routes/webhook-twilio-status.ts):
- Parse form-urlencoded body (Twilio uses form encoding, not JSON)
- Verify signature: HMAC-SHA1 of URL + sorted form params keyed by
TWILIO_AUTH_TOKEN.X-Twilio-Signatureheader. - Insert into
twilio_events(dedup on(MessageSid, MessageStatus)) - Sync terminal-state to
outbound_log:delivered→markOutboundDeliveredfailed/undelivered→markOutboundFailedwith reason"failed (Twilio {ErrorCode}: {ErrorMessage})"
- Alert on terminal failure: SMS Bill with recipient + error
Outbound integration
sendSMS in src/twilio/client.ts automatically attaches
StatusCallback={env.TWILIO_STATUS_CALLBACK_URL} if the env var is
set. Currently:
TWILIO_STATUS_CALLBACK_URL=https://stayonthesnow-pms.minnetonka.workers.dev/webhook/twilio/status(set via wrangler secret put).
Also records to outbound_log on send with channel='sms',
message_id=result.sid, booking_id + purpose from the call’s
params.
Schema (twilio_events)
event_sid, message_sid, status, recipient, error_code, error_message,raw, received_atevent_sid = {MessageSid}:{MessageStatus} for dedup.
Inbound SMS
Separate endpoint: /webhook/sms/inbound (src/routes/webhook-sms.ts)
handles incoming SMS to Bill’s Twilio number. Verifies signature,
logs to migration_log, forwards via email to Bill.
Source
src/routes/webhook-twilio-status.ts— receiversrc/lib/twilio-signature.ts— HMAC-SHA1 helpersrc/twilio/client.ts—sendSMSwith auto-attachmigrations/0024_delivery_observability.sql(includestwilio_events)- Tests:
test/routes/webhook-twilio-status.test.ts(13 cases)