Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Intercom Laravel Package

laravel-notification-channels/intercom

Laravel Notification Channels Intercom adds an Intercom channel to Laravel notifications, letting you send messages and updates to users through Intercom from your existing notification classes. Requires Laravel and an Intercom access token.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a thin bridge between Laravel's notification system and Intercom's PHP SDK: it lets an existing Notification class fan out to Intercom (in-app messages, emails, and contact/event updates) using the same via() / toX() contract you already use for mail, SMS, and database notifications.

Version 1.4.0 added Laravel 9 support (PR #14), so you can use the channel on Laravel 9 if your other dependencies allow. There are no new features in this release — just compatibility and style fixes.

Minimal steps:

composer require laravel-notification-channels/intercom
php artisan vendor:publish --provider="NotificationChannels\Intercom\IntercomServiceProvider"

Set the token in .env (usually INTERCOM_TOKEN) and pick the config file that gets published (config/intercom.php). Before wiring anything into a real notification, read three files in the vendor directory, in this order:

  1. src/IntercomChannel.php — shows exactly how the notification is dispatched and what exceptions bubble up.
  2. src/IntercomMessage.php — the fluent message builder; this is the API you will actually spend time with.
  3. config/intercom.php — token, and (critically) any base-URI/region setting.

First use case: a transactional in-app message to a known Intercom contact when something happens in your app (invoice paid, seat assigned, invite accepted).

use Illuminate\Notifications\Notification;
use NotificationChannels\Intercom\IntercomChannel;
use NotificationChannels\Intercom\IntercomMessage;

class InvoicePaid extends Notification
{
    public function via($notifiable): array
    {
        return [IntercomChannel::class];
    }

    public function toIntercom($notifiable)
    {
        return IntercomMessage::create()
            ->to($notifiable->intercom_id)   // contact id, not Laravel user id
            ->withTitle('Invoice paid')
            ->withBody('Thanks — your receipt is ready.');
    }
}

If the fluent method names differ in your pinned version, mirror what IntercomMessage exposes; the pattern is stable even when method names drift.

Implementation Patterns

Resolve the Intercom identity on the notifiable, not in the notification. Add a routeNotificationForIntercom() method (or an intercom_id attribute) so the channel and message builder don't need to guess between email and contact id:

public function routeNotificationForIntercom()
{
    return $this->intercom_id;
}

Separate "notify a human" from "update the contact record." The package is a notification channel; contact attributes, tags, and events are better handled in a small service or job that calls the Intercom client directly. Don't try to make a notification do contact sync — it gets messy fast and you lose idempotency.

Queue everything. Add implements ShouldQueue to the notification (or use Notification::route(...)->notify() from a job). Intercom's API is rate-limited and network-bound; a synchronous call inside a web request is a latency and failure liability.

Template vs. inline body. For anything user-facing and recurring, prefer an Intercom-side template (so copy changes don't require a deploy) and pass variables from toIntercom(). Keep the Laravel notification responsible for when and to whom, and Intercom responsible for what it says.

Admin sender. Admin-initiated messages typically require a from admin id. Put it in config (intercom.admin_id) and inject it in the message builder rather than hardcoding it in every notification.

Testing. Use Notification::fake() and assert on the notification class, not the Intercom payload. For the payload shape, unit-test the builder in isolation:

Notification::fake();
$user->notify(new InvoicePaid($invoice));
Notification::assertSentTo($user, InvoicePaid::class);

Compose with other channels. Intercom as an additional channel alongside mail and database is the sweet spot — Intercom for in-app/retention messaging, mail for the legally-required receipt.

Gotchas and Tips

  • Maintenance risk is still the headline, but the 1.4.0 bump helps. The Laravel 9 compatibility merge (1.4.0) shows the channel keeps pace with supported framework versions, but the codebase is small and releases are spaced out — there's no promise of Laravel 10/11 support on any particular timeline. Treat this as a small piece of glue you may need to fork. Pin the version in composer.json, and keep the Intercom calls behind one or two classes so a swap (or a direct HTTP client) is a localized change.
  • Framework compatibility. 1.4.0 is the minimum if you are on Laravel 9. If you are on Laravel 10+, verify support in composer.json before adopting — the release notes only mention Laravel 9. Check the constraint (illuminate/*) rather than assuming forward compatibility.
  • Region/base URI. Intercom has separate US, EU, and AU workspaces (api.intercom.io vs api.eu.intercom.io vs api.au.intercom.io). If the config doesn't expose a base URI, you'll need to bind a configured IntercomClient yourself in a service provider. This is the most common "it works locally, 401s in prod" cause.
  • Token type. Access tokens and OAuth tokens are not interchangeable, and a token scoped to one workspace will silently fail against another. Verify with a single GET /me before debugging the channel.
  • Contact existence. Intercom will not always auto-create a contact from a message call depending on message type and settings. If intercom_id is null, decide explicitly: skip the notification, or create the contact first. Silent no-ops are the usual failure mode.
  • Rate limits and 429s. The channel does not add retry/backoff for you. Wrap queued notifications with retryUntil/backoff, and be aware that a burst of notifications (e.g., a mass announcement) will hit limits fast — chunk it.
  • Config caching. php artisan config:cache after any .env change to the token; a stale cached config is a classic 15-minute debugging detour.
  • Error surface. Decide whether Intercom failures should fail the job. For transactional messages, fail loudly (so retries work). For marketing-ish messages, catch and log so one bad contact doesn't poison a batch.
  • Extension points worth knowing: rebind the IntercomClient in the container for region/proxy/mocking; macro the message class if you need a house style; and swap the channel's message class if you want a domain-specific builder without forking the package.
  • Documentation is the README. There's no deep docs site. Budget an hour to read IntercomChannel and IntercomMessage source before you build on it — it's faster than guessing method names from memory. The 1.4.0 changelog adds nothing to the docs, so the README remains the only reference.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource