
kintone: Download File
This item downloads files from an Attachment field of a record in a Kintone App.
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_recordId
- C6: Record ID *
- conf_fieldCode
- C7: Field Code of Attachment field *
- conf_files
- C8: File type data item to add the downloaded files *
Notes
- To get an API Token, open the Settings of the App and click “API Token” in the App Settings tab on Kintone.
Click “Generate”, select 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.
Capture

See Also
Script (click to open)
- An XML file that contains the code below is available to download
- kintone-file-download.xml (C) Questetra, Inc. (MIT License)
- If you are using Professional, you can modify the contents of this file and use it as your own add-on auto step
main();
function main(){
//// == 工程コンフィグ・ワークフローデータの参照 / Config & Data 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 recordId = retrieveRecordId();
const fieldCode = configs.get("conf_fieldCode");
const filesDef = configs.getObject("conf_files");
const apiToken = auth.getToken();
let files = engine.findData( filesDef );
if (files === null) {
files = new java.util.ArrayList();
}
//// == 演算 / Calculating ==
checkDomainAndIds( domain, appId, recordId );
const apiUri = determineApiUri( domain, guestSpaceId ); // /v1/ までの URI
const attachments = getAttachmentsInfo( apiUri, apiToken, basic, appId, recordId, fieldCode );
getAndAddAttachments( apiUri, apiToken, basic, attachments, files ); // 添付ファイルをダウンロードして files に追加
//// == ワークフローデータへの代入 / Data Updating ==
engine.setData( filesDef, files );
}
/**
* config からレコード ID を読み出す
* @return {Stromg} recordId レコード ID
*/
function retrieveRecordId() {
const recordIdDef = configs.getObject( "conf_recordId" );
let recordId = configs.get( "conf_recordId" );
if ( recordIdDef !== null ) {
recordId = engine.findData( recordIdDef );
}
return recordId;
}
/**
* ドメイン、アプリ ID、レコード ID が空または不正な文字列であればエラーとする
* @param {String} domain ドメイン
* @param {String} appId アプリ ID
* @param {String} recordId レコード ID
*/
function checkDomainAndIds( domain, appId, recordId ) {
if ( domain === "" || domain === null ) {
throw "Domain is empty.";
}
const reg = new RegExp( '^[0-9a-zA-Z-]{3,32}.(?:kintone.com|cybozu.com)$' );
if ( !reg.test(domain) ) {
throw "Invalid Kintone domain.";
}
if ( appId === "" || appId === null ) {
throw "App ID is empty.";
}
if ( !isValidId(appId) ) {
throw "Invalid App ID.";
}
if ( recordId === "" || recordId === null ) {
throw "Record ID is empty.";
}
if ( !isValidId(recordId) ) {
throw "Invalid Record 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 の URI を決定する(/v1/ まで)
* ドメインが空、または kintone のドメインとして不正な文字列であればエラーとする
* @param {String} domain ドメイン
* @param {String} guestSpaceId ゲストスペース ID
* @return {String} apiUri API の URI(/v1/ まで)
*/
function determineApiUri( domain, guestSpaceId ) {
let apiUri = "";
if ( guestSpaceId === "" || guestSpaceId === null ) {
apiUri = `https://${domain}/k/v1/`;
} else {
if ( !isValidId(guestSpaceId) ) {
throw "Invalid Guest Space ID.";
}
apiUri = `https://${domain}/k/guest/${guestSpaceId}/v1/`;
}
return apiUri;
}
/**
* kintone REST API にレコード取得の GET リクエストを送信し、添付ファイルの情報の配列を返す
* @param {String} apiUri API の URI(/v1/ まで)
* @param {String} apiToken API トークン
* @param {AuthSettingWrapper} basic Basic 認証設定
* @param {String} appId アプリ ID
* @param {String} recordId レコード ID
* @param {String} fieldCode 添付ファイルフィールドのフィールドコード
* @return {Array<Object>} attachments 添付ファイル情報 {contentType, fileKey, name, size} の配列
*/
function getAttachmentsInfo( apiUri, apiToken, basic, appId, recordId, fieldCode ) {
let request = httpClient.begin()
.header( "X-Cybozu-API-Token", apiToken )
.queryParam( "app", appId )
.queryParam( "id", recordId );
if (basic !== null) {
request = request.authSetting(basic);
}
const response = request.get( `${apiUri}record.json` );
//when error thrown
const responseStr = response.getResponseAsString();
const status = response.getStatusCode();
if (status !== 200) {
const accessLog = `---GET request--- ${status}\n${responseStr}\n`;
engine.log(accessLog);
throw `Failed to get record. status: ${status}`;
}
const json = JSON.parse(responseStr);
if ( json.record[fieldCode] === undefined ) { // 一致するフィールドコードがない場合、エラー
throw `${fieldCode} does not exist in the record.`;
}
if ( json.record[fieldCode].type !== "FILE" ) { // 添付ファイルフィールドでない場合、エラー
throw `${fieldCode} is not an Attachment field.`;
}
return json.record[fieldCode].value;
}
/**
* kintone REST API にファイルダウンロードの GET リクエストを送信し、添付ファイルを配列に追加する
* @param {String} apiUri API の URI(/v1/ まで)
* @param {String} apiToken API トークン
* @param {AuthSettingWrapper} basic Basic 認証設定
* @param {Array<Object>} attachments 添付ファイル情報 {contentType, fileKey, name, size} の配列
* @param {Array<Qfile>} files ファイルの配列
*/
function getAndAddAttachments( apiUri, apiToken, basic, attachments, files ) {
const fileNum = attachments.length;
if ( fileNum + 1 > httpClient.getRequestingLimit() ) { // HTTP リクエストの上限を超える場合はエラー
throw "Necessary HTTP requests exceeds the limit.";
}
attachments.forEach( att => {
const response = getAttachment( apiUri, apiToken, basic, att );
const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
att.name,
response.getContentType(),
response.getResponse()
);
files.add( qfile );
});
}
/**
* kintone REST API にファイルダウンロードの GET リクエストを送信し、レスポンスを返す
* @param {String} apiUri API の URI(/v1/ まで)
* @param {String} apiToken API トークン
* @param {AuthSettingWrapper} basic Basic 認証設定
* @param {Object} attachment 添付ファイル情報 {contentType, fileKey, name, size}
* @return {HttpResponseWrapper} response レスポンス
*/
function getAttachment( apiUri, apiToken, basic, attachment ) {
let request = httpClient.begin()
.header( "X-Cybozu-API-Token", apiToken )
.queryParam( "fileKey", attachment.fileKey );
if (basic !== null) {
request = request.authSetting(basic);
}
const response = request.get( `${apiUri}file.json` );
//when error thrown
const status = response.getStatusCode();
if (status !== 200) {
engine.log(`attachment: ${JSON.stringify(attachment)}`);
const responseStr = response.getResponseAsString();
const accessLog = `---GET request--- ${status}\n${responseStr}\n`;
engine.log(accessLog);
throw `Failed to download file. status: ${status}`;
}
return response;
}
Pingback: Using kintone from Workflow – Questetra Support
Pingback: Starting Processes According to Records Shown in kintone Calendar – Questetra Support