Integrating Intercom with Laravel

Choosing an analytics package for an application is never an easy decision. You can get a list of features from the website, and if you are lucky, it is possible to view the app in action in a webinar or live demo. However, ultimately, you never really know if it is going to work until you give it a try and unfortunately, this takes time. Intercom is our third attempt, and so far, it is looking like a great fit. That is not to say there weren't some challenges along the way, but that just makes it more fun, right?

What Did We Want to Achieve

At ubisend, we have spent lots of time translating our sales and marketing funnels into a key set of requirements for an analytics package. At a very high level, this consists of:

  • Capturing leads based on a customer action
  • Sending email drip campaigns to leads
  • Locating bottle-necks in our funnels
  • Capturing signups to our app
  • Monitoring user activity
  • Triggering retention emails based on user activity (or lack of activity)

Why Is This Difficult?

The obvious answer here is that there is not one analytics package which offers all of this functionality out of the box. We have trialled some analytics packages which are perfect for allowing you to track user activity once they are in the app, but offer no way of dealing with leads and vice versa. We have also tried separate packages for handling leads and customers, but this felt pretty cumbersome and made running reports tough.

What Did We End Up Doing

After lots of research, we came across Intercom. It seemed to satisfy many requirements, so we decided to take a look at the product overview webinar they were running. We were blown away by what it could do. In particular:

  • Capture leads and sends emails based on any criteria you can imagine using the powerful segmentation features.
  • Capture all events a user carries out in our app and trigger email or in-app messages based on their activity.
  • Robust reporting to make it easy to see where customers are getting stuck.
  • Separation of users and customers. This is ideal for ubisend as it is possible for a customer to have multiple users. Intercom makes it possible to see the activity of an entire customer and not just an individual user.

All of this coupled with the slick interface and the bonus of bundled customer support (which could replace our existing solution), meant we had to give it a try.

Let's Get Technical

Intercom segregates customers into two different groups. A Lead is someone who is yet to signup for an account, and a User is someone who has. Unfortunately, leads are only created by a customer initiating a conversation with Intercom Messenger or sending us an email. They cannot be created programmatically. Not an ideal start to the integration, but we like a challenge and the opportunity for thinking outside of the box.

Here Is Our Solution

We decided not to utilise the native Intercom Lead vs. User separation. Instead, we treat every Lead as a User and distinguish them by using the powerful Intercom custom user attributes. When we capture a Lead, we store the details in our database (more on that later), then provided they are not an existing Intercom User, we create them using the excellent Intercom API.

Firstly, we grab the unique ID from the Intercom cookie

1//check the cookie is set and grab the content
2$intercomId = isset($_COOKIE['intercom-id-your-intercom-id'])
3 ? $_COOKIE['intercom-id-your-intercom-id']
4 : null;

Then we store this value in our database

1$lead = Lead::create([
2 'some' => 'other',
3 'details' => 'here',
4 'lead_id' => $intercomId

The cookie ID is checked against our database to make sure they have not already become a Lead with a different email address. Doing this means that we ensure all User activity remains on a single Intercom account.

Then we use intercoms create API method which will first check whether or not they already exist. If they do not it will create them, and if they do, it will update them.

1//create if doesn't exist or update the user record on Intercom
3 'id' => $lead->lead_id
4 'custom_attributes' => [
5 'Stage' => $stage
6 ]

Later down the line, when the User signs up for an account they are auto-magically enrolled on our free plan. At this point, the user's Stage attribute gets flagged as such, and we create and associate them with an Intercom Company. The Company gets it own Stage attribute which gets set to 'Sales Qualified Lead' (SQL).

1//create or update intercom user
3 'user_id' => $user->id,
4 'email' => $user->email,
7//add the company info
9 'company_id' => $client->id,
10 'custom_attributes' => [
11 'Stage' => 'SQL',
12 ]

If and when they become a paying customer, the company Stage gets updated to 'Customer' (CUST). Although there is quite a lot of implementation involved, setting up Intercom in this way, allows us to quickly filter our users and send drip campaigns based on their current stage using Intercom's powerful segmentation capabilities.

A quick gotcha to note is that sending a message to a User immediately on signup is not possible as Intercom messages are only fired once every hour. However, it is possible to manually fire a user's pending messages using the Intercom conversations API. Below is an example of this using their excellent official PHP library:

1$this->client->get('conversations', [
2 'intercom_user_id' => $userId,
3 'type' => 'user',


So far the only compromise we have had to make is that Intercom does not capture customer activity before they become a Lead or User. This is a bit of a hassle as it means we cannot easily run complex reports such as looking at the initial referrer of every user who sends a message with Facebook Messenger or seeing which landing page resulted in the most messages sent.

Final Thoughts

Intercom is a great piece of software and the time and effort spent designing and implementing our integration is really paying off for us. Once we knew what we wanted to do, the integration was easy due to the excellent Javascript and PHP libraries and thorough documentation. The platform is incredibly flexible and allows us to always have clear picture of what is going on in our app. We can quickly and easily reach out to our customers either manually or automatically by segmenting our customers using the powerful custom attributes. We also get the added bonus of a bundled support desk which has saved us some money. I can't recommend it highly enough.

Code highlighting provided by Torchlight