Intercom Destination


Intercom makes customer messaging apps for sales, marketing, and support, connected on one platform. The Intercom Destination is open-source. You can browse the code for analytics.js, iOS and Android on Github.

This document was last updated on January 18, 2019. If you notice any gaps, outdated information or simply want to leave some feedback to help us improve our documentation, please let us know!

Use Cases

Getting Started

The first step is to make sure Intercom supports the source type and connection mode you’ve chosen to implement. You can learn more about what dictates the connection modes we support here.

Web Mobile Server
📱 Device-mode
☁️ Cloud-mode
  1. From your Segment UI’s Destinations page click on “Add Destination”.
  2. Search for “Intercom” within the Destinations Catalog and confirm the Source you’d like to connect to.
  3. Authorize your Intercom account in Segment and select the Intercom Account you want to sync with Segment. You can choose which account to sync in the drop down menu in the top right. If you have opted to utilize our server-side sources, we will begin passing data through our servers once you activate the Destination. For other libraries please continue reading below.
  4. Find your “App ID” within the Intercom UI following the instructions here or by navigating to the Gear Menu and clicking on “App Settings” followed by “API Keys”. It should look something like this: 9iefb489.

Client

  1. Activate your Intercom Destination and our CDN will be updated within 45 minutes.
  2. Our snippet will then start asynchronously loading Intercom’s library.js onto your page. This means you should remove Intercom’s snippet from your page.

Mobile

IMPORTANT: Our Intercom mobile components are currently in public beta. We appreciate any feedback you have on the new components, so please let us know!

Before reading the specific instructions for iOS or Android below, please ensure you enter your Mobile API Key in the Segment Settings UI. This is required to send data to Intercom from your mobile apps.

iOS

  1. In your application, add pod 'Segment-Intercom' to your Podfile.
  2. After adding the dependency, you must import the integration 'SEGIntercomIntegrationFactory.h' and register it with the Segment SDK [configuration use:[SEGIntercomIntegrationFactory instance]];.
  3. When installing Intercom, you’ll need to make sure that you have a NSPhotoLibraryUsageDescription entry in your Info.plist. This is required by Apple for all apps that access the photo library. It is necessary when installing Intercom due to the image upload functionality. Users will be prompted for the photo library permission only when they tap the image upload button.

Android

  1. Add compile 'com.segment.analytics.android.integrations:intercom:+' to your app-level build.gradle file
  2. Sync your project, then import the integration in your Application subclass or wherever you’re initializing Segment:
     import com.segment.analytics.android.integrations.intercom.IntercomIntegration;
    
  3. Next, remember to register the IntercomIntegration.FACTORY with the Segment SDK:

     analytics = new Analytics.Builder(this, "write_key")
       .use(IntercomIntegration.FACTORY)
       .build();
    

Page

If you haven’t had a chance to review our spec, please take a look to understand what the Page method does. An example call would look like:

analytics.page();

The Page call only works client-side through Analytics.js by triggering the Intercom update method, which will look for new Intercom messages that should be displayed to the current user. It is not supported by any of our server-side or mobile SDKs.

Intercom Respond

If you have Intercom’s Respond package, calling page will trigger the chat widget to appear. Otherwise, you would need to use the Identify method to make the chat widget appear.

If you have the Respond package and calling page still does not show your chat widget, be sure to check your “Visitors on your website” setting inside your Intercom account.

Identify

If you haven’t had a chance to review our spec, please take a look to understand what the Identify method does. An example call would look like:

analytics.identify('su3r73', {
  name: 'Iñigo Montoya',
  email: 'avenger@gmail.com',
  company: {
    id: '123',
    name: 'Iñigo & Friends Holding Company'
  },
  createdAt: 'Mon Mar 26 2018 17:44:51 GMT+0000 (UTC)'
});

When you call Identify, we create or update a user in Intercom using their Users API. We currently do not support creation of leads.

Note: Intercom only associates Track events with known users, an Identify call with a userId is required before Track events will be associated properly. Our bundled mobile SDK’s also require that identify be called prior to track, but accepts setting an unknown user in Intercom via the anonymousId.

Keep reading for more information about the Identify call depending on the source type you send it from.

