Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
  views
  state
  utils
  state
  utils
  index.js
  package.json
  README.md
Size: Mime:
  README.md

Intercom Connector

This connector provides an integration with the Intercom Javascript API. It runs a saga listening to relevant redux actions and notifies Intercom about the changes.

Installation

Add the package to your package.json:

yarn add @doodle/intercom-connector

Initial setup

Method 1: EJS

Use this method if you want Intercom to always be included and if you're running in an environment where EJS templates are supported.

  1. Include the EJS snippet before </body>

    <%- include(`${nodeModulesPath}/@doodle/intercom-connector/views/init.ejs`); %>
    

    In your view rendering, provide intercomAppId:

    res.render('index', {
      intercomAppId: process.env.INTERCOM_APP_ID,
      env: {
          // ... other env vars
          INTERCOM_APP_ID: process.env.INTERCOM_APP_ID,
      },
    

    In your webpack config:

    new webpack.DefinePlugin({
      'process.env': {
         // ... other env vars
         INTERCOM_APP_ID: 'window.__env__.INTERCOM_APP_ID',
      },
    }),
    
  2. Call the saga: client.js:

    store.runRootSaga({
      // ... other saga settings
      intercom: {
        intercomAppId: process.env.INTERCOM_APP_ID,
      },
    });
    

    In your root reducer:

    import { createReducer as createIntercomReducer } from '@doodle/intercom-connector';
    
    export default function createReducer(injectedReducers = {}) {
      return combineReducers({
        // other reducers
        ...createIntercomReducer(),
      });
    }
    

    In your root saga:

    import { loadIntercomSaga } from '@doodle/intercom-connector';
    
    export default function* rootSaga(options = {}, history) {
      yield all([
        // ... other sagas
        call(loadIntercomSaga, options.intercom),
      ]);
    }
    

    Where you want to start Intercom tracking:

    import {
      boot as bootIntercom,
      getUserDataFromState as getIntercomUserDataFromState,
    } from '@doodle/intercom-connector';
    
    function* onUserLoaded() {
      const user = yield select(state => state.user.data);
    
      yield put(bootIntercom(getUserDataFromState(user)));
    }
    
  3. Add the Intercom App ID to the environment .env:

    INTERCOM_APP_ID=abcdef
    

Method 2: DOM Injection

Use this method if you need be able to control at which point Intercom is loaded/injected (eg. after waiting for user consent).

  1. Configure the Intercom Saga:

    store.runRootSaga({
      // ... other saga settings
      intercom: {
        intercomAppId: process.env.INTERCOM_APP_ID,
      },
    });
    

    In your root reducer:

    import { createReducer as createIntercomReducer } from '@doodle/intercom-connector';
    
    export default function createReducer(injectedReducers = {}) {
      return combineReducers({
        // other reducers
        ...createIntercomReducer(),
      });
    }
    

    In your root saga:

    import { loadIntercomSaga } from '@doodle/intercom-connector';
    
    export default function* rootSaga(options = {}, history) {
      yield all([
        // ... other sagas
        call(loadIntercomSaga, options.intercom),
        call(trackingSaga, options),
      ]);
    }
    

    In the Saga where you want to interact with Intercom:

    import {
      boot as bootIntercom,
      update as updateIntercom,
      shutdown as shutdownIntercom,
      install as installIntercom,
      uninstall as uninstallIntercom,
      getUserDataFromState as getIntercomUserDataFromState,
    } from '@doodle/intercom-connector';
    
    function* onConsentChanged(options) {
      const user = yield select(state => state.user.data)
    
      if (intercomHasConsent()) {
        // Inject the Intercom script into the DOM, then start Intercom tracking
        yield put(installIntercom());
        yield put(bootIntercom(getIntercomUserDataFromState(user)));
      } else {
        yield put(shutdownIntercom());
        yield put(uninstallIntercom());
      }
    }
    
    function* watchForConsent(options, activeConsents) {
      yield takeEvery(TrackingActionTypes.CONSENT_CHANGES, onConsentChanged, options);
    }
    
    function* onUserLoaded(options) {
      const user = yield select(state => state.user.data);
    
      // Update the data associated with the current Intercom session
      yield put(updateIntercom(getIntercomUserDataFromState(user)));
    }
    
    function* watchUserLoaded() {
      yield takeLatest(UserActionTypes.USER_LOADED, onUserLoaded);
    }
    
    export default function* trackingSaga(options = {}) {
      yield all([call(watchForConsent, options), call(watchUserLoaded, options)]);
    }
    
  2. Add the Intercom App ID to the environment .env:

    INTERCOM_APP_ID=abcdef
    

Communicate with Intercom

Track events

import { trackEvent } from '@doodle/intercom-connector';
// Or: import { trackEvent } from '@doodle/intercom/state/actions';

// in your saga:
export function* onMyTrackedAction(options) {
  ...
  yield put(
    trackEvent('event.name', {
      metadata_key: 'some value'
    })
  );
}

Update user attributes

When loaded the Intercom Connector saga updates the following user attributes for tracking:

{
  user_id: '',
  user_hash: '',
  email: '',
  name: '',
  language: '',
  avatar: {
    type: '',
    image_url: '',
  },
}

This structure can also be constructed from user data state using the getIntercomUserDataFromState method.

To update any of those or track custom user ones always include both user_id and email fields in the call to the update action creator:

import { update as intercomUpdate } from '@doodle/intercom-connector';
// Or: import { update as intercomUpdate } from '@doodle/intercom-connector/state/actions';

// in your saga:
export function* onMyTrackedAction(options) {
  ...
  yield put(
    intercomUpdate({
      user_id: yield select(getUserId),
      email: yield select(getUserEmail),
      customAttr: yield select(getCustomAttr),
    })
  );
}