クラウド型 ワークフロー

見積承認フローの改善奮闘 – 安全なファイルの提出(自動工程の開発) –

Box にアクセスする処理を javascript で書こう!

こんにちわ!矢作です!

 

ある営業部長(私のこと)は、現在「見積承認フロー」の改善に奮闘中!

 

今取り組んでいる改善は、「見積承認フロー」見積承認後に自動生成される見積書 PDF ファイルを安全にお客様に提出する手段を追加すること。「見積承認フローの改善奮闘 – 安全なファイルの提出(処理画面の作成) –」では、今回の改良に伴い変更するべき処理画面の設定方法などを紹介しました。

 

今回の記事では、いよいよアドオン(自動工程)の開発を行います。

クラウド型ワークフロー Questetra BPM Suite を利用

 

「見積承認フローの改善奮闘」では、業務フローの改善のために、クラウド型ワークフロー「Questetra BPM Suite」を使うことを前提として進めます。

 

「Questetra BPM Suite」上で利用していただけるアプリもダウンロードできるようにするので、実際に使ってみたい!と言う人は、Questetra BPM Suite 無料版をお申込みください。

 

アドオンを開発する前の確認

 

今回の「見積承認フロー」の改善で、ワークフロー図は次の図のように変更することとしました(※)。
見積承認フローの改善奮闘 – 安全なファイルの提出(処理画面の作成) –

 

 

今回、開発するアドオンは変更後のワークフロー図にある「Box へ」と書かれている工程です。このアドオンが行う処理は次のとおりです。

 

  • 見積書 PDF ファイルを自動的に Box にアップロード
  • ダウンロード期限、パスワードを設定
  • ダウンロード URL を取得

 

このアドオンが、このような処理を行うために、どのようなデータを受け取り(INPUT)、どのようなデータを出力(OUTPUT)するのかを前回(※)の記事で整理しましたが、その結果は次のとおりです。
見積承認フローの改善奮闘 – 安全なファイルの提出(INPUTとOUTPUTの整理) –

 

INPUT 項目 説明
OAuth2.0設定 Box にアクセスするための情報
フォルダID 見積書 PDF ファイルを保存する Box 内のフォルダの位置を示すもの
ダウンロード期限 営業マンが「提出準備」工程で指定する日付型の項目。
ダウンロードパスワード 営業マンが「提出準備」工程で指定する文字型(単一行)の項目。

 

OUTPUT 項目 説明
ダウンロード URL アップロードされたファイルをダウンロードするための URL

 

ここまで整理された情報をベースにアドオンの開発を行います。

 

アドオン(自動工程)の開発

 

アドオン(自動工程)がどのような処理を行うのかを定義したファイルは XML で書かれます。この XML ファイルを作成する詳細な説明は 使い方 に譲りますが、ここからは完成したアドオンを見ながら説明を進めていくこととします。

 

完成したアドオンは次のとおりです。

 

<?xml version="1.0" encoding="UTF-8"?>
<service-task-definition>
<label>[box] upload file and set Password/ Expiration</label>
<label locale="ja">Box ファイルアップロード(パスワード、期限)</label>

<summary>Uploads (one) file which set in File type Data Item into "box" and obtain its URL for publication. At the same time, it sets and expiration date. It is recommended to set "Max number of files" of the File type Data Item where the file to be uploaded as 1.</summary>

<summary locale="ja">ファイル型にセットされたファイル(1つ)を box にアップロードし、公開用URLを取得します。同時に、ダウンロード用パスワードと公開期限を設定します。アップロードするファイルが格納されるファイル型データ項目の「最大添付ファイル数」は 1 としておくことを推奨します。</summary>

<!--help-page-url></help-page-url>
<help-page-url locale="ja"></help-page-url-->


