Marketoとkintoneを連携してみよう

目次

caution
警告

  • セキュアコーディング ガイドライン に抵触する内容が含まれています。
    認証情報が漏洩した場合の影響を考慮して慎重に検討してください。
    JavaScriptプログラムの11行目と12行目が該当箇所です。

はじめに

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

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

完成イメージ

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

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

下準備

kintone

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

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

「フォーム」タブに移動し、Marketoのリード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

Marketoデベロッパーサイト

Marketo API Documentation | Create an API Only User Role (External link) を参考に、API専用ユーザーロールを作成してください。
ロールの権限は「APIへのアクセス」にチェックを入れてください。

次に、 Marketo API Documentation | Create an API Only User (External link) を参考に、API専用ユーザーを作成してください。

続いて、 Marketo API Documentation | Create a Custom Service for Use with ReST API (External link) を参考に、カスタムサービスを作成してください。
また、クライアントIDとクライアントシークレットをメモしてください。

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

以上で準備は完了です。

Marketo設定

MarketoWebhookを作成する

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

Marketo API Documentation | Create a Webhook (External link) を参考に、新規Webhookを作成してください。

Webhook作成画面で、それぞれ以下を設定します。

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

    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トークン

以上でMarketoWebhookの作成は完了です。

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

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

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

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

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

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

これで、Marketoから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
/*
 * kintone to marketo sample program (ES6+ & Authorization header 対応版)
 * Copyright (c) 2025 Cybozu
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */

(() => {
  'use strict';

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

  // SweetAlertで確認ダイアログを表示
  const showSwalQues = () =>
    Swal.fire({
      title: 'Marketoリードの情報を更新しますか?',
      icon: 'warning',
      showCancelButton: true,
      cancelButtonText: 'いいえ',
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'はい',
    });

  // MarketoのAuthTokenを取得
  const getAuthToken = async () => {
    const url = `${IdentityURL}/oauth/token?grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}`;
    const [body] = await kintone.proxy(url, 'GET', {}, {});
    return JSON.parse(body).access_token;
  };

  // 更新ボタンを作成
  const createPutButton = () => {
    const button = new Kuc.Button({
      text: 'Marketoのリードを更新する',
      type: 'normal',
    });
    kintone.app.record.getHeaderMenuSpaceElement().appendChild(button);
    return button;
  };

  // Marketoにリードを送信
  const putLeads = async (record, token) => {
    const [first, last] = record.contactName.value.split(' ');
    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`;
    const headers = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    };

    const [res] = await kintone.proxy(url, 'POST', headers, JSON.stringify(body));
    return JSON.parse(res);
  };

  // 更新ボタン押下時の処理
  const buttonAction = (button, record) => {
    button.addEventListener('click', async () => {
      let spinner;

      try {
        const result = await showSwalQues();
        if (result.isDismissed) throw new Error('キャンセルされました');

        spinner = new Kuc.Spinner();
        kintone.app.record.getHeaderMenuSpaceElement().appendChild(spinner);

        const token = await getAuthToken();
        await putLeads(record, token);

        spinner.remove();
        await Swal.fire('リードを更新しました。');
        location.reload();
      } catch (err) {
        if (spinner) spinner.remove();
        console.error(err);
      }
    });
  };

  // レコード詳細画面でボタンを表示
  kintone.events.on('app.record.detail.show', (event) => {
    const record = event.record;
    const putButton = createPutButton();
    buttonAction(putButton, record);
    return event;
  });
})();

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

本来11行目と12行目に記述する認証情報は、プラグイン化するなど、情報を秘匿する必要があります。
参考: kintoneプラグインのメリット

JavaScript / CSSカスタマイズ設定

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

kintone UI Component

Marketoリード更新ボタンとスピナーの表示にkintone UI Componentを使用しています。
kintone-labs/kintone-ui-componentのReleases (External link) より最新バージョンをダウンロードして解凍し、jsファイルをアプリに適用します。
使用方法は kintone UI Component v1 の記事を確認してください。

Cybozu CDN

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

  • https://js.cybozu.com/sweetalert2/v11.19.1/sweetalert2.min.js
  • https://js.cybozu.com/sweetalert2/v11.19.1/sweetalert2.min.css

動作確認

Marketo新規顧客作成 → kintoneレコード追加

kintoneレコード詳細画面から更新ボタン → Marketoリード更新

また、Marketo側で作成したスマートキャンペーンから「実行結果」を確認できます。

サンプルコード解説

showSwalQues

16
17
18
19
20
21
22
23
24
25
26
// SweetAlertで確認ダイアログを表示
const showSwalQues = () =>
  Swal.fire({
    title: 'Marketoリードの情報を更新しますか?',
    icon: 'warning',
    showCancelButton: true,
    cancelButtonText: 'いいえ',
    confirmButtonColor: '#3085d6',
    cancelButtonColor: '#d33',
    confirmButtonText: 'はい',
  });

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

getAuthToken

28
29
30
31
32
33
// MarketoのAuthTokenを取得
const getAuthToken = async () => {
  const url = `${IdentityURL}/oauth/token?grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}`;
  const [body] = await kintone.proxy(url, 'GET', {}, {});
  return JSON.parse(body).access_token;
};

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

createPutButton

35
36
37
38
39
40
41
42
43
// 更新ボタンを作成
const createPutButton = () => {
  const button = new Kuc.Button({
    text: 'Marketoのリードを更新する',
    type: 'normal',
  });
  kintone.app.record.getHeaderMenuSpaceElement().appendChild(button);
  return button;
};

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

putLeads

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
// Marketoにリードを送信
const putLeads = async (record, token) => {
  const [first, last] = record.contactName.value.split(' ');
  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`;
  const headers = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  };

  const [res] = await kintone.proxy(url, 'POST', headers, JSON.stringify(body));
  return JSON.parse(res);
};

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

