kintoneアプリからGASでレコード情報を取得する方法(カーソルから取得する方法)

kintone REST APIを利用して、kintoneアプリ内のレコード情報を取得する方法をご紹介します。
レコード情報を一括で取得する方法は2つ用意されています。
今回は、そのうちカーソルを作成してレコード情報を取得する方法をご紹介します。
カーソルは、 DB 内の位置情報のことで、今回の方法の方が、レコード情報を取得する方が処理速度が早いそうです。

kintone REST APIの認証

kintone REST APIでkintoneのサーバーにアクセスするときに必要な認証には、2つの方法があります。パスワード認証と、APIトークン認証です。

今回は、普段kintoneにログインするときに利用しているログイン名とパスワードを利用したパスワード認証の方法をご紹介します。

const api_url = 'https://xxxxxx.cybozu.com';
const authorization = encodeBase64Text('ログイン名:パスワード');

// Base64エンコード
function encodeBase64Text(text) {
  return Utilities.base64Encode(text, Utilities.Charset.UTF_8)
}

1行目のapi_urlに設定するのは、kintoneにログインした時のドメインです。
✕✕✕の部分は、アカウントによって異なります。

2行目が、パスワード認証で利用します。「ログイン名:パスワード」の部分には、実際に利用しているログイン名とパスワードを入力してください。
ログイン名とパスワード部分は、Base64でエンコードして送信されます。

カーソルの作成

一括でレコード情報を取得する場合、カーソルというDB上の位置情報を作成し、作成したカーソルの位置情報からレコードを取得することが可能になります。

カーソルを作成するCreateCursor関数

//カーソルの作成
function CreateCursor(data)
{
  let headers = {
    'Content-Type':'application/json',
    'X-Cybozu-Authorization':authorization
  };
  let options = {
    'method' : 'post',
    "headers" : headers,
    'payload' : JSON.stringify(data)
  };
  let response = UrlFetchApp.fetch(api_url+'/k/v1/records/cursor.json', options);
  return JSON.parse(response);
}

第1引数には、ボディ情報を渡します。

CreateCursor関数の使い方

  let app_id = 100;
  let data = {
    'app':app_id,
    'fields': ['レコード番号', '日時'],
    'query':"日時 = LAST_WEEK() order by レコード番号 desc",
    'size': 500
  }
  let result = CreateCursor(app_id,data);

app_id変数には、kintoneアプリIDが入ります。
アプリIDは、kintoneアプリをブラウザでアクセスした時のURLが「https://xxxx.cybozu.com/k/100/」の場合は、「100」がkintoneのアプリIDとなります。

fieldsには、取得したいフィールドコードを書きます。省略した場合は、すべてのフィールドを取得できます。ここに記載するのは、フィールドコードであって、フィールド名ではないということに注意してください。

queryには、「検索条件 order by データの並び順」という指定方法になります。
省略した場合は、sizeで指定したレコード数の範囲内ですべてのデータを取得します。
上記のサンプルでは、日付フィールドが、先週のレコード情報をレコード番号の降順に取得します。
検索条件で指定している「日時 = LAST_WEEK()」ですが、この場合は、日時のフィールドの値が、先週だったデータを取得しています。先週とは、前の週の日曜日~土曜日を指します。
他にもTODAY()、YESTERDAY()など色々な関数が用意されています。
参照ページ
https://developer.cybozu.io/hc/ja/articles/202331474#q1-function

sizeは、1回のGETリクエストでカーソルから取得するレコード数を指定します。
最大500まで指定可能で、省略した場合は、100件までとなります。

CreateCursor関数の戻り値ですが、カーソルIDが返ってきます。このカーソルIDを利用してレコード情報を取得します。

作成したカーソルからレコード情報をすべて取得する

