
Timer Start: kintone: Number of Records
This item periodically starts processes with the number of records matching the search query from a Kintone App. In each string type data item of each process, each record ID will be set.
Basic Configs
- Step Name
- Note
Configs for this Auto Step
- conf_auth
- C1: Authorization Setting in which API Token is set *
- conf_basic
- C2: Basic Auth Setting (required if enabled on Kintone)
- conf_domain
- C3: Domain (such as xxxxx.kintone.com or xxxxx.cybozu.com) *
- conf_guestSpaceId
- C4: Guest Space ID (required if the App is in a Guest Space)
- conf_appId
- C5: App ID *
- conf_query
- C6: Search Query#{EL}
- conf_idData
- C7: Data item to save Record ID *
Notes
- You can set multiple schedules on a Timer
- The number of Processes that can be started simultaneously is limited to 100
- To get the API Token, open the App Settings and click “API Token” in the App Settings tab on Kintone
Click “Generate”, select the Permissions (“View records” permission is required), and click “Save”
Do not forget to click “Update App” to apply the update - Guest Space ID (only when the Kintone App is in a guest space) and App ID can be confirmed in the API Token settings on Kintone
- See the Kintone Reference for the operators and functions that can be used in Search Query
- Query options (order by, limit, offset) are not supported
Capture


See Also
- R2170: Limitation on the Number of Running Processes
- M217: Setting a Time and Date to Auto-Start a Process
- Starting a Process Every Monday Morning
Script (click to open)
- An XML file that contains the code below is available to download
- kintone-num-of-records.xml (C) Questetra, Inc. (MIT License)
- Just use it for a reference for the codes
- This file cannot be imported into a Workflow App as an Add-on
- kintone-num-of-records.xml (C) Questetra, Inc. (MIT License)
function list(limit) {
//// == 工程コンフィグの参照 / Config Retrieving ==
const auth = configs.getObject("conf_auth");
const basic = configs.getObject("conf_basic");
const domain = configs.get("conf_domain");
const guestSpaceId = configs.get("conf_guestSpaceId");
const appId = configs.get("conf_appId");
const query = configs.get("conf_query");
//// == ワークフローデータの参照 / Data Retrieving ==
const apiUri = determineApiUri(domain, guestSpaceId);
checkAppId(appId);
return getRecords(apiUri, auth.getToken(), basic, {app: appId, query}, limit);
}
/**
* kintone REST API のレコード取得の URI を決定する
* ドメインが空、または kintone のドメインとして不正な文字列であればエラーとする
* @param {String} domain ドメイン
* @param {String} guestSpaceId ゲストスペース ID
* @return {String} apiUri API の URI
*/
function determineApiUri(domain, guestSpaceId) {
checkDomain(domain);
let apiUri;
if (guestSpaceId === "" || guestSpaceId === null) {
apiUri = `https://${domain}/k/v1/`;
} else {
if (!isValidId(guestSpaceId)) {
throw new Error("Invalid Guest Space ID.");
}
apiUri = `https://${domain}/k/guest/${guestSpaceId}/v1/`;
}
return apiUri;
}
/**
* ドメインが空または不正な文字列であればエラーとする
* @param {String} domain ドメイン
*/
function checkDomain(domain) {
if (domain === "" || domain === null) { // required="true" なので空になることはないが、チェック
throw new Error("Domain is empty.");
}
const reg = new RegExp('^[0-9a-zA-Z-]{3,32}.(?:kintone.com|cybozu.com)$');
if (!reg.test(domain)) {
throw new Error("Invalid Kintone domain.");
}
}
/**
* アプリ ID が空または不正な文字列であればエラーとする
* @param {String} appId アプリ ID
*/
function checkAppId(appId) {
if (appId === "" || appId === null) { // required="true" なので空になることはないが、チェック
throw new Error("App ID is empty.");
}
if (!isValidId(appId)) {
throw new Error("Invalid App ID.");
}
}
/**
* ID が有効か(自然数か)を判定する
* @param {String} idString ID の文字列
* @return {Boolean} 有効な ID かどうか
*/
function isValidId(idString) {
const idReg = new RegExp('^[1-9][0-9]*$');
return idReg.test(idString);
}
/**
* kintone REST API にレコード取得の GET リクエストを送信する
* 未取得のレコードがなくなるまで再帰的に実行される
* @param {String} apiUri API の URI
* @param {String} apiToken API トークン
* @param {String} basic Basic 認証設定
* @param {Object} params GET リクエストのパラメータに使用する情報が格納されたオブジェクト
* プロパティ: {String} app アプリ ID
* {String} query 検索クエリ
* @param {Number} limit 1 回のリクエストで取得するレコード数
* @return {Array<String>} records レコード ID の配列
*/
function getRecords(apiUri, apiToken, basic, {app, query}, limit) {
const getRecordsUri = `${apiUri}records.json`;
let request = httpClient.begin()
.queryParam("app", app)
.header("X-Cybozu-API-Token", apiToken);
if (basic !== null) {
request = request.authSetting(basic);
}
// query パラメータの設定
if (query === "" || query === null) {
request = request.queryParam("query", `order by $id asc limit ${limit + 1}`);
} else {
request = request.queryParam("query", `( ${query} ) order by $id asc limit ${limit + 1}`);
}
request = request.queryParam('fields[0]', '$id');
const response = request.get(getRecordsUri);
//when error thrown
const responseStr = response.getResponseAsString();
const status = response.getStatusCode();
if (status >= 300) {
engine.log(`---GET request--- ${status}\n${responseStr}\n`);
throw new Error(`Failed to get records. status: ${status}`);
}
const records = JSON.parse(responseStr).records;
if (records.length > limit) {
throw new Error(`The number of records exceeds the limit ${limit}.`);
}
return records.map(record => ({
id: record.$id.value
}));
}