Tableau Desktop からMarketoのカスタムオブジェクトの情報を利用する

# Marketoのカスタムオブジェクトとは

マーケティングオートメーションのクラウドサービス[Marketo](https://jp.marketo.com/)では、既にビルドインで準備されているマーケティングに必要なデータベースに対して、自社で使用している固有の情報をカスタムオブジェクトとして追加することが出来ます。

Marketoのカスタムオブジェクトに関する[Marketo社のマニュアルはこちら](https://docs.marketo.com/pages/releaseview.action?pageId=11374515)をご覧ください。Marketoのカスタムオブジェクトは、通常、Marketoの標準オブジェクトに、紐つけて利用することを想定しています。Marketo社のマニュアル「[Marketoカスタムオブジェクトを理解する](https://docs.marketo.com/pages/releaseview.action?pageId=11374520)」では以下のように説明されています。

>カスタムオブジェクトは、1対多または多対多の関係で設定できます。たとえば、次のような使い方があります。
>
>1対多：1人の人が複数の自動車を所有している
>多対多：複数の学生がコースカタログの複数のコースに登録する
>1対多の構造では、1つのリンクフィールドを使用してカスタムオブジェクトを人または会社に結び付けます。

つまり、リード情報に自社の固有の情報をカスタムオブジェクトで保有する、という事は、「リード：カスタムオブジェクト」は、「1対多」の関係で設定して、リンクフィールドで紐つけします。
以下、Marketoの管理画面でカスタムオブジェクトのフィールド定義です。この例ではlinkidのタイプが「リンク」となっており、リード情報のIdと紐ついています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/ddbcc1d8-0df9-e80f-e474-f6d9d49d8123.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/c37982cf-ec9f-cc68-86a8-00ead08cea52.png)


この設定により、リードの詳細画面にてカスタムオブジェクトのタブからデータを確認することが出来ます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/226d2907-c4a8-f823-6e98-f08a14f05fcf.png)

# Tableau Desktop標準のMarketoコネクターについて

Tableau Desktopでは、標準でMarketo向けてのコネクターが搭載されています。これにより、Marketo内のリードやアクティビティなど標準オブジェクトのデータを可視化することが出来ます。しかし、Marketoのカスタムオブジェクトはサポートしていないため、テーブルとしてデータを取得する事が出来ません。

# CData ODBC Driver for Marketo の利用

CData ODBC Driver for Marketoは、TableauなどODBC接続が可能なツールからMarketoのデータにアクセス出来るデータドライバー製品です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/b6aaef5e-b0c1-17e7-1724-b03d43da69b4.png)

（製品ページ）　https://www.cdata.com/jp/drivers/marketo/odbc/

本製品では、Marketoのカスタムオブジェクトへのアクセスも可能です。

# Marketoのカスタムオブジェクト利用時の注意点