Client

  • Passing traits.company will create a new Intercom Company if the company_id does not match a known company.(https://developers.intercom.io/reference#user-model).
  • Trait values must be no longer than 255 characters

When you call Identify on analytics.js, we create the intercomSettings object and load Intercom’s Javascript into the page.

Here’s how Segment parameters are mapped to those in the intercomSettings object:

Segment Parameter Intercom Parameter Description
userId intercomSettings.user_id The user ID for this user.
traits intercomSettings.custom_attributes The traits associated for this user.
traits.email intercomSettings.email The email of this user.
traits.name intercomSettings.name The full name of this user.
traits.company intercomSettings.company The company associated for this user.
traits.createdAt intercomSettings.created_at The UNIX timestamp when the user was created.

NOTE: Intercom does not accept trait values longer than 255 characters.

If a user with traits.company is identified and the company_id does not match a known company, a new company will be created in Intercom. If company is a string, we will set the company_id as a hash of company_name as an id is required to associate the user to the company. The group call may be used to create/update company profiles explicitly.

Server

When you call Identify from any of the server-side libraries or mobile sources in Cloud-mode we’ll map our special traits (email, firstName, lastName, createdAt, and company) to Intercom special properties.

If you want to use Intercom’s last_request_at, you’ll need to pass in active: true in the context object. Then, by default we will set last_request_at to the current time; however, if you pass in your own timestamp, pass it in as lastRequestAt (in camelCase), and we’ll set last_request_at to that value in our server-side sources.

If you want to include last_seen_user_agent then include it in the context.userAgent. Similarly with last_seen_ip which is used for geolocation, you can include the IP address at context.ip. Click here for an example.

Mobile

Intercom supports both logged-in or logged-out users. You will need to register your users with Intercom before you can talk to them or see what they do in your app. This means that identify must be called before track.

Intercom allows users to choose to track only known or only unknown users, as well as both. Segment will support the ability to track both by checking for logged in users (determined by the userId) and falling back to setting the user as “Unidentified” if this is not present.

Intercom knows when your app is backgrounded and comes alive again, so you won’t need to re-register your users.

Segment maps the following Intercom standard attributes on identify.

Segment Parameter Intercom Parameter Description
traits.userId user_id The user ID for this user.
traits.email email The email of this user.
traits.name name The full name of this user.
traits.phone phone The phone number for this user.
traits.company company The company associated for this user.
traits.signedUpAt created_at The signed up date as an NSDate (iOS) & Long (Android)
integrations.intercom.language_override languageOverride The language override code for this user.
integrations.intercom.unsubscribed unsubscribedFromEmails A boolean indicating if the user has unsubscribed from emails.
remaining traits customAttributes Custom attributes for this user.

Note: Intercom only supports values of type NSString, NSNumber or NSNull on iOS and String, Long, Float, Double, Boolean, Character, Byte, Short or Integer on Android. In addition, Android traits should be passed using camelCase to conform with Java convention.

Collect Context

With this option selected, identify calls will include contextual information collected by Segment’s mobile libraries if it is available. This info will be set as Custom Attributes on the Intercom user.

The fields collected from the context object are device.type, device.manufacturer, device.model, os.name, os.version, app.name, app.version and will populate in Intercom as device_type, device_manufacturer, device_model, os_name, os_version, app_name and app_version.

Track

If you haven’t had a chance to review our spec, please take a look to understand what the Track method does. An example call would look like:

analytics.track('Product Purchased', {
    order_ID: '2969302398',
    category: 'boots',
    product_name: 'yellow_cowboy_boots',
    price: 99.95,
    currency: 'EUR'
});

Note: Because Intercom only associates Track events with known users, an Identify call with a userId is required before Track events will be associated properly.

When you call track from any of the server-side libraries or mobile sources in cloud-mode (i.e. without our beta Segment mobile Intercom SDK installed), you will need to include either the userId or email of an existing user within Intercom.

Revenue and currency

If you send properties.revenue and properties.currency, we will format that according to Intercom’s Monetary Amount and send it as:

price: {
  amount: <properties.revenue> * 100, // since Intercom requires this in cents
  currency: <properties.currency> // will default to 'usd'
}

Our bundled mobile integrations will also check properties.total if properties.revenue is not present, and assign the total value as the amount value.

Limited Properties

Intercom can only store 5 event properties per event. That means if you send an event to Segment with more than 5 properties, Intercom will only show the first 5 properties.

Limited Events

Intercom only allows a total of 120 unique active event names. If you are sending Segment more than 120 unique event names, Intercom only accepts the first 120 events that their servers see, and the rest throw an error. In Intercom, an “Active” event is one which has not been archived. If you archive an event, it makes it inactive and removes it from your 120 active events. If you need to bring your account back under the 120 event limit, archive some events from in the Intercom UI by navigating to **Settings > data > Events**, then click on the event to archive.

Server-side Race Condition

Because our server-side libraries batch calls by default, it is possible for an identify call that would create a user record to arrive at the same time as a track event associated with this user. If the track event is processed before the user is created you get an error, and the event is not recorded.

Adding a Flush method immediately following the identify, and before any additional track events helps ensure that the identify call reaches Intercom first to create the user. Generally, this is enough to prevent the race condition, but you can add an extra timeout if necessary.

If you still see issues, the identify call is most likely either either not reaching Intercom at all, or is arriving too late after a subsequent retry. In cases like this you can use our Event Delivery functionality to check for recent errors, and get some insight into how to prevent errors in the future.

Group

If you haven’t had a chance to review our spec, please take a look to understand what the Group method does. An example call would look like:

analytics.group('companyId123', {
  name: 'Segment'
});

Segment supports Intercom companies in all of our sources. Users can be put into multiple groups, which will associate them to multiple companies in Intercom.

When you call Group from any of our server-side libraries or mobile sources in cloud-mode (i.e. without our beta Segment mobile Intercom SDK installed), you will need to include either the userId or email of an existing user within Intercom.

Note: In order for the Company Sessions Count to update within Intercom, the company must first be recorded in an identify call.

Segment Parameter Intercom Parameter Description
groupId companyId The ID for the company.
traits.name name The name of the company.
traits.plan plan The plan of the company.
traits.monthly_spend monthlySpend The monthly spend of the company.
traits.company intercomSettings.company The company associated for this user.
traits.createdAt intercomSettings.created_at The UNIX timestamp when the user was created.
remaining traits customAttributes Custom attributes for this user.

Note: Intercom only supports values of type NSString, NSNumber or NSNull on iOS and String, Long, Float, Double, Boolean, Character, Byte, Short or Integer on Android. In addition, Android traits should be passed using camelCase to conform with Java convention.

Reset

Segment supports Intercom’s reset method only for Device-mode Mobile sources. The bundled mobile SDK’s reset method unregisters a user in Intercom. When users want to log out of your app and you call Segment’s reset method, Segment will call:

On iOS:

  [Intercom reset];

On Android:

  Analytics.with(context).reset();

Best Practices

Arrays and Objects

Intercom does not support custom arrays or objects. Per Intercom’s request, we removed support for this feature starting Aug 21st, 2017. This means that if you want a certain user trait or event property to be sent to Intercom, you must send them at the top level.

This limitation does not apply, however, for mapping company objects on identify calls. We will continue to handle that in the same way as before. This is only applicable for any custom traits or properties.

Disassociating Users from a Company (server-side only)

You can disassociate a user from a company by passing in a field inside the company trait with remove: true in your identify calls.

analytics.identify({
  userId: '019mr8mf4r',
  traits: {
    name: 'Michael Bolton',
    email: 'mbolton@initech.com',
    plan: 'Enterprise',
    company: {
      id: 12345,
      remove: true
    },
    createdAt: 'Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)'
  }
});

Identity Verification

Intercom’s identity verification helps to make sure that conversations between you and your users are kept private and that one user can’t impersonate another. Segment supports identity verification through our analytics.js web library and our iOS and Android mobile sources.

For mobile apps, before enabling identity verification, please read Intercom’s docs on identity verification for iOS and Android.

If you want to enable Intercom identity verification for analytics.js or our bundled mobile SDKs, you can pass in the user_hash variable inside the integrations object.

The user_hash should be a SHA256 hash of your Intercom API secret and the userId. The hash is not based on the email, it’s based on the userId. Here’s an example rendering an identify call with identity verification:

analytics.identify('<%= current_user.id %>', {
    email: '<%= current_user.email %>',
    createdAt: '<%= current_user.created %>'
}, {
     Intercom: {
        user_hash: '<%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_INTERCOM_APP_SECRET", current_user.id) %>'
     }
});

Android example:

Traits traits = new Traits();
Map<String, Object> intercomOptions = new HashMap<>();
intercomOptions.put("userHash", "YOUR_USER_HASH");
Options options = new Options().setIntegrationOptions("Intercom", intercomOptions);
Analytics.with(context).identify("123", traits, options);

YOUR_INTERCOM_APP_SECRET is found in Intercom’s identity verification setup guide.

Identity verification plus filtering via Destinations Object

If using Intercom identity verification AND selective destinations functionality, the context object will look like this:

{
     integrations: {
         All: false,
         Intercom: {
            user_hash: '<%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_INTERCOM_APP_SECRET", current_user.id) %>'
         }
     }
}

Unsubscribe Users

To unsubscribe users from emails, you may set a flag from server side libraries, unsubscribedFromEmails, inside context object:

node.js example:

analytics.identify({
  userId: '4832094283057439285723523452345',
  anonymousId:'43254364571',
  context:{
    Intercom: { unsubscribedFromEmails: true }
  },
  traits: {
    firstName: 'John ',
    lastName: 'Jacob',
    email: 'jingleheimer@schmidt.com'
  }
});

objective-c example:

options:@{
  @"integrations": @{
   @"intercom" : @{
     @"unsubscribed": @YES
    }
  }
}

Android example:

Traits traits = new Traits();
Map<String, Object> intercomOptions = new HashMap<>();
intercomOptions.put("unsubscribedFromEmails", true);
Options options = new Options().setIntegrationOptions("Intercom", intercomOptions);
Analytics.with(context).identify("123", traits, options);

Note: This will only work from server side libraries and bundled mobile. NOT analytics.js.

Last Seen

By default Intercom updates the Last Seen user trait whenever a user’s profile is updated by identify calls, or if a group call is sent with a user’s userId. If you want to update a user without updating their Last Seen time, pass active with a value of false into the context (see example below) of your identify or group calls.

Note that this only works server-side; Last Seen will always be updated client-side. Please note that id or name are necessary to update company.

Here’s a full python example of an identify call with active set to false:

analytics.identify(user_id='some_user_id', traits={
    "email": "ben@intercom.io",
    "firstName": "Ben",
    "lastName": "McRedmond"
    "createdAt": 1363902294011,
    "plan": "Premium"
}, context={
    "ip": "192.168.0.1",
    "active": False,
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.47 Safari/537.36"
})

Intercom Tags

Our API doesn’t support Intercom tags. Traits can be used instead of tags to create segments of users, and the advantage is you can use those traits in other destinations like Segment.

Conditionally show the Intercom chat widget (Browser only)

You can take advantage of Intercom’s hide_default_launcher option to selectively show the chat widget. According to Intercom’s docs, you want to first hide the Messenger for all users inside their UI via Messenger settings. Then think about how you want to programmatically decide which users you’d like to show the widget to. Then you can pass an Intercom specific destination setting like this:

// with analytics.js
analytics.identify('teemo', { someTrait: 'x'}, {
  Intercom: { hideDefaultLauncher: true }
});

Note: You can pass in the Intercom specific option via all supported calls for this destination (page, identify, and group)!

Control the Intercom Chat Widget (Mobile only)

Our mobile SDKs give you the ability to tap into the Intercom instance our integration creates so that you can call any of Intercom’s native’ methods on it. This includes all methods required to interact with the Intercom chat widget.

Here’s an example of how to grab the underlying Intercom instance.

On Android:

analytics.onIntegrationReady("Intercom", new Callback() {
  @Override public void onReady(Object instance) {
    Intercom intercom = (Intercom) instance;
  }
});
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(integrationDidStart:) name:SEGAnalyticsIntegrationDidStart object:nil];

