会社でsansanを使っているのですが、他のシステムと連携するために名刺情報をCSVで取得しています。
APIがあるんだから自動化したいよねってことでGASでやってみました。
function get_sansanCSV() {
const api_key = '******************';
//sansanアカウントに紐づけられたAPIキー
const sansan_endpoint = 'https://api.sansan.com/v3.2/'
// タグ指定だと期間指定ができない。期間指定だとタグ指定ができない。
const sansan_bizcards_tag = 'bizCards/search?'
const sansan_bizcards_term = 'bizCards?'
//期間指定のための日付フォーマット設定と1週間期間の作成
//YYYY-MM-DDThh:mm:ssTZD 形式
var date = new Date();
var date_footer = "T24:00:00+09:00"
var today = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd');
var up_dated_to = today + date_footer;
date.setDate(date.getDate() - 7);
var one_week_ago = Utilities.formatDate(date, 'JST', 'yyyy-MM-dd');
var up_dated_from = one_week_ago + date_footer;
const term = '&updatedFrom=' + up_dated_from + '&updatedTo=' + up_dated_to
var tag_id = '**********************'; //sansanのタグID。タグ一覧取得APIで確認できる
//認証用ヘッダー
var header = {
"X-Sansan-Api-Key": api_key
};
var options = {
'method': 'get',
'contentType': 'application/json',
'headers': header,
'muteHttpExceptions': false
}
try{
let pageToken = '';
let response;
let json;
let data;
let csv_data = [];
//リクエスト
do {
//let test_url = 'https://api.sansan.com/v3.2/me';
let search_set = 'nextPageToken='+ pageToken + term +'&includeTags=true&includePastBizCards=false&range=all&entryStatus=completed&orderBy=updatedAt&orderDirection=asc&limit=100';
const url = sansan_endpoint + sansan_bizcards_tag + search_set;
response = UrlFetchApp.fetch(url, options);
json = JSON.parse(response);
data = json.data;
for(i=0;i<data.length;i++){
csv_data.push([data[i].lastName,data[i].firstName,data[i].lastNameReading,data[i].firstNameReading,data[i].email,data[i].companyName,data[i].departmentName,data[i].title,"",data[i].countryCode,data[i].postalCode,data[i].prefecture,data[i].city,data[i].street,data[i].building,data[i].tel,data[i].fax,data[i].secondTel,data[i].url,"","","","","",data[i].owner.name,"","",""]);
}
pageToken = json.nextPageToken;
} while (pageToken);
//スプレッドシートに書き込み
const thisworksheet = SpreadsheetApp.getActiveSheet();
thisworksheet.getRange(2,1,csv_data.length,csv_data[1].length).setValues(csv_data);
} catch(e) {
//エラー時
cnost error_result = "エラー:" + e ;
console.log(error_result);
}
}
タグ+期間で取得できないようなので実務的にはダメでした。
・タグ指定ならそのタグ付いているもの全て
・期間指定ならそのほかの条件付けられない
というなんとも痒いところに手が届かないAPIのようでした。
ただ、公式ドキュメントは丁寧にまとめられているのでその点は非常にいいと思います。
https://docs.ap.sansan.com/ja/api/openapi/index.html
ちなみに、sansanAPIで引っ張ってこれる名刺情報の項目は下記になっていました。
id,companyId,personId,exchangeDate,registeredTime,updatedTime,owner,lastName,firstName,lastNameReading,firstNameReading, departmentName,title,email,mobile,companyName,countryCode,postalCode,address,prefecture,city,street,building,tel,secondTel,fax,url,memo,entryStatus,isUserCreated,isVirtualCard,tags,name,type,owner,name,type,owner,hasUnrecognizedChar
APIの仕様上やりたいことはできませんでしたが、nextPageTokenの使い方が分かったので勉強になりました。
使い方の考えとしては、下記のようにまとめられるかと思います。
let pageToken = "";
const url = "https://api.sansan.com/v3.2/bizCards?";
let param = "";
do{
param = "nextPageToken=" + pageToken + "?hoge=hoge";
response = UrlFetchApp.fetch(url + param, options);
json = JSON.parse(response);
data = json.data;
pageToken = json.nextPageToken;
}while(pageToken);
まず空のpageTokenを用意します。1回目のAPI実行時は、nextPageTokenの値は空で実行します。
1回目の実行で返ってきたJSONレスポンスの中にはnextPageTokenというプロパティがありますので、それをpageTokenに代入します。
無論1回の取得で全件取得できてしまえばnextPageTokenは空です。
この流れの繰り返しをすればいいので、do{}while();でpageTokenが空になるまで繰り返す処理を書きました。
nextPageTokenはYouTubeのAPIやGoogleの他アプリやAWSのサービスなんかでも使われている一般的な概念のようです。
大量のリストがあるとき、一回のAPIでは取得しきれない時に前回どこまで取得したかを記録しておく役割がnextPageTokenということですね。
APIでのやりとり(REST)はステートレスですからこんな工夫が必要になっているのでしょうね。
ちなみに、当記事のコードはスプレッドシートのコンテナバインドスクリプトであることが前提になっています。
スプレッドシートに書き込むので、CSV書き出しとかの処理も作れば自動化は簡単そうですね。
ただ、sansanのAPIがいまいちやりたいことにマッチしないので、今回はnextPageTokenの勉強ということでまとめました。
コメント