Skip to content

SMS Sending Workflow ​

The Notifications module can send SMS messages through Twilio. The current implementation keeps SMS delivery simple: it sends a raw message body, records the delivery attempt, and exposes a development-only endpoint for manual testing.

How It Works ​

  1. A caller sends a request to POST /api/notifications/sms/test.
  2. The SmsController validates the payload with the shared sendTestSmsSchema.
  3. The controller dispatches a SendSmsNotificationCommand with the fixed log key manual-test-sms.
  4. The SendSmsNotificationHandler calls the TwilioSmsAdapter, emits structured app logs for provider failures, and persists a NotificationLog with type: SMS.
  5. On success, the API returns the Twilio message SID as providerMessageId.
  6. On failure, the command still writes a failed notification log and returns an application error.

Required Twilio Environment Variables ​

  • TWILIO_ACCOUNT_SID: Twilio account SID used to authenticate the SDK.
  • TWILIO_AUTH_TOKEN: Twilio auth token paired with the account SID.
  • TWILIO_MESSAGING_SERVICE_SID: Recommended sender configuration when using a Twilio Messaging Service.
  • TWILIO_FROM_PHONE_NUMBER: Fallback sender number in E.164 format when a messaging service is not used.

At least one sender option must be configured: TWILIO_MESSAGING_SERVICE_SID or TWILIO_FROM_PHONE_NUMBER.

Test Endpoint ​

  • Route: POST /api/notifications/sms/test
  • Availability: development only
  • Rate limit: 3 requests per 5 minutes per IP
  • Request body:
    • to: destination phone number in E.164 format
    • message: SMS body text

Example payload:

json
{
  "to": "+15555550123",
  "message": "Hello from DaraMex"
}

Twilio Notes ​

  • Twilio expects phone numbers in E.164 format.
  • Trial Twilio accounts can only send to verified recipient numbers.
  • If both sender options are configured, the adapter prefers TWILIO_MESSAGING_SERVICE_SID over TWILIO_FROM_PHONE_NUMBER.

Observability ​

SMS failures now emit structured OTEL log events through AppLoggerService in addition to the notifications.notification_logs audit row:

  • notifications.sms.provider_misconfigured: emitted when Twilio credentials or sender configuration are missing.
  • notifications.sms.delivery_failed: emitted when Twilio rejects or fails a send attempt.
  • notifications.sms.log_persist_failed: emitted when the NotificationLog row cannot be saved.

These events include templateKey, recipient, channel, any available entity IDs, and Twilio-specific diagnostics when present (providerErrorCode, providerMoreInfo, providerDetails, or missingVariables). This makes provider failures queryable in Loki without inspecting the database directly.

Error Handling ​

If Twilio is not configured or rejects the request, the API returns an application error, emits a structured app log, and stores the failure reason in notifications.notification_logs.error. For Twilio RestException responses, the stored value is a JSON string that includes message, code, moreInfo, and details, so provider diagnostics are preserved for debugging in both the database row and the OTEL log stream.