- (void)integrationDidStart:(nonnull NSNotification *)notification
{
    NSString *integration = notification.object;

    if ([integration.name isEqualToString:@"Intercom"]) {
        // Call Intercom library methods here.
    }
}

You can read more about tapping into destination-specific methods on Android here and on iOS here.

Push notification and deep linking

Our mobile SDKs do not support push notifications and deep linking out of the box. Refer to the Intercom documentation here and here for more information on setting up push notifications and deep linking on iOS and here and here for more information on these features on Android. Note our Android SDK bundles Intercom’s Firebase push notification dependency, and cannot support Google Cloud Messaging push notifications at this time.

Troubleshooting

I’m seeing a 403 Forbidden error

You probably have Intercom’s identity verification setting turned on but are not passing the user_hash correctly or at all.

You may also have to whitelist your domain in Intercom’s dashboard. Otherwise, events on non-whitelisted pages may be rejected with a 403 error.

My Intercom Widget doesn’t show up

Make sure you are sending a page and identify call when the page is loaded. This allows Intercom to register the page and the user, which would enable the widget to appear.

If you are sending those two calls, then check that the CSS selector for the widget is correct. The default is #IntercomDefaultWidget, but if you customize your widget, then be sure to update this field accordingly.

My client-side and server-side calls are going to one Segment source, but different Intercom projects

