MyComm docs
Menu

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')).