<configs>
  <config name="conf_OAuth2" required="true" form-type="TEXTFIELD">
    <label>A: Set OAuth2 Config Name (at [OAuth 2.0 Setting])</label>
    <label locale="ja">A: OAuth2通信許可設定名 (←[OAuth 2.0 設定])</label>
  </config>
  <config name="conf_DataIdB" required="true" form-type="SELECT" select-data-type="STRING_TEXTFIELD|SELECT_SINGLE">
    <label>B: Select STRING/SELECT for Folder ID on box ("0" for Root)</label>
    <label locale="ja">B: boxのフォルダIDが格納されている文字列型or選択肢型データを選択してください(ルートフォルダは"0")</label>
  </config>
  <config name="conf_DataIdC" required="true" form-type="SELECT" select-data-type="FILE">
    <label>C: Select FILE DATA for upload</label>
    <label locale="ja">C: アップロードするファイル型データを選択してください。</label>
  </config>
  <config name="conf_DataIdD" required="true" form-type="SELECT" select-data-type="DATE">
    <label>D: Select DATE DATA for file download expiration</label>
    <label locale="ja">D: ダウンロード期限が格納されている日付型データを選択してください</label>
  </config>
  <config name="conf_DataIdE" required="true" form-type="SELECT" select-data-type="STRING">
    <label>E: Select STRING DATA for download password</label>
    <label locale="ja">E: ダウンロードパスワードが格納されている文字型データを選択してください</label>
  </config>
  <config name="conf_DataIdF" required="true" form-type="SELECT" select-data-type="STRING">
    <label>F: Select STRING DATA for download URL</label>
    <label locale="ja">F: ダウンロードURLが格納される文字型データを選択してください</label>
  </config>
  <config name="conf_DataIdX" required="false" form-type="SELECT" select-data-type="STRING_TEXTAREA">
    <label>X: Select STRING DATA for Access Log (update)</label>
    <label locale="ja">X: 通信ログが格納される文字列型データを選択してください (更新)</label>
  </config>
</configs>

<script><![CDATA[
// (c) 2017, Questetra, Inc. (the MIT License)

//// == Config Retrieving / 工程コンフィグの参照 ==
var oauth2  = configs.get("conf_OAuth2") + "";
var dataIdB = configs.get("conf_DataIdB") + "";
var dataIdC = configs.get("conf_DataIdC") + "";
var dataIdD = configs.get("conf_DataIdD") + "";
var dataIdE = configs.get("conf_DataIdE") + "";
var dataIdF = configs.get("conf_DataIdF") + "";
var dataIdX = configs.get("conf_DataIdX") + "";

//// == Data Retrieving / ワークフローデータの参照 ==
var folderId = "";
if(engine.findDataByNumber(dataIdB) instanceof java.util.ArrayList ){
  folderId = engine.findDataByNumber(dataIdB).get(0).getValue() + "";
}else if( engine.findDataByNumber(dataIdB) instanceof java.lang.String ){
  folderId = engine.findDataByNumber(dataIdB) + "";
}
var files = engine.findDataByNumber(dataIdC);
var download_limit = engine.findDataByNumber(dataIdD) + "";
var download_password = engine.findDataByNumber(dataIdE) + "";

//// == File Upload ==
var accessLog = "";
var responseJson = "";
var token = httpClient.getOAuth2Token( oauth2 );

if (files !== null) {
  var file = files.get(0);
  var attributes = {
    parent : {id : folderId}
  };
  attributes["name"] = String(file.getName());

  var response = httpClient.begin()
    .bearer(token)
    .multipart('attributes', JSON.stringify(attributes))
    .multipart('file', file)
    .post('https://upload.box.com/api/2.0/files/content');
  accessLog += "---POST request--- " + response.getStatusCode() + "\n";
  accessLog += file.getName() + "\n";
  responseJson += response.getResponseAsString() + "\n";
}

// for Debug
accessLog += responseJson + "\n";

//// == ワークフローデータへの代入 / Data Updating ==
if( dataIdX !== "" ){
  engine.setDataByNumber(dataIdX,accessLog);
}

var update_info_obj = {};

update_info_obj.shared_link = {};
update_info_obj.shared_link.access = "open";
update_info_obj.shared_link.password = download_password;
update_info_obj.shared_link.unshared_at = download_limit;
update_info_obj.shared_link.permissions = {};
update_info_obj.shared_link.permissions.can_download = true;

var file_obj = JSON.parse(responseJson);
var file_id = file_obj.entries[0].id;

var response_update = httpClient.begin()
      .bearer(token)
      .body(JSON.stringify(update_info_obj), "application/json" )
      .put('https://api.box.com/2.0/files/' + file_id);

accessLog += "---PUT request--- "
    + response_update.getStatusCode() + "\n";
var updateResponseJson = response_update.getResponseAsString() + "\n";
var update_file_obj = JSON.parse(updateResponseJson);
engine.setDataByNumber(dataIdF, update_file_obj.shared_link.download_url);

// for Debug
accessLog += updateResponseJson + "\n";

if( dataIdX !== "" ){
  engine.setDataByNumber(dataIdX,accessLog);
}

]]></script>