Server-side calls go the the project selected when you authenticated your Intercom account while setting up the destination. Client-side calls go to the project referenced with the App ID setting. Make sure those projects are the same.

I’m seeing a Cannot have more than 120 active event names error

Intercom only allows a total of 120 unique event names. That means if you are sending Segment more than 120 unique event names, Intercom will only accept the first 120 events that hit their servers and the rest will throw an error.

If you want to prevent some of your events from being passed to Intercom and thus prevent the error, you can filter out Intercom in those events using the Selecting Destinations feature available on all of our libraries.

Personas

You can send computed traits and audiences generated through Segment Personas to this destination as a user property. To learn more about Personas, reach out for a demo.

For user-property destinations, an identify call will be sent to the destination for each user being added and removed. The property name will be the snake_cased version of the audience name you provide with a true/false value. For example, when a user first completes an order in the last 30 days, we will send an identify call with the property order_completed_last_30days: true, and when this user no longer satisfies we will set that value to false.

When the audience is first created an identify call is sent for every user in the audience. Subsequent syncs will only send updates for those users which were added or removed since the last sync.

Personas

You can send computed traits and audiences generated through Segment Personas to this destination as a user property. To learn more about Personas, reach out for a demo.

For user-property destinations, an identify call will be sent to the destination for each user being added and removed. The property name will be the snake_cased version of the audience name you provide with a true/false value. For example, when a user first completes an order in the last 30 days, we will send an identify call with the property order_completed_last_30days: true, and when this user no longer satisfies we will set that value to false.