information

access_tokenクエリパラメーターを利用したAPI認証方式は非推奨(廃止予定)となっており、2025年10月31日以降は使用できなくなります。
すでにaccess_tokenを使ってMarketoとkintoneを連携している場合は、下記を参考に修正してください。 access_token認証方式の廃止と対応方法

buttonAction

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 更新ボタン押下時の処理
const buttonAction = (button, record) => {
  button.addEventListener('click', async () => {
    let spinner;

    try {
      const result = await showSwalQues();
      if (result.isDismissed) throw new Error('キャンセルされました');

      spinner = new Kuc.Spinner();
      kintone.app.record.getHeaderMenuSpaceElement().appendChild(spinner);

      const token = await getAuthToken();
      await putLeads(record, token);

      spinner.remove();
      await Swal.fire('リードを更新しました。');
      location.reload();
    } catch (err) {
      if (spinner) spinner.remove();
      console.error(err);
    }
  });
};

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

access_token認証方式の廃止と対応方法

MarketoのREST APIでは、これまでaccess_tokenをクエリパラメーターとしてURLに含める認証方式が利用されてきました。
しかしこの方式は非推奨(廃止予定)となっており、2025年10月31日以降は使用できなくなります。
以下の対応により、本記事で紹介しているAuthorizationヘッダーを利用する方法に修正してください。

修正のポイント

  • access_tokenクエリパラメーターを削除する。
    以下のような形式でトークンをURLに含めるのは、セキュリティ上のリスクがあり、今後はサポートされないため削除してください。
1
const url = EndpointURL + '/v1/leads.json?access_token=' + authToken;
  • Authorizationヘッダーを使った方法に変更する。
    次のように、取得したトークンをリクエストヘッダーに含める方式へ修正してください。
1
2
3
4
const headers = {
  'Content-Type': 'application/json',
  Authorization: `Bearer ${token}`,
};

この方式はセキュリティ的にも安全で、Marketoの新しい仕様にも対応しています。
詳しくは、下記を確認してください。
Marketo API Documentation | Authentication (External link)

おわりに

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

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

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

information

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