開始: Box: ファイルアップロード時 (Start: Box: File Uploaded)
このアイテムは、Box の指定フォルダにファイルがアップロードされると、プロセスを開始します。
Configs: 共通設定
  • 工程名
  • メモ
Configs
  • C1: OAuth2 設定 *
  • C2: 監視するフォルダの ID (空白の場合、ルートフォルダ)
  • C3: ファイル ID を保存するデータ項目 *
  • C4: ファイルがアップロードされた日時を保存するデータ項目

Notes

  • フォルダ ID は、URL に含まれています。https://app.box.com/folder/(フォルダ ID)
  • 定期的に Questetra BPM Suite から Box にポーリングが行われ、アップロードされているファイルがないか、チェックされます。アップロードされているファイルがあれば、プロセスが開始されます。
  • 初回のチェック時には、プロセスは開始されません。チェックのみ行われます。チェックの状況は、プロセスログより確認できます。
  • 短時間に多数のファイルがアップロードされると、全てのファイルについて、プロセスは開始されません。目安は、15 分間で 90 プロセスです。
  • フォルダ内に、多数 (2021 年 4 月現在 1000) のアイテム (ファイル / フォルダ) がある場合、チェックは中止されます。アイテム数が増えすぎないように、コントロールしてください。

Capture

See also

Script (click to open)
  • 下記のスクリプトを記述した XML ファイルをダウンロードできます
    • box-file-uploaded.xml (C) Questetra, Inc. (MIT License)
    • コードの参考用にご利用ください
    • アドオンとしてワークフローアプリにインポートすることはできません

/**
 * @typedef {Object} timestamp java.sql.Timestamp オブジェクト
 */

/** 日時フォーマッター */
const datetimeFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");

/**
 * @param {string} str 日時文字列
 * @return {timestamp} java.sql.Timestamp オブジェクト
 */
const parseDatetime = str => new java.sql.Timestamp(datetimeFormatter.parse(str).getTime());

/**
 * configs から必要な情報を取り出す
 * @returns {Object} setting 設定
 * @returns {string} setting.folderId 検索対象の フォルダ ID
 * @returns {string} setting.oauth2 OAuth2 設定名
 */
const prepare = () => {
    const oauth2 = configs.get("conf_OAuth2");
    let folderId = configs.get("conf_FolderId");
    if (folderId === "" || folderId === null) {
        folderId = "0";
    }

    return {
        folderId,
        oauth2
    };
};

/**
 * ファイルの検索
 * @param {number} limit ファイル数の上限
 * @param {timestamp} timestampLowerLimit timestamp の下限
 * @returns {Array} files ファイル一覧
 * @returns {string} files[].id ファイル ID
 * @returns {timestamp} files[].timestamp ファイルアップロード時刻
 */
const list = (limit, timestampLowerLimit) => {
    const {
        folderId,
        oauth2
    } = prepare();

    let files = getFiles(oauth2, folderId, timestampLowerLimit);
    // 新しい順に並べ替え
    files.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
    // 先頭から limit で切る
    files = files.slice(0, limit);
    logFiles(files);
    return files;
};

/**
 * ファイルのログ出力
 * @param {Array} files ファイル一覧
 */
const logFiles = (files) => {
    if (files.length === 0) {
        engine.log("no files");
        return;
    }
    const replacer = (key, value) => value instanceof java.sql.Timestamp ? datetimeFormatter.format(value) : value;
    files.forEach(file => engine.log(JSON.stringify(file, replacer)));
};

/**
 * 指定フォルダ内の、ファイルの取得
 * フォルダ内のアイテム (ファイル+フォルダ) 数が 1000 を超える場合、エラー
 * @param {String} oauth2 OAuth2 設定
 * @param {String} folderId 検索対象のフォルダ ID
 * @param {timestamp} timestampLowerLimit timestamp の下限
 * @returns {Array} files ファイル一覧
 * @returns {string} files[].id ファイル ID
 * @returns {timestamp} files[].timestamp ファイルアップロード時刻
 */
const getFiles = (oauth2, folderId, timestampLowerLimit) => {
    const url = `https://api.box.com/2.0/folders/${folderId}/items`;

    const LIMIT = 1000; // Box API で定める LIMIT の最大値が 1000
    const response = httpClient.begin()
        .authSetting(oauth2)
        .queryParam("fields", "id,type,name,created_at")
        // date で sort をするが、これは更新日と思われる。作成日では sort できない。
        .queryParam('sort', 'date')
        .queryParam('direction', 'DESC')
        .queryParam("limit", String(LIMIT))
        .queryParam("usemarker", "true")
        .get(url);
    const status = response.getStatusCode();
    const responseTxt = response.getResponseAsString() + "\n";
    if (status >= 300) {
        const accessLog = `---GET request--- ${status}\n${responseTxt}\n`;
        engine.log(accessLog);
        throw `Failed to get files. status: ${status}`;
    }
    const json = JSON.parse(responseTxt);

    // marker がある場合は、フォルダに まだ ファイルがあるとみなして、エラーとする
    const marker = json['next_marker'];
    if (marker !== undefined && marker !== '' && marker !== null) {
        throw `More than ${LIMIT} items are in the specified folder`;
    }

    return json.entries
        .filter(entry => entry.type === 'file') // ファイルのみに絞り込み
        .map(formatFile)
        .filter(entry => !entry.timestamp.before(timestampLowerLimit)); // timestampLowerLimit 以降のデータのみに絞り込み
}

/**
 * Box のファイルデータから、必要な部分のみ抜き出す
 * @param file ファイルデータ
 * @returns {Object} file ファイル
 * @returns {string} file.id ファイル ID
 * @returns {timestamp} file.timestamp ファイルアップロード時刻
 */
const formatFile = (file) => {
    const {
        id,
        created_at
    } = file;
    return {
        id,
        timestamp: parseDatetime(created_at)
    };
};
%d人のブロガーが「いいね」をつけました。