kintone: ファイルダウンロード

kintone: ファイルダウンロード

kintone: Download File

この工程は、kintone アプリのレコード(1件)の添付ファイルフィールドからファイルをダウンロードします。

Auto Step icon
Basic Configs
工程名
メモ
Configs for this Auto Step
conf_auth
C1: API トークンを設定した認証設定 *
conf_basic
C2: Basic 認証設定(kintone で設定されている場合のみ)
conf_domain
C3: ドメイン(xxxxx.kintone.com または xxxxx.cybozu.com) *
conf_guestSpaceId
C4: ゲストスペース ID(ゲストスペース内のアプリの場合のみ)
conf_appId
C5: アプリ ID *
conf_recordId
C6: レコード ID *
conf_fieldCode
C7: 添付ファイルフィールドのフィールドコード *
conf_files
C8: ダウンロードファイルを追加保存するファイル型データ項目 *

Notes

  • kintone アプリの API トークンを取得するには、アプリの設定画面の「設定(App Settings)」のタブを開き、「API トークン(API Token)」へと進みます。

    「生成する(Generate)」をクリックし、権限(Permissions)を選択(「レコード参照(View records)」権限が必要です)したあと、「保存(Save)」をクリックします。

    「アプリを更新(Update App)」をクリックして変更を適用するのも忘れないようにしてください。
  • kintone アプリのゲストスペース ID(アプリがゲストスペースにある場合)とアプリ ID は、API トークンの設定画面で確認することができます。

Capture

See Also

Script (click to open)
  • 次のスクリプトが記述されている XML ファイルをダウンロードできます
    • kintone-file-download.xml (C) Questetra, Inc. (MIT License)
    • Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます


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;
}

  

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む

上部へスクロール