マルケトと kintone を連携してみよう

目次

caution
警告

はじめに

標準機能だけを使用して kintone を MA ツールとして用いることは難しいです。
そこで今回は、強力な MA ツールの「マルケト」と連携する方法を紹介します。

マルケトの詳細は、公式サイトを確認してください。
MA(マーケティングオートメーション)の市場リーダー | Adobe Marketo Engage (External link)

完成イメージ

今回のシナリオでは上図の 2 と 4 の連携部分にあたるカスタマイズ方法を紹介します。

連携では、マルケトに新規顧客が登録されたことをトリガーとして、kintone へレコードを追加します。
また、kintone からマルケトのリード更新は、kintone アプリ詳細画面に設置したボタンから行います。

下準備

kintone

kintone アプリストアから「案件管理」のアプリを作成してください。
アプリの詳細をクリックして「サンプルデータを含める」のチェックを外してください。

右側の歯車アイコンから設定画面に進み、「設定 > API トークン」で API トークンを作成してください。
権限は「レコード追加」の権限が付与してあれば大丈夫です。
生成した API トークンはのちほど利用するので、メモしてください。

「フォーム」タブに移動し、マルケトのリード ID を保存するフィールドを追加します。
フィールドは「数値フィールド」フィールドコードは「leadID」で設定します。
また、ユニークなキーとなるため、「値の重複を禁止する」にチェックを入れます。
設置したフィールドの右上の歯車アイコンから変更できます。

さらに、既存フィールドのフィールドコードも変更します。
下表のとおりに変更してください。

フィールド名 フィールドコード
会社名 companyName
部署名 division
先方担当者 contactName
TEL tel
FAX fax
メールアドレス mail
確度 accuracy

最後に kintone のアプリ ID を確認します。
設定が完了したら、「アプリを公開」(または「アプリを更新」)をクリックしてください。

先ほど作成した kintone アプリを開き URL を確認してください。
URL の https://sample.cybozu.com/k/APP_ID/ の「APP_ID」がアプリ ID なのでメモしてください。

マルケト

マルケトデベロッパーサイト

Marketo API Documentation | Getting Started (External link) を参考に、マルケトの REST API 用のユーザーを追加してください。
ロールの権限は「API へのアクセス」にチェックを入れてください。

次に、LanchPoint を作成し、クライアント ID とクライアントシークレットをメモしてください。

最後にマルケト管理画面で Endpoint と Identity(ID)を確認する必要があります。
下記リンクと画像を参考に確認し、メモしてください。

Market Documentation | Authentication (External link)

以上で準備は完了です。

マルケト設定

マルケト Webhook を作成する

まず、マルケトから kintone にデータを登録するための Webhook を作成します。

下図のとおり、マルケトの管理画面から Webhook の設定画面に遷移し、新規 Webhook を作成してください。

次に、下図のような Webhook 作成画面が開きます。
それぞれ以下を設定します。

  • URL:自身の環境に合わせて以下を設定します。

    1
    
    https://sample.cybozu.com/k/v1/record.json
  • リクエストタイプ:POST

  • テンプレート:後述の JSON サンプル を元に、app の値だけ先ほど作成した kintone のアプリ ID に変更して貼り付けてください。

  • リクエストトークンのエンコード:JSON

  • 応答タイプ:JSON

JSON サンプル
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
    "app": xx,
    "record": {
        "companyName": {
            "value": {{company.Company Name}}
        },
        "division": {
            "value": {{lead.Job Title}}
        },
        "contactName": {
            "value": {{lead.Full Name}}
        },
        "mail": {
            "value": {{lead.Email Address}}
        },
        "tel": {
            "value": {{lead.Phone Number}}
        },
        "fax": {
            "value": {{lead.Fax Number}}
        },
        "leadID": {
            "value": {{Lead.id}}
        },
        "accuracy": {
            "value": {{lead.Lead Status:default=C}}
        }
    }
}

次にカスタムヘッダーを設定します。

それぞれ以下を設定します。

  • Content-Type:application/json
  • X-Cybozu-API-Token:先ほど作成した kintone アプリの API トークン

以上でマルケト Webhook の作成は完了です。

新規顧客が作成されたとき Webhook が動くようにする

先ほど作成した Webhook を、新規顧客が作成されたら動くようにします。

マルケト画面左上のアイコンをクリックし、「マーケティング活動」から、Webhook を実行させたいワークスペースを選択し、新規スマートキャンペーンを作成します。
フォルダーや名前は任意に設定してください。