Marketoのカスタムオブジェクトのデータを取得するには、Marketo側のAPI制約に注意が必要です。[CData ODBC Driver for Marketo 2018J マニュアル CustomObjects]( http://cdn.cdata.com/help/HKD/odbc/pg_resttable-customobjects.htm )をご覧ください。

>Marketo REST API では、カスタムオブジェクトを取得するためにフィルタを指定する必要があります。フィルタは少なくとも一つのキーカラム、dedupeField、または検索可能なカラムを含んでいる必要があります。 これらのフィルタタイプでは、'=' 論理演算子のみがサポートされています。加えて、他のフィルタを指定することができますが、先述のフィルタを少なくとも一つ指定する必要があります。 すべてのフィルタリング可能なカラムでは、IN 演算子またはOR 論理演算子を使って複数の値を指定できます。
>
>取得したい行とカラムだけを指定することで、サーバーからの応答時間を向上できます。 
>
>SELECT Make, Model, Year, Color FROM CustomObject_MyCustomBikeObject WHERE VIN='12345'

つまり、キー項目、もしくは、重複排除項目（dedupeField）の指定が必須となります。あるリード情報に（リンクフィールドで）紐づいているカスタムオブジェクトのレコード情報を取得するには下記のSQLとなりますが、WHERE句は＝（イコール）しか指定出来ないため、複数のリードに紐づくカスタムオブジェクトのデータを取得することが出来ません。

```sql
SELECT * FROM CustomObject_cdataj WHERE LinkID='12345'
```
※上記、LinkIDは、リードのIDを指定するリンクフィールド

CData ODBC Drivers製品では、複数のリードに紐つくカスタムオブジェクトの情報を、下記のような副問い合わせのSQLで取得することが可能としています。

```sql
select * from CustomObject_cdataj where LinkId IN (SELECT Id FROM Leads LIMIT 100)
```

ただし、内部的には、Leadsテーブルから取得したIdの数だけ、CustomObject_cdatajを取得するリクエストが発行されるため、全リードを検索すると期待するパフォーマンスが得られないことがあります。そこで、下記のようにLeadsテーブルをCreatedAtやUpdatedAtで期間を絞り込む事を検討してください。

select * from CustomObject_cdataj where LinkId IN (SELECT Id FROM Leads UpdatedAt > '2018-01-01')

なお、Leadテーブルもフィルタの指定に制約がありますので、[CData ODBC Driver for Marketo 2018J マニュアル Leads]( http://cdn.cdata.com/help/HKD/odbc/pg_resttable-leads.htm )をご覧ください。

>すべてのカラムは '=' 演算子を使って指定される必要があります。すべてのフィルタリング可能なカラムでは、IN 演算子またはOR 論理演算子を使って複数の値を指定できます。
>
>取得したい行とカラムだけを指定することで、サーバーからの応答時間を向上できます。 
>
>SELECT Id, FirstName, LastName FROM Leads WHERE Id IN ('1','2','5','10')
フィルタが指定されていない場合は、Activities_NewLead テーブルがクエリされ、Lead Id のリストが取得されます。Lead Id がコンパイルされたら、コンパイルされたLead Id のリストを使ってLeads テーブルがクエリされます。 CreatedAt カラムは、取得するリードが作成された日時の範囲を指定するフィルタとして使用できます。'>' または'>=' 演算子を指定すると、 Activities_NewLead テーブルリクエストにdatetime 値が送られます。これは追加のAPI 呼び出しを必要とし、少なくとも倍のAPI 呼び出しが発生します。これは、それぞれのLeads リクエストに対して、1つのActivities_NewLead が発生するためです。 REST API のリクエストごとの最大バッチサイズは300です。必要なAPI 呼び出しの概算を出すには、次の式が使えます： (リードの総数 / 300) * 2
>
>UpdatedAt カラムは、取得するリードが更新された日時の範囲を指定するフィルタとしても使用できます。フィルタを指定した場合は、Activities_LeadChanges テーブルがクエリされ、Lead Id のリストが取得されます。 Lead Id がコンパイルされたら、コンパイルされたLead Id のリストを使ってLeads テーブルがクエリされます。'>' または'>=' 演算子を指定すると、 Activities_LeadChanges テーブルリクエストにdatetime 値が送られます。これは追加のAPI 呼び出しを必要とし、少なくとも倍のAPI 呼び出しが発生します。これは、それぞれのLeads リクエストに対して、1つのActivities_LEADChanges が発生するためです。 大抵の場合、API 呼び出しの総数は、リードの個々の値がレコードとして返されるため、倍以上になります。 したがって、Lead Id の完全なリストを入手するには、複数のActivities_LeadChanges リクエストが必要になることがあります。REST API のリクエストごとの最大バッチサイズは300です。必要なAPI 呼び出しの最小見積もりを出すには、次の式が使えます： (リードの総数 / 300) * 2
>
>複数のAPI 呼び出し利用を回避しベストパフォーマンスを得るには、Marketo 内でリードのスタティックリストを作成し、ListId を指定してそれらを取得します。

# Tableau Desktop からカスタムオブジェクトへのアクセス

Tableau DesktopのマシンにCData　Driverをインストールします。３０日間ご利用頂ける評価版がありますので[こちらのページ](https://www.cdata.com/jp/drivers/marketo/download/odbc/)よりインストーラをダウンロードしてください。

ダウンロードされたインストーラを起動するとセットアップウィザードが起動します。ウィザードに従ってインストールを完了してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/c928e8b2-338b-febd-5097-0ef10de4414f.png)
途中オンラインでのアクティベーションが走りますので、プロキシサーバー経由での外部ネットワークへ接続する環境だとアクティベーションに失敗する場合があります。その場合には、オフラインでのアクティベーションの方法がありますので[CData社のサポート窓口](https://www.cdata.com/jp/support/submit.aspx)までお問い合わせください。

インストールが終わると、ODBCのDSN設定が起動します。接続プロパティを「必須を表示」をクリックして下記の項目をセットします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/c3c8d803-4e5a-15db-bec8-4e5022823b7e.png)

- OAuth Client Id & OAuth Client Secret : 管理画面「LaunchPoint」を選択して「インストール済みのサービス」より「REST Service」を選択して表示されたクライアントIDとクライアントシークレットをセット
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/3944d04d-ff68-8c4c-1997-156bf880ab08.png)
- REST Endpoint ： 管理画面「ウェブサービス」内のREST　APIのEndopointを設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/6928e92b-da4c-45d9-8788-3427cfdf7fbf.png)
- Schema : REST を指定

