Search by

sudiptpa / laravel-sent-dm

sudiptpa

An expressive Laravel adapter for the Sent.dm unified messaging API: SMS, WhatsApp and RCS with a fluent, elegant interface.

Package info

github.com/sudiptpa/laravel-sent-dm

pkg:composer/sudiptpa/laravel-sent-dm

Fund package maintenance!

sudiptpa

Statistics

Installs: 130

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v2.1.0 2026-10-03 14:55 UTC

README

laravel-sent-dm

Tests Latest Stable Version Total Downloads License

A Laravel integration for Sent.dm, the unified messaging API for SMS, WhatsApp, and RCS.

This package wraps the official sentdm/sent-dm-php SDK with Laravel features for sending messages, queueing jobs, notification channels, handling webhooks, logging delivery state, managing opt-outs, scoping organization profiles, and testing without real API calls.

All HTTP transport goes through the official SDK. Sender profiles, compliance, and non-voice channel setup use the SDK client's request method until the SDK adds named methods for those endpoints.

What this package handles

  • Immediate or queued sends: send() sends now; sendLater() dispatches a job.
  • MMS and scheduled sends: attach media, add a subject, or schedule delivery.
  • Auto-channel routing: Sent.dm chooses WhatsApp or SMS based on reachability.
  • Webhook signature verification: HMAC-SHA256 checked before handlers run.
  • Voice calls: manage voice numbers, app tokens, calls, and participants.
  • Idempotent deduplication: retried webhook events do not fire listeners twice.
  • Rate limit handling: queued sends retry after the API's Retry-After delay.
  • Caching: caches contacts, profiles, number lookups, and template names.
  • Multi-tenancy: switch accounts with Sent::connection().
  • Organization profile scoping: scope resource calls with ->profile($id).
  • Message log: records queued sends and syncs webhook delivery status.
  • Opt-out compliance: handles STOP/UNSTOP and can guard opted-out sends.
  • Testing: Sent::fake() gives assertions without real API calls.

What stays in your application

These choices stay in your application:

  • When to send: decide timing in your own business logic.
  • Template content: create and manage templates in the Sent.dm dashboard.
  • Campaign scheduling: use Laravel's schedule() to dispatch bulk sends.
  • Analytics UI: build dashboards from your own data, such as $user->sentMessages().
  • Contact imports: sync from your database with Sent::contacts()->create() in a job or command.
  • Custom retry strategies: listen to MessageFailed and re-dispatch with your own rules.
  • Per-user notification preferences: check $user->optedOutFromSent() before sending.

Requirements

  • PHP 8.2+ for Laravel 11 and 12
  • PHP 8.3+ for Laravel 13
  • Laravel 11, 12, or 13

Installation

composer require sudiptpa/laravel-sent-dm

Publish the config file:

php artisan sent:install

Add your API key to .env:

SENT_API_KEY=your-api-key

Verify the connection and local package configuration:

php artisan sent:health

See the upgrade guide before updating an existing installation.

Configuration

The published config is at config/sent.php:

'default' => env('SENT_CONNECTION', 'default'),

'connections' => [
    'default' => [
        'api_key' => env('SENT_API_KEY'),
    ],
],

'default_channel' => env('SENT_DEFAULT_CHANNEL'), // null = auto-route

'queue' => [
    'connection' => env('SENT_QUEUE_CONNECTION'),
    'name'       => env('SENT_QUEUE_NAME', 'default'),
],

'webhook' => [
    'enabled' => env('SENT_WEBHOOK_ENABLED', false),
    'secret'  => env('SENT_WEBHOOK_SECRET'),
    'path'    => env('SENT_WEBHOOK_PATH', 'sent/webhook'),
],

'cache' => [
    'enabled' => env('SENT_CACHE_ENABLED', true),
    'ttl'     => env('SENT_CACHE_TTL', 3600),
],

'sandbox' => env('SENT_SANDBOX', false),

'logging' => [
    'enabled' => env('SENT_LOGGING_ENABLED', false),
],

'opt_out' => [
    'enabled' => env('SENT_OPT_OUT_ENABLED', false),
    'guard'   => env('SENT_OPT_OUT_GUARD', false),
    'tenant_resolver' => null, // optional tenant-aware opt-out resolver
    'keywords' => ['STOP', 'UNSUBSCRIBE', 'CANCEL', 'END', 'QUIT'],
    'opt_in_keywords' => ['START', 'YES', 'UNSTOP'],
],

Quick start

use Sujip\SentDm\Facades\Sent;

Sent::to('+61412345678')
    ->template('otp-verification')
    ->send();

This sends immediately. For queued sends, plain-text bodies, channel selection, template variables, and bulk sends, see Sending messages.

Documentation

Guide Covers
Sending messages Immediate and queued sends, template variables, idempotency, bulk messaging, the notification channel
Sandbox mode Simulating writes without real delivery, per-call and globally
Webhooks Receiving delivery events, signature verification, managing endpoints from code
Message log The opt-in sent_logs table, HasSentMessages, query scopes, status tracking
Opt-out management STOP/START keyword handling, tenant-aware opt-outs, HasSentContact, the send guard
Multi-tenancy Organization profile scoping and multiple Sent.dm connections
Number lookup and validation Carrier lookup and the sentMobileNumber validation rule
API reference Contacts, Templates, Profiles, Users, Messages, Conversations, Account, Artisan commands
Testing Sent::fake() and its full assertion set

Sponsoring

Sponsor

If this package helps your project, GitHub Sponsors is a simple way to support maintenance and future releases.

Contributing

Contributions are welcome. Open an issue to discuss larger changes, or send a pull request for bug fixes and small improvements.

Before submitting, run:

composer test
composer stan
composer lint:check

License

This package is open source, licensed under the MIT license.