スマートキャンペーンを作成したら、スマートリストから「顧客を作成」のトリガーを選択します。

次にフローで「ウェブフックを呼び出し」を選択し、ドロップダウンから先ほど作成した Webhook を選択します。

最後にスケジュールから有効化をクリックして設定は完了です。

これで、マルケトから kintone へのデータの設定が完了しました。

kintone 設定

サンプルコード

次のサンプルコードを js ファイルとして保存してください。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * kintone to marketo sample program
 * Copyright (c) 2018 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
*/

(function(swal) {
  'use strict';

  const clientId = 'MARKETO_CLIENT_ID';
  const clientSecret = 'MARKETO_CLIENT_SECRET';
  const IdentityURL = 'MARKETO_IDENTITY_URL';
  const EndpointURL = 'MARKETO_ENDPOINT_URL';

  // リード送信時のsweetalert
  function showSwalQues() {
    return swal({
      title: 'マルケトリードの情報を更新しますか?',
      type: 'warning',
      showCancelButton: true,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'はい',
      cancelButtonText: 'いいえ'
    });
  }

  // マルケトのAuthTokenを取得する
  function getAuthToken() {
    const url = IdentityURL + '/oauth/token?' +
            'grant_type=client_credentials&client_id=' + clientId +
            '&client_secret=' + clientSecret;

    return kintone.proxy(url, 'GET', {}, {})
      .then((resp) => {
        const obj = JSON.parse(resp[0]);
        return obj;
      });
  }

  // 更新ボタン作成関数
  function createPutButton() {
    const button = new kintoneUIComponent.Button({
      text: 'マルケトのリードを更新する',
      type: 'normal'
    });
    kintone.app.record.getHeaderMenuSpaceElement().appendChild(button.render());
    return button;
  }

  // マルケトにリードを送信する
  function putLeads(record, authToken) {
    const name = record.contactName.value.split(' ');
    const first = name[0];
    const last = name[1];
    const body = {
      action: 'updateOnly',
      lookupField: 'id',
      input: [{
        id: record.leadID.value,
        firstName: first,
        lastName: last,
        title: record.division.value,
        company: record.companyName.value,
        email: record.mail.value,
        phone: record.tel.value,
        fax: record.fax.value,
        leadStatus: record.accuracy.value,
      }]
    };
    const url = EndpointURL + '/v1/leads.json?access_token=' + authToken;
    kintone.proxy(url, 'POST', {'Content-Type': 'application/json'}, body)
      .then((resp) => {
        console.log(resp);
      }).catch((err) => {
        console.log(err);
      });
  }

  // 更新ボタンを押したときに動く
  function buttonAction(button, record) {
    const spinner = new kintoneUIComponent.Spinner();
    kintone.app.record.getHeaderMenuSpaceElement().appendChild(spinner.render());
    button.on('click', (e) => {
      return showSwalQues().then((resp) => {
        if (resp.dismiss === 'cancel') {
          throw new Error();
        }
        spinner.show();
        return getAuthToken();
      }).then((authResp) => {
        return putLeads(record, authResp.access_token);
      }).then((resp) => {
        spinner.hide();
        return swal('リードを更新しました。');
      }).then((r) => {
        location.reload();
      }).catch((err) => {
        console.log(err);
      });
    });
  }

  kintone.events.on('app.record.detail.show', (event) => {
    const record = event.record;
    const putButton = createPutButton();
    buttonAction(putButton, record);
    return event;
  });

})(swal);

12〜15 行目は下準備でメモした情報を記入してください。

本来 12 行目と 13 行目に記述する認証情報は、プラグイン化するなど、情報を秘匿する必要があります。
参考: kintoneプラグイン開発入門 【Part1: メリット編】

JavaScript / CSSカスタマイズ設定

アプリの設定 > 設定タブ > JavaScript / CSS でカスタマイズの順に遷移し、下図のとおり設定します。
「connect-to-Marketo.js」は先ほど作成したサンプルコードです。

kintone UI Component

マルケトリード更新ボタンとスピナーの表示に kintone UI Component を使用しています。
kintone-labs/kintone-ui-component の Releases (External link) より v0.1 で始まる最新バージョンをダウンロードして解凍し、js ファイルと css ファイルをアプリに適用します。
使用方法は 「kintone UI Component v0」を使って簡単に kintone ライクな UI を設置する の記事を確認してください。

Cybozu CDN

