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 Template

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: Dynamic Install

Use this method if you need be able to control at which point Intercom is loaded (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, 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),
    })
  );
}