//カーソルIDからレコード情報の取得
function GetCursor(id)
{ 
  let headers = {
    'X-Cybozu-Authorization':authorization
  };
  let options = {
    'method' : 'get',
    "headers" : headers
  };
  let response = UrlFetchApp.fetch(api_url+'/k/v1/records/cursor.json?id='+id, options);
  return JSON.parse(response);
}

GetCursor関数を作成しました。引数にカーソルIDを渡します。

先程sizeの指定で最大値が500と書きました。1回に500件のレコード情報を取得できますが、それ以上レコードがある場合は、複数回上記の関数を繰り返します。

  let result = CreateCursor(data);
  let records_data = GetCursor(result.id);
  console.log(records_data.records);//consoleにレコード情報を表示
 //レコード情報をすべて取得するまで繰り返す
  while(records_data.next){
    records_data = GetCursor(result.id);
    console.log(records_data.records);//consoleにレコード情報を表示
  }

1行目で、カーソルを作成し、2行目のGetCursor関数の引数にカーソルIDを渡しています。

3行目で取得したレコード情報をコンソールに出力していますが、上限が500件までですので、すべてのレコードを取得するまで、5行目以降で繰り返しGetCursor関数を実行しています。

カーソル作成の方法では、offsetが利用できない

CreateCursor関数の使い方の説明のところで、queryを書くことができましたが、limitやoffsetが利用できません。
offsetは、本来レコードの何番目の情報から取得するという指定をするためのものです。
画面上に、100件ずつ情報を表示したい場合、100件だけレコード情報を取得すればいいだけですので、何万件も1度に情報を取得すると、処理が重くなってしまいます。

たとえば、画面の2ページは、101番目のレコードから、200番目までのレコード情報があれば良いため、通常クエリには、「limit 100 offset 101」と指定します。

カーソル作成の方法では、limitとoffsetが利用できませんので、そういった処理が書けません。
ただ大量にデータを取得する場合は、カーソル作成の方法の方が取得時間が安定しているそうですので、バッチ処理など、大量のデータを一度に処理したいときに有効な取得方法になります。

ソースコード全体

最後に今回ご紹介したソースコードを下記のまとめました。
1行目、2行目、5行目部分は書き換えが必要です。

const api_url = 'https://xxxx.cybozu.com';
const authorization = encodeBase64Text('ログイン名:パスワード');

function myFunction() {
  let app_id = 100;//kintoneアプリID
  let data = {
    'app':app_id,
    //'fields': ['レコード番号', '日付', '日時','文字列__1行_'],
    'query':"日時 = LAST_WEEK() order by レコード番号 desc",
    'size': 500
  }
  let result = CreateCursor(data);//カーソルの作成
  let records_data = GetCursor(result.id);//カーソルからレコード情報の取得
  console.log(records_data.records);//consoleにレコード情報を表示
 //レコード情報をすべて取得するまで繰り返す
  while(records_data.next){
    records_data = GetCursor(result.id);//カーソルからレコード情報の取得
    console.log(records_data.records);//consoleにレコード情報を表示
  }
}

//カーソルの作成
function CreateCursor(data)
{
  let headers = {
    'Content-Type':'application/json',
    'X-Cybozu-Authorization':authorization
  };
  let options = {
    'method' : 'post',
    "headers" : headers,
    'payload' : JSON.stringify(data)
  };
  let response = UrlFetchApp.fetch(api_url+'/k/v1/records/cursor.json', options);
  return JSON.parse(response);
}
//カーソルIDからレコード情報の取得
function GetCursor(id)
{ 
  let headers = {
    //'Content-Type':'application/json',
    'X-Cybozu-Authorization':authorization
  };
  let options = {
    'method' : 'get',
    "headers" : headers
  };
  let response = UrlFetchApp.fetch(api_url+'/k/v1/records/cursor.json?id='+id, options);
  return JSON.parse(response);
}

// Base64エンコード
function encodeBase64Text(text) {
  return Utilities.base64Encode(text, Utilities.Charset.UTF_8)
}

参考サイト
https://developer.cybozu.io/hc/ja/articles/360029152012