URL 指定で Cybozu CDN の SweetAlert2 を使用しています。

  • https://js.cybozu.com/sweetalert2/v7.28.2/sweetalert2.min.js
  • https://js.cybozu.com/sweetalert2/v7.28.2/sweetalert2.min.css

動作確認

マルケト新規顧客作成 → kintone レコード追加

kintone レコード詳細画面から更新ボタン → マルケトリード更新

サンプルコード解説

showSwalQues

16
17
18
19
20
21
22
23
24
25
26
27
// リード送信時のsweetalert
function showSwalQues() {
  return swal({
    title: 'マルケトリードの情報を更新しますか?',
    type: 'warning',
    showCancelButton: true,
    confirmButtonColor: '#3085d6',
    cancelButtonColor: '#d33',
    confirmButtonText: 'はい',
    cancelButtonText: 'いいえ'
  });
}

SweetAlert2 (External link) を使用してボタン押下時のアラートを作成しています。

getAuthToken

29
30
31
32
33
34
35
36
37
38
39
40
// マルケトのAuthTokenを取得する
function getAuthToken() {
  const url = IdentityURL + '/oauth/token?' +
        'grant_type=client_credentials&client_id=' + clientId +
        '&client_secret=' + clientSecret;

  return kintone.proxy(url, 'GET', {}, {})
    .then((resp) => {
      const obj = JSON.parse(resp[0]);
      return obj;
    });
}

外部の API を実行する API を使用して マルケトの認証トークンを取得する API (External link) を実行しています。

createPutButton

42
43
44
45
46
47
48
49
50
// 更新ボタン作成関数
function createPutButton() {
  const button = new kintoneUIComponent.Button({
    text: 'マルケトのリードを更新する',
    type: 'normal'
  });
  kintone.app.record.getHeaderMenuSpaceElement().appendChild(button.render());
  return button;
}

kintone UI Component の ボタンに関する関数 (External link) を使用してボタンを作成しています。

putLeads

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// マルケトにリードを送信する
function putLeads(record, authToken) {
  const name = record.contactName.value.split(' ');
  const first = name[0];
  const last = name[1];
  const body = {
    action: 'updateOnly',
    lookupField: 'id',
    input: [{
      id: record.leadID.value,
      firstName: first,
      lastName: last,
      title: record.division.value,
      company: record.companyName.value,
      email: record.mail.value,
      phone: record.tel.value,
      fax: record.fax.value,
      leadStatus: record.accuracy.value,
    }]
  };
  const url = EndpointURL + '/v1/leads.json?access_token=' + authToken;
  kintone.proxy(url, 'POST', {'Content-Type': 'application/json'}, body)
    .then((resp) => {
      console.log(resp);
    }).catch((err) => {
      console.log(err);
    });
}

外部の API を実行する API を使用して マルケトのリードを更新する API (External link) を実行しています。
マルケトの REST API は POST メソッドで作成と更新を実施する Upsert API なので、更新時も POST メソッドを使用します。
詳細はドキュメントを確認してください。

buttonAction

 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
// 更新ボタンを押したときに動く
function buttonAction(button, record) {
  const spinner = new kintoneUIComponent.Spinner();
  kintone.app.record.getHeaderMenuSpaceElement().appendChild(spinner.render());
  button.on('click', (e) => {
    return showSwalQues().then((resp) => {
      if (resp.dismiss === 'cancel') {
        throw new Error();
      }
      spinner.show();
      return getAuthToken();
    }).then((authResp) => {
      return putleads(record, authResp.access_token);
    }).then((resp) => {
      spinner.hide();
      return swal('リードを更新しました。');
    }).then((r) => {
      location.reload();
    }).catch((err) => {
      console.log(err);
    });
  });
}

ボタン押下時のアクションを設定しています。
マルケトのリード更新処理が終了するまで、kintone UI Component の スピナー (External link) を表示しています。

おわりに

いかがでしょうか。
kintone とマルケトの相互連携が実現できたと思います。
他にも以下のカスタマイズが実装できそうですね。

  • kintone アプリのステータス変更時にマルケトリードを更新する。
  • kintone レコードの値が変更されたときマルケトリードを更新する。
  • kintone レコード詳細画面にリアルタイムでマルケトリードスコアを表示する。

マルケトの REST API はリード情報を操作する API だけではなく豊富に用意されているのでさまざまなことが可能そうです。
詳細は次のマルケトデベロッパーサイトを確認してください。
Marketo Documentation (External link)

information

この Tips は、2018 年 10 月版 kintone で動作を確認しています。