<icon>(略)</icon>

</service-task-definition>

 

このファイルの大きな構成は、次のとおりです。

 

  • <configs>…</configs> (14〜43行)でアドオンの処理に必要な設定項目に関する定義を記述。
    • ダウンロード期限、パスワードを設定
    • ダウンロード URL を取得
  • <script>…</script>(45〜128行)で処理内容を記述。

 

アドオンの設定項目の定義

 

<configs>…</configs> (14〜43行)では、アドオンの処理に必要な設定項目に関することを記述します。具体的には、主に前述した入力(INPUT)に関することを <config> 要素を使って定義します。

 

記述した内容とアドオンの設定画面(プロパティ画面)の関係を次の図に示します。細かい記述は 使い方 を参考にしていただければと思いますが、どのような記述がどのような画面になるのか分かっていただけると思います。

 

 

アドオンの処理

 

<script>…</script>(45〜128行)で、アドオンが行う処理の内容を javascript で記述します。

 

49〜55行では、アドオンの設定画面で設定された内容を取得しています。例えば、アドオンの設定画面の一つ目の項目「A: OAuth2通信許可設定名」で入力された文字列を、oauth という変数にセットしています。

 

 

(1), (2), (3) については、アドオンの設定画面で設定したプロセスデータ項目が何であるのかを取得し、その後にワークフローの処理の中でプロセスデータ項目に入力された値を取得しています。

 

  • (1) Box にアップロードするファイルを files にセット
  • (2) ダウンロード期限の値を download_limit にセット
  • (3) ダウンロードパスワードの値を download_password にセット

 

69〜88行はファイルをアップロードする処理を記述しています。「Box API (Upload File) について」で説明した Box の API にアクセスする処理が書かれています。

 

 

98〜105行では、アップロードしたファイルにダウンロード期限、ダウンロードパスワードを JSON オブジェクトとしてセットする準備を行っています。

 

 

107〜119行で、アップロードしたファイルにダウンロード期限とダウンロードパスワードを設定しています。「Box API (Update File Info) について」で説明した、Box の API にアクセスする処理が書かれています。

 

 

開発したアドオンの概要についての説明は以上となります。細かい記述については、使い方 を参照していただければと思います。

 

このまま、作成したアドオンを使うところまで説明したいところなのですが、かなり長い記事になってしまったため、アドオンの利用に関する説明は次の記事に書くこととします。

 

今回はここまで!


参考

 

YAHAGI Hajime の紹介

幸せを生み出すITを追求するクエステトラの一味です。 国産の BPM ソフト Questetra BPM Suite で日本・世界を幸せにしたい。
YAHAGI Hajime の投稿をすべて表示

あわせて読みたい
55.カイゼン Tips の前の記事 見積承認フローの改善奮闘 – 安全なファイルの提出(処理画面の作成) –
55.カイゼン Tips の次の記事 見積承認フローの改善奮闘 – 安全なファイルの提出(動作確認) –
YAHAGI Hajime の他の記事 BPMフォーラム2013 ハッピでプレゼン編

アーカイブ

 RSS