Box Sign: 署名リクエスト作成 (Box Sign: Create Sign Request)
この工程は、Box 上のファイルから署名用ドキュメントを作成し、署名リクエストを送信します。
Configs:共通設定
  • 工程名
  • メモ
Configs
  • C1: OAuth2 設定 *
  • C2: 署名用ドキュメントの作成元ファイル ID *
  • C3: 署名用ドキュメントを保存するフォルダ ID (ルートフォルダは使用できません) *
  • C4: 署名者メールアドレス (複数設定する場合、1件ごとに改行してください) *
  • C5: 署名者ごとのパスワード (1件ごとに改行してください)
  • C6: 送信されるメールの件名 (空白の場合、デフォルトの件名が使用されます)#{EL}
  • C7: メール本文に含めるメッセージ (空白の場合、デフォルトの文面が使用されます)#{EL}

Notes

  • Box プラットフォームで Box Sign が有効にされている必要があります(デフォルト:無効)
  • C1: OAuth2 設定で認証を得るユーザは、Box のBusiness プランのユーザーアカウントが必要です
  • ファイル ID は、URL に含まれています。https://{sub-domain}.app.box.com/file/(File ID)
  • フォルダ ID は、URL に含まれています。https://{sub-domain}.app.box.com/folder/(Folder ID)
  • Box のリフレッシュトークンには、期限があります。期限を超えないよう、定期的に利用する必要があります。(Box: トークンおよびURLの有効期限)
  • 「電子すかし」が適用されたファイルを署名の対象にするとエラーとなります

Capture

See also

Script (click to open)
  • 下記のスクリプトを記述した XML ファイルをダウンロードできます
    • box-sign-request-create.xml (C) Questetra, Inc. (MIT License)
    • Professional をご利用であればファイルの内容を改変することでオリジナルのアドオンとして活用できます


// OAuth2 config sample at [OAuth 2.0 Setting]
// - Authorization Endpoint URL: https://account.box.com/api/oauth2/authorize
// - Token Endpoint URL: https://api.box.com/oauth2/token
// - Scope: sign_requests.readwrite root_readwrite
// - Consumer Key: (Get by Box Developer Console)
// - Consumer Secret: (Get by Box Developer Console)

main();
function main(){
  //// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
  const oauth2 = configs.get('conf_OAuth2');
  const fileId = decideEditable('conf_SourceFileId', 'Source File ID');
  const folderId = decideEditable('conf_FolderId', 'Folder ID');
  if (folderId === '0') {
    throw 'Root folder cannot be used.';
  }
  const signers = retrieveSigners();
  const subject = configs.get('conf_EmailSubject');
  const message = configs.get('conf_EmailMessage');

  //// == 演算 / Calculating ==
  createRequest(oauth2, fileId, folderId, signers, subject, message);
}

/**
  * editable な config から設定値を読み出す
  * 設定値が空の場合はエラー
  * @param {String} confName 設定名
  * @param {String} label エラー出力用ラベル
  * @return {String} value 設定値
  */
function decideEditable(confName, label) {
  let value = '';
  const dataDef = configs.getObject(confName);
  if (dataDef === null) {
    value = configs.get(confName);
  } else {
    value = engine.findData(dataDef);
  }
  if (value === '' || value === null) {
    throw `${label} is blank.`;
  }
  return value;
}

/**
  * 署名者情報 (メールアドレスとパスワード) をデータ項目から読み出す
  * 1つも設定されていない場合、上限件数を超える場合はエラー
  * @return {Array<Object>} signers 署名者 {email, password} の配列
  */
function retrieveSigners() {
  const emails = retrieveFilledArray('conf_EmailAddress', 'Email Address');
  const passwords = retrieveFilledArray('conf_Password', 'Password');

  // 件数チェック
  if (emails === null || emails.length === 0) {
    throw 'No Email Address.';
  }
  if (emails.length > 35) { // Box Sign の仕様で最大35件まで
    throw 'Number of Email Addresses exceeds the limit. The maximum number is 35.';
  }

  // 署名者の配列を作成
  const signers = emails.map(email => ({email}));
  if (passwords === null) { // パスワード設定なし
    return signers;
  }
  // パスワード設定あり
  if (passwords.length !== signers.length) { // 件数が一致しない
    throw 'Number of Passwords does not match the number of Email Addresses.';
  }
  passwords.forEach((password, i) => {
    signers[i].password = password
  });
  return signers;
}

/**
  * config から複数行のデータを読み出し、配列を生成する
  * データ項目が設定されていない場合は null を返す
  * データ項目が設定されていて、中身が空の場合はエラー
  * 空行を含む場合はエラー (最後に空行がひとつだけある場合は無視)
  * @param {String} confName config 名
  * @param {String} label エラー出力に使用するラベル
  * @return {Array<String>} array 空文字列を含まない配列
  */
function retrieveFilledArray(confName, label) {
  const dataDef = configs.getObject(confName);
  if (dataDef === null) { // データ項目が設定されていない
    return null;
  }
  const string = engine.findData(dataDef);
  if (string === null || string === '') { // データ項目の中身が空
    throw `Data item for ${label} is set but its content is empty.`;
  }

  const array = string.split('\n');
  if (array[array.length - 1] === '') { // 最後に空行があれば削除
    array.pop();
  }
  // 空行が残っている場合はエラー
  const i = array.indexOf('');
  if (i !== -1) {
    throw `${label} at line ${i+1} is blank.`;
  }
  return array;
}

/**
  * Create Sign Request  署名リクエスト作成
  * @param {String} oauth OAuth2 設定
  * @param {String} fileId 元ファイルの ID
  * @param {String} folderId 保存先フォルダの ID
  * @param {Array<Object>} signers 署名者 {email, password} の配列
  * @param {String} subject 送信メールの件名
  * @param {String} message 送信メールに含めるメッセージ
  */
function createRequest(oauth2, fileId, folderId, signers, subject, message) {
  const jsonBody = {signers};
  jsonBody['source_files'] = [{
    'id': fileId,
    'type': 'file'
  }];
  jsonBody['parent_folder'] = {
    'id': folderId,
    'type': 'folder'
  };
  if (subject !== '' && subject !== null) {
    jsonBody['email_subject'] = subject;
  }
  if (message !== '' && message !== null) {
    jsonBody['email_message'] = message;
  }

  const url = 'https://api.box.com/2.0/sign_requests';
  const response = httpClient.begin()
    .authSetting(oauth2)
    .body(JSON.stringify(jsonBody), 'application/json; charset=UTF-8')
    .post(url);

  const status = response.getStatusCode();
  const responseTxt = response.getResponseAsString();

  if (status !== 201) {
    engine.log(responseTxt);
    throw `Failed to create Sign Request. status:${status}`;
  }
}

%d人のブロガーが「いいね」をつけました。