SDKs
Laravel
Install the Laravel package, configure it from your .env, send notifications, receive webhooks and test it.
mycomm/mycomm-laravel puts the PHP SDK into a Laravel 12 or 13 application: configuration from your
.env, a facade, a notification channel, a signed webhook route that dispatches Laravel events, a mycomm:verify command and a
fake for your tests.
composer require mycomm/mycomm-laravel
MYCOMM_API_KEY=mc_live_...
MYCOMM_WEBHOOK_SECRET=... # only if you receive webhooks
The service provider and the MyComm facade are discovered automatically.
Configuration#
| Environment variable | Default | What it does |
|---|---|---|
MYCOMM_API_KEY |
none, required | An account key (mc_live_...) or a partner key (mc_partner_...) |
MYCOMM_BASE_URL |
https://mycomm.cogneer.tech |
Origin of the API, without /v1; change it only to reach staging |
MYCOMM_MAX_RETRIES |
2 |
Retries after a network error, a 429 or a 5xx; sends carry an idempotency key, so a retry never sends twice |
MYCOMM_TIMEOUT |
30 |
Seconds per attempt |
MYCOMM_VALIDATE |
true |
Check arguments against the API's documented rules before sending |
MYCOMM_WEBHOOK_SECRET |
none | Signing secret of your webhook endpoint; new,old while rotating |
MYCOMM_WEBHOOK_TOLERANCE |
300 |
Seconds a webhook signature stays acceptable |
MYCOMM_WEBHOOK_DEDUPLICATE |
true |
Acknowledge an event id seen in the last 7 days without dispatching it again |
Publish the config file with php artisan vendor:publish --tag=mycomm-config only to change something the variables do not cover.
Check the setup#
php artisan mycomm:verify --to=+923001234567
It checks the key and dry-runs a message to that number. It sends nothing, prints each check as PASS or FAIL with the API's
own message, and exits with code 1 when one fails, so it can run in a deploy script. MyComm::verify($to) does the same from
code, for a "test settings" button. See Verify your integration.
Send#
use MyComm\Laravel\Facades\MyComm;
$message = MyComm::messages()->send(
to: $order->phone,
body: "Order {$order->number} has shipped.",
category: 'transactional',
);
You can inject MyComm\Client instead; both are the same client. The facade calls a resource as a method
(MyComm::messages()->send(...)), the injected client has it as a property ($client->messages->send(...)). With a partner
key, send as one of your lines with MyComm::forLine($lineId)->messages->send(...); <x-mycomm-connect :line="$lineId" purpose="connect" /> renders the connect widget with a fresh link.
Notifications#
use Illuminate\Notifications\Notification;
use MyComm\Laravel\Notifications\MyCommMessage;
final class OrderShipped extends Notification
{
public function via(object $notifiable): array
{
return ['mycomm'];
}
public function toMyComm(object $notifiable): MyCommMessage
{
return MyCommMessage::create('Your order has shipped.')->category('transactional');
}
}
$customer->notify(new OrderShipped);
The number comes from routeNotificationForMyComm() on the notifiable, else its phone attribute. The notification's id is the
idempotency key, so a queued notification that is retried cannot send twice. When the send fails, the SDK exception reaches your
queue and a MyComm\Laravel\Events\MyCommNotificationFailed event carries a log-ready summary.
Receive webhooks#
Route::mycommWebhooks('webhooks/mycomm'); // routes/api.php
Create a webhook endpoint pointing at that URL and put its secret in MYCOMM_WEBHOOK_SECRET. The route verifies the signature,
skips an event it has seen, and dispatches each event as a normal Laravel event (MyComm\Webhooks\Events\MessageDelivered, ...;
MyComm\Laravel\Events\WebhookReceived for all of them). Queue your listeners, make them idempotent, and expect events out of order;
the package README explains the details, and the event catalogue lists every event.
Handle errors#
SDK exceptions pass through the facade unchanged: InvalidArgumentException (refused before sending), ApiException and its
subclasses. $e->summary() is one log line with the code, message, details and request id.
Test#
$fake = MyComm::fake();
$order->ship();
$fake->assertCalled('messages.send', fn ($request) => $request->json['to'] === $order->phone);
MyComm::fake() replaces the client for the facade and for injection; nothing reaches the network. Stub an answer with
$fake->respond('messages.send', FakeResponse::error(422, 'RECIPIENT_OPTED_OUT')).