TL;TR
からファイルをダウンロードする。
<YOUR API KEY>
の箇所を書き換える。
IntercomのPHPのSDKを同じ階層にcomposer経由でダウンロードする。
composer require intercom/intercom-php php-http/guzzle6-adapter
以下のコマンドで実行する。
php index.php
解説
IntercomのAPIを純粋に片っ端から叩いてデータを集めてきて最後に配列にして1行ずつCSVに書き出しています。
Intercomの画面上から会社やユーザー情報はCSVエクスポートできます。
会話のデータもエクスポートできますが、過去2年分でサマリーのみになるため、細かな会話のやり取りを出力するにはAPIを使う方法しかありません。(個々の会話の画面から plain text でダウンロードするボタンもありますが、件数が多いと大変かと思います。)
処理に時間がかかる
IntercomのAPIはレスポンスがそんなに早くなく、4年ほどの会話データおよそ2万行を抽出するのに10時間くらいかかりました。
RateLimitに引っかかることはなさそう
IntercomのAPIはたまにタイムアウトしてしまいます。
このスクリプトを回してる途中にRateLimitに引っかかるかなと思っていましたが、レスポンスが爆速でもないので引っかからずに最後まで処理できるかと思います。
https://developers.intercom.com/intercom-api-reference/reference#rate-limiting
タイムアウトするなど途中で処理が止まってしまうとまた最初からやり直しになってしまうため、会話データは最後にまとめてではなく1行ずつCSVに書き出すようにしています。
APIの結果をファイルに保存する
file_put_contents("admins.dat", serialize($admins));
のように配列を全部シリアライズしてファイルに書き出しているのは、途中でタイムアウトして失敗したときはそれ以前のAPIコール部分はファイルをデシリアライズしてそれを代替として使えるようにするためファイルに保存しています。
会話データのhtmlタグ除去
パラメータに 'display_as' => 'plaintext'
を指定することでタグが除去されます。
$result = $client->conversations->getConversations([
'display_as' => 'plaintext'
]);
IntercomのAPI設計は微妙
ページングの処理が微妙
微妙というか過渡期というか、ページングの処理がまちまちです。
AWSをはじめ多くのAPIの設計が nextToken
でページング処理をしていると思いますが、
にあるようにパラメータに page=
で渡すパターンが中心です。(v2.3時点)
contactsだけはなぜか
"next": {
"page": 4,
"starting_after": "1HaSB+xrOyyMXAkS/c1RteCL7BzOzTvYjmjakgTergIH31eoe2v4/sbLsJWP\nIncfQLD3ouPkZlCwJ86F\n"
}
のようにしてページ番号とともにページ送りをするためのトークンがセットされています。
contacts取得時のページ送りの処理
if (! empty($result->pages->next)) {
$result = $client->contacts->nextCursor($result->pages);
}
とそれ以外のページ送りの処理
if (! empty($result->pages->next)) {
$result = $client->nextPage($result->pages);
}
が異なっているのは上記の理由からです。
逆にcontactsではnextPage()が動きません。
Intercom PHP SDK v4.4.2 の nextCursorPage バグ
2020年11月19日 時点での最新版 v4.4.2 には nextCursorPageの処理にバグがあります。
でプルリクが出ていますが、APIを叩いたレスポンスをモデルに変換する処理が二重で行われているためエラーになります。
のように修正する必要があります。
メインデータのレスポンスが微妙
管理者ユーザーの一覧データのレスポンスは
foreach ($result->admins as $admin) {
$admins[$admin->id] = $admin->name;
}
ですが、会社の一覧データのレスポンスは
foreach ($result->data as $company) {
$companies[$company->id] = $company;
}
だったりして、なぜか $result->admins
のようなケースと $result->data
のようなケースがあるので注意が必要です。
感想
IntercomのAPI叩いて会話のデータをCSV出力するのなんて世界のどこかに先人がいるだろう、と思っていましたが、Dockerのコンテナ上でCをコンパイルして会話データを取得するっぽいことをしてたりなんやかんやいいのがないので致し方なく自分でスクリプトを組みました。
とりあえず1回きりのデータ全出力、のつもりで作っているのでエラーハンドリングとかは無考慮です。
別にPHPじゃなくてPerlやRuby,Pythonでもいいんですが(JavaとNodeは下準備が多いので却下)
https://developers.intercom.com/building-apps/docs/sdks-plugins
用意されているSDKを見て、まあRubyより書き慣れているPHPで書いておくか、という判断をしました。