symfony/gatewayapi-notifier
Symfony Notifier bridge for GatewayAPI SMS. Configure via GATEWAYAPI_DSN (token, from) and send SmsMessage with optional GatewayApiOptions (class, callback URL, user ref, labels, etc.) for advanced message settings.
Install the Package (via Composer):
composer require symfony/gatewayapi-notifier
Note: Requires Symfony components like symfony/notifier and symfony/http-client. Use composer require symfony/notifier symfony/http-client if missing.
Configure the DSN in .env:
GATEWAYAPI_DSN=gatewayapi://YOUR_OAUTH_TOKEN@default?from=YourSenderName
YOUR_OAUTH_TOKEN with your GatewayAPI OAuth token.from is the sender name (e.g., "YourApp").Register the Transport in a Laravel Service Provider:
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Bridge\GatewayApi\GatewayApiTransportFactory;
public function register()
{
$this->app->singleton('gatewayapi.transport', function ($app) {
$dsn = $app['config']['services.gatewayapi.dsn'];
return (new GatewayApiTransportFactory())->create($dsn);
});
}
Send Your First SMS:
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Notifier;
$notifier = new Notifier([$this->app->make('gatewayapi.transport')]);
$message = new SmsMessage('+1234567890', 'Hello from Laravel!');
$notifier->send($message);
GatewayApiOptionsExtend SMS messages with GatewayAPI-specific options (e.g., class, callbackUrl):
use Symfony\Component\Notifier\Bridge\GatewayApi\GatewayApiOptions;
$options = (new GatewayApiOptions())
->class('standard') // 'standard' or 'flash'
->callbackUrl('https://your-app.com/webhook')
->userRef('user_123')
->label('payment_confirmation');
$message = new SmsMessage('+1234567890', 'Your payment is confirmed!');
$message->options($options);
$notifier->send($message);
Offload notifications to a queue for async processing:
use Illuminate\Support\Facades\Bus;
Bus::dispatch(function () use ($notifier, $message) {
$notifier->send($message);
});
Configure QUEUE_CONNECTION in .env (e.g., redis, database).
Override the DSN per environment or dynamically:
// In a service provider or config file
'services.gatewayapi.dsn' => env('GATEWAYAPI_DSN', 'gatewayapi://default_token@default?from=DefaultSender'),
Leverage Symfony Notifier’s built-in retry logic:
$notifier = new Notifier([$transport], [
'max_retries' => 3,
'delay' => 1000, // 1 second between retries
]);
Use Symfony’s MockTransport for unit tests:
use Symfony\Component\Notifier\Transport\MockTransport;
$mockTransport = new MockTransport();
$notifier = new Notifier([$mockTransport]);
$notifier->send($message);
$this->assertCount(1, $mockTransport->sentMessages());
Symfony Dependency Conflicts:
notifier and http-client. If your Laravel app uses Guzzle or Laravel’s HTTP client, conflicts may arise.composer require symfony/notifier symfony/http-client --ignore-platform-req=php and alias packages in composer.json:
"replace": {
"guzzlehttp/guzzle": "symfony/http-client"
}
DSN Format Sensitivity:
gatewayapi:// and a valid OAuth token. Missing from defaults to undefined.if (!preg_match('/^gatewayapi:\/\/.+@.+$/', $dsn)) {
throw new \InvalidArgumentException('Invalid GatewayAPI DSN format.');
}
Rate Limiting:
throttle middleware or Symfony’s retry logic to handle failures gracefully.Callback URL Validation:
callbackUrl in GatewayApiOptions is publicly accessible. GatewayAPI will hit this URL on delivery events.route() helper to generate absolute URLs:
->callbackUrl(route('gatewayapi.webhook', [], false))
Enable Symfony Notifier Debug Mode:
$notifier = new Notifier([$transport], [
'debug' => true,
]);
Logs will include raw HTTP requests/responses.
Inspect Sent Messages:
Use a MockTransport in tests or a custom transport wrapper to log messages:
class DebugTransport implements TransportInterface
{
public function __invoke(MessageInterface $message, array $failedRecipients = []): void
{
\Log::debug('Sent message:', [
'recipient' => $message->getRecipients()[0],
'content' => $message->getContent(),
'options' => $message->options(),
]);
// Delegate to real transport...
}
}
Handle GatewayAPI Webhook Responses:
If using callbackUrl, ensure your Laravel endpoint validates signatures (GatewayAPI uses OAuth tokens). Example:
Route::post('/gatewayapi/webhook', function (Request $request) {
$token = config('services.gatewayapi.token');
$signature = $request->header('X-GatewayAPI-Signature');
if (!hash_equals($signature, hash_hmac('sha256', $request->getContent(), $token))) {
abort(403, 'Invalid signature');
}
// Process webhook...
});
Custom Transport Factory:
Extend GatewayApiTransportFactory to add Laravel-specific logic (e.g., queue integration):
class LaravelGatewayApiTransportFactory extends GatewayApiTransportFactory
{
public function create($dsn): TransportInterface
{
$transport = parent::create($dsn);
return new QueuedTransport($transport);
}
}
Add Laravel Events: Dispatch Laravel events when messages are sent:
class GatewayApiTransport implements TransportInterface
{
public function __invoke(MessageInterface $message, array $failedRecipients = []): void
{
event(new SmsSent($message));
// Send via GatewayAPI...
}
}
Override Message Serialization: Customize how messages are serialized for GatewayAPI (e.g., add metadata):
$message->options()->add('custom_metadata', ['key' => 'value']);
How can I help you explore Laravel packages today?