When the audience is first created an identify call is sent for every user in the audience. Subsequent syncs will only send updates for those users which were added or removed since the last sync.

Settings

Segment lets you change these destination settings from your Segment dashboard without having to touch any code.

Custom Inbox Button Selector

By default, Intercom will inject their own inbox button onto the page, but you can choose to use your own custom button instead by providing a CSS selector like: #my-button. Note: you must have enabled the Show the Intercom Inbox setting for this to work. The default value is #IntercomDefaultWidget

Enter your API Key

Note: this is deprecated . Intercom requires events hitting their server-side api authenticated via OAuth.

App ID (required for analytics.js and mobile)

Note: this is required to send data to Intercom from your browser or mobile app. You can find your App ID after activating your account under the Gear Menu > App Settings > API Keys at Intercom.io. It should look something like this: 9iefb489.

Include Context with Identify Calls

Pass context data with Identify calls as Custom Attributes. Includes device.type, device.manufacturer, device.model, os.name, os.version, app.name, app.version

isBulkAPIEnabled

Enter your Mobile API Key

Note: this is required to send data to Intercom from your mobile apps.

OAuth

Intercom uses an OAuth-like interface for reading/writing to their system. This option stores the various values that are needed by Intercom to validate requests (replaces API keys), and the user-specific values for UI display (e.g. user’s email, avatar, list of accounts, etc.). These fields are unique to Intercom, and are cleared out en masse when disconnecting (revoking authorization).

To use Intercom’s Rich Link object, list the name of the exact Segment property name and make sure the value of those properties only include url and value keys.

Get started with Segment

Segment is the easiest way to integrate your websites & mobile apps data to over 300 analytics and growth tools.
or
Create free account