「接続テスト」を実行して成功したら、OKボタンでDSN設定を保存して閉じてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/70914b35-4b2a-ffd9-9bcb-995fe06782fb.png)

Tableau　Desktopの接続を開いて、「その他のデータベース（ODBC）」を開きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/a85d7eed-75ef-abad-01ba-eb8a7acbd5c8.png)

接続手段のDSNに上記で設定したDSNを指定します（※システムDSNとユーザDSNにご注意ください）。「接続」ボタンをクリックして接続に成功すると「サインイン」ボタンが活性化されますのでクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/28632b3a-40b5-07ff-7d57-1d6b80489b26.png)

「データソース」タブが開くので、「データベース＝CData」を選択して、表の「表の名前の入力」右横の検索アイコン（小さくてわかりにくいです）をクリックすると、テーブルのリストが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/7a04bb5a-1414-599f-23bc-bd8d4b3b3809.png)

試しに、CustomObjectを選択して、ドラッグ＆ドリップで右上のペインにセットしてライブ接続で「今すぐ更新」をクリックしてみます。すると、'＝'でのフィルタで絞りこむ必要がある旨のエラーメッセージが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/1bf4969b-dfaf-4a0f-03da-946ca6c6c5b9.png)

リンクフィールドの項目でフィルターを指定してみると、該当のキーの値が存在する場合にはレコードが取得出来る事を確認出来ます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/0a0aebc1-483d-4fc5-e2d6-df2c8228db57.png)

フィルタを一度クリアして、「CustomObject」を右クリックして「カスタムSQLの編集」から副問い合わせを含む複数Leadを取得出来るSQLを指定します。

```sql
select * from CustomObject_cdataj where LinkId IN (SELECT Id FROM Leads LIMIT 100)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/aa9df4fa-d232-5e59-b041-e742eb9c0fbf.png)

再度、「今すぐ更新」でデータを表示してみると、複数Leadにリンクするカスタムオブジェクトのデータが取得出来ました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/123181/08be6733-fc85-a526-dd39-c101ac741713.png)

# おわりに

CData　 ODBC Driver for Marketoを使用する事で、Tableauの標準コネクターでは取得出来ないMarketoのカスタムオブジェクトからデータを取得することが出来ました。本手順でご不明な点などがありましたら↓よりコメントくださいませ。