簡単なサービスならQuestetraですぐに作って提供できる（API利用フロー）

#🔷 はじめに

**「○○ができるサービスを作ってください。」**

処理で言うと、「あるAPIにリクエストを投げる」というだけのサービスなのに、業務で使うとなると、サービスとしてキッチリしたものを求められます。

ログイン機能、ユーザー管理、権限管理、etc、これらを自分で作るとなると結構な手間になります。

しかし、[Questetra BPM Suite](https://questetra.com/ja/)を使えば簡単なサービスをすぐに作る事ができます。

###🔶 Questetra BPM Suite

https://questetra.com/ja/

> Questetra BPM Suite は、クラウド型の 業務プロセス管理システム (SaaS BPMS) です。
> 様々な業務システム（ワークフローアプリ）をノンプログラミングで開発・運用・監視できます。 日常業務のデジタル化・自動化を推進できます。 （DX 支援ツール、ワークフローオートメーションツール）

 Questetra BPM Suite（以下、Questetra）はノンプログラミングでワークフローアプリを作れるサービスです。
メインはワークフロー機能ですが、付随してログイン機能、ユーザー管理、権限管理、etc、様々な機能が用意されています。

しかも、**プランも無料からあります。**
（ただし、無料のプランは2週間ログインが無いと削除されます）
<img width="1190" alt="001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/2c136a88-df9d-9fd8-ba77-c133540b807e.png">

#🔷 今回作るもの

今回作るのは、「業務処理を開始するAPI」にリクエストを投げて、APIで業務処理が終わったら完了を伝えるアプリです。
その中で、実際に作る部分は**業務フローとAPIです。**
![101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/f3fe0425-6b24-ad05-23b7-a7c0e6439539.png)
**上図フローのオブジェクトの説明**

1. フロー開始を、担当者が確認する。
1. 6のオブジェクトにあるwebhookの、URLを生成する。
1. 業務処理を行う外部APIにリクエストを投げる。
1. 今回はAPI Gatewayでリクエストを受ける。
1. 業務処理をLambdaで行い、処理が終わった合図として、Questetraのwebhookにリクエストを投げる。
1. 外部APIから、業務処理完了の合図のリクエストを受ける。
1. フロー完了を、担当者が確認する。


#🔷 業務フローの作成

###🔶 準備

最初に、Questetraのスタータープランの申込みを行います。
これは無料で使えるプランで、申込み後、すぐに試せる環境の案内がメールで送られます。

https://questetra.com/ja/pricing/

案内メールの中に、ログインURL、ID、PWが記載されているので、管理者としてログインします。
<img width="529" alt="102.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/635fbae3-0334-06cd-94d8-d8a10dd735c4.png">

この時点で、ログイン機能が実現できている事が分かります。
今回は詳しく触れませんが、このQuestetraの環境に対して、ユーザー追加したり、組織構造を定義して、権限を付与する事が可能です。


###🔶 アプリの作成

Questetraのアプリの作り方は、オフィシャルサポートサイトでも紹介されています。
今回は以下を参考にアプリを作ります。

* [Chapter 2: 簡単なアプリを作ってみる](https://support.questetra.com/ja/developer-blog/first-questetra-bpm-suite-step2/)
* [ワークフローの途中で、自動的に電話をかける](https://support.questetra.com/ja/developer-blog/receive-task-webhook-twilio/)

ただ、Quetetraは一般的な製品マニュアルのような、製品について1から10まで全て記載したドキュメントはまだ無く、ブログやユースケースの紹介のような形のドキュメントしかありません。
初めて触る人には情報が足りないところもあるので、補足しながら説明します。

####✅ アプリの新規作成

Questetraにログインしたら、右上のユーザー名をクリックして、[アプリ設定] → [アプリ一覧] → [アプリ新規作成] をクリック。

<img width="1010" alt="201.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/7211c680-0b55-25dc-bf82-1eb0eb61da7b.png">

アプリ新規作成画面に遷移したら、アプリ名等を入力して、[新規作成]ボタンをクリックします。
<img width="1009" alt="202.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/39156867-c22c-c1e4-5e1b-451496bff23a.png">

ワークフロー作成画面に遷移します。
（Adobe Flashは有効にしないと起動しません）
<img width="1009" alt="203.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/a764f976-1dd8-7b59-33e6-c91a5240bc10.png">

####✅ データ項目の作成

まずは、このワークフローで使用するデータ項目を、あらかじめ設定しておきます。

画面上部の[データ項目]タブをクリックします。
画面左エリアの[追加]プルダウンをクリックして、データ項目を追加します。
<img width="1011" alt="204.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/cdfbf88c-29eb-cfe0-ba9b-b537ba266469.png">
追加するデータ項目は以下の通りです。
何に使うかは後ほど説明します。

|  データ項名 | フィールド名 | データタイプ | 初期値 |
| :--- | :--- | :---: | :---: |
|  件名 | `title` | 文字、単一行 | "確認イベント" |
|  リクエスト時エラー格納用変数 | `q_error` | 文字、複数行 | （なし） |
|  APIキー | `q_api_key` | 文字、複数行 | （なし） |
|  callback用 Webhook url | `q_callback_url` | 文字、単一行 | （なし） |
|  リクエストボディ | `q_req_body` | 文字、複数行 | （なし） |
|  レスポンス格納用変数 | `q_response` | 文字、複数行 | （なし） |
|  外部API | `q_api_endpoint` | 文字、単一行 | (リクエストする外部APIのURL) |
※フィールド名は"q_"で開始するように命名すること

####✅ ワークフローの作成

[ワークフロー図]タブをクリックして、最初の画面に戻ります。

左エリアの[advance]タブをクリックします。
細かい設定は後にして、まずは以下のようにオブジェクトを配置します。
配置も矢印の接続も、ドラッグ＆ドロップでできます。
<img width="1010" alt="205.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/d3473b68-1dd7-b1d4-1257-94a701463f52.png">

個別にオブジェクトをダブルクリックして、以下のように設定します。

⬛開始
（デフォルト設定）

⬛処理開始の確認
（デフォルト設定）

⬛分岐
（デフォルト設定）

⬛webhook url 生成
QuestetraのwebhookオブジェクトのURLを生成します。
webhookのURLが固定であれば問題ないのですが、URLの一部は、フローを実行する度に動的に生成される値であるため、フローの中で生成します。
<img width="555" alt="206.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/ae227f8a-f2f9-0110-65c3-a1df7c8f7173.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
|  値もしくは式の評価を保存するデータ項目 | callback用 Webhook url | 設定した左記のデータ項目を選択します。 |
|  値もしくは式 | ${var[applicationRoot]}System/ReceiveTask/Http/4/14/#{processInstanceId}/#{#q_api_key}/receive | フロー処理の中で、「callback用 Webhook url」に本URLがセットされます。 |

* 上記で使用されている特別なパラメータの意味は以下の通りです・
   * `${var[applicationRoot]}`：本フローの実行環境のベースURLがセットされます。
   * `#{processInstanceId}`：フロー処理が開始される度に生成される、プロセスIDがセットされます。
   * `#{#q_api_key}`：先程設定した、フロー処理が開始される度に生成される、「APIキー」の値がセットされます。

⬛APIリクエスト処理
外部APIにリクエスト投げるオブジェクトです。

[通信設定]タブで、リクエスト先のAPIの情報を設定します。
<img width="806" alt="207-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/ef52c266-eca1-037c-8970-4c3cab2e083b.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
|  アクセスURL | #{#q_api_endpoint} | [データの参照を挿入する...]プルダウンをクリックして、先程設定した左記のデータ項目を選択します。 |
|  HTTP Mthod | GET | 今回の外部APIはGETメソッドのAPIなので、「GET」を選択します。 |
|  エラー内容を保存するデータ項目（文字複数行） | APIリクエスト時エラー格納用変数 | 設定した左記のデータ項目を選択します。 |

[送信パラメータ]タブで、リクエスト時のクエリストリングを設定します。
<img width="805" alt="207-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/39631333-1d2e-65cb-0d27-29e030cc4362.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
|  パラメータ名 | param | 任意の名称を設定します。 |
| 値 | callback用 Webhook url | 設定した左記のデータ項目を選択します。 |

* この設定で、「https://(外部API)?param=https://(webhookのURL)」のようなリクエストパスになり、**webhookのURLを外部APIに渡せるようにします。**

[レスポンス]タブで、レスポンスの格納先を設定します。
<img width="806" alt="207-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/a2d4b23a-7b23-818e-f24d-8c969801ff04.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
| レスポンスを保存する | チェック | （なし） |
| レスポンスを保存するデータ項目（文字複数行/ファイル） | レスポンス格納用変数 | 設定した左記のデータ項目を選択します。 |

* フロー処理上は使用しないですが、レスポンスの格納先として、データ項目の「レスポンス格納用変数」を選択します。


⬛終了（上）
　→ デフォルト設定でOK

⬛トリガー用webhook
外部APIで業務処理が完了したら、完了の合図としてのリクエストを受けるwebhookのオブジェクトです。

[リクエスト]タブで、webhookを設定します。
<img width="808" alt="208-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/b1f6adad-dedf-8481-0aff-6bee8f8351c7.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
| 受信するHTTPリクエストのメソッド | GET | （なし） |
| 受信するHTTPリクエストのContent-Type | application-json | （なし） |
| リクエストボディ保存先の文字型データ項目 | リクエストボディ | 設定した左記のデータ項目を選択します。 |

* フロー処理上は使用しないですが、リクエストボディの格納先として、データ項目の「リクエストボディ」を選択します。

[レスポンス]タブで、外部APIに返すレスポンスを設定します。
<img width="806" alt="208-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/55977eaf-a755-4f3b-f344-6c608715b48e.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
| HTTPレスポンスのContent-Type | application-json;charset=UTF-8 | （なし） |
| HTTPレスポンスの内容 | {"result": "Request to webhook is successful !"} | （なし） |

[APIキー]タブで、APIキーの格納場所を設定します。
<img width="805" alt="208-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/3be34690-6906-ba4f-e205-569b751d8f97.png">

|  設定項目 | 設定値 | 備考 |
| --- | --- | --- |
| APIキーの値を指定する文字型データ項目 | APIキー| 設定した左記のデータ項目を選択します。 |

* 外部APIが、webhookへのリクエスト時に含めるAPIキーと突き合わせる、正解となるAPIキーの格納先として、データ項目の「APIキー」を選択します。

⬛処理完了の確認
　→ デフォルト設定でOK

⬛終了（下）
　→ デフォルト設定でOK

設定が完了したら、画面右上の[保存]ボタンをクリックして保存し、[閉じる]ボタンをクリックして閉じます。
<img width="1009" alt="209.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/85166ff2-1641-9e3d-6156-8700da5a9685.png">

アプリ詳細画面に遷移するので、最後に[開発中のバージョン1のリリース]ボタンをクリックします。
<img width="1012" alt="210.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/956fd052-2792-18d6-c5ac-a4ff0e52ad32.png">

これで、作成したフローが実行できるようになります。
#🔷 APIの作成

業務処理役のAPIを作成します。
今回は、API GatewayでQuestetraからのリクエストを受け取り、Lambdaで業務処理を行ったとして、処理の中でwebhookにGETリクエストを投げます。

webhookのURLは、リクエストのクエリストリングにセットされているものを使います。

Lambdaのサンプルソースは以下になります。

```javascript:index.js
const https = require ('https');
const url = require('url');

exports.handler = async (event) => {
  let webhookUrl;
  if('param' in event.queryStringParameters) {
    webhookUrl = event.queryStringParameters.param; // クエリストリングparamの値を取得
    await requestToAPI(webhookUrl);
  }
  
  // リクエスト元へ返すレスポンス
  const response = {
    statusCode: 200,
    body: JSON.stringify(
      {
        "result":"Work is complete!",
        "webhook":String(webhookUrl)
      }),
  };
  return response;
};

function requestToAPI(webhookUrl) {
  console.log(`■□■□ requestToAPI : Questetraの受信Webhookにリクエストする処理 ■□■□`);

  return new Promise(
    (resolve, reject) => { 
      // TODO implement
      const parser = url.parse(webhookUrl);
      let req, body = '';
    
      const options = {
        host : parser.host,
        port : 443,
        path : parser.path,
        method : 'GET',
        headers : {
          'Content-Type' : 'application/json'
        }
      };
    
      /* webhookへのリクエスト */
      req = https.request(options, (res) => {
        res.setEncoding('utf8');
        /* レスポンスボディのデータ読み込み処理（dataイベント発生）*/
        res.on('data', (chunk) => {
          body += chunk;
        });
        /* 読み込むデータが無くなった時の処理（endイベント発生） */
        res.on('end', () => {
          if(res.statusCode == 200) {
            console.log('■□■□ レスポンス情報 ');
            console.log(body);
          } else {
            console.log('■□■□ レスポンス情報なし ');
          }
          resolve(body);
        });
      });
    
      req.on('error', (e) => {
        console.error(`problem with request: ${e.message}`);
        reject(body);
      });
      req.end();
  });
}

```

#🔷 テスト

**1. アプリを実行します。**

ヘッダーメニューの[ワークフロー]をクリックします。
<img width="1009" alt="301.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/5c4901e3-8e58-4228-3be3-f134bc9bf93a.png">

ブラウザの別タブに、ワークフロー画面が開かれます。

左メニューの[新規開始]をクリックすると、実行可能なアプリが一覧表示されます。
作成した「外部API利用サンプル」の実行ボタンをクリックして、アプリを実行します。
<img width="1142" alt="302.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/96b7b261-7725-4928-dd79-7aac81731c57.png">

**2. 「処理開始の確認」タスクを完了させます。**

業務フローの開始と共に、「処理開始の確認」というタスク画面が表示されます。
画面下部の[「処理開始の確認」処理完了]ボタンをクリックして、本タスクを完了させます。
<img width="1142" alt="303.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/5820f0af-19fe-505a-91d1-292090df2b7b.png">

これは、業務フローの以下のタスクに当たります。
<img width="806" alt="304.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/74a6779c-a91a-85d4-0af1-0d0beeb947c2.png">

**3. 外部APIで業務処理が完了するのを待ちます。**

業務フローでは、「APIリクエスト処理」タスクで外部APIにリクエストを投げ、「トリガー用webook」タスクで、外部APIから送られて来る、処理完了の合図のリクエストを待っているところです。
<img width="806" alt="305.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/1e8711e3-98fd-0702-7dfd-b472aa65312d.png">

**4. 「処理完了の確認」タスクを完了させます。**

業務処理が終わるまで少し待ってから、左メニューの[マイタスク]をクリックすると、対応すべきタスクが一覧表示されます。
「処理完了の確認」タスクの実行ボタンをクリックして、タスクを実行します。
<img width="1142" alt="306.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/06243b78-8c4b-0eb4-d25a-bbe3eef041d2.png">

[「処理完了の確認」処理完了]ボタンをクリックして、タスクを完了します。
<img width="1143" alt="307.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38099/7af1f852-76c2-e31a-7aa4-56523318cda7.png">


#🔷 まとめ

このようにQuestetraを使えば、ちょっとした処理を行うだけの、シンプルなサービスをすぐに作成する事ができます。
他にも、標準でユーザー管理、権限管理、ダッシュボードによる利用状況管理、等が揃っているので、アプリとしての提供もすぐに可能です。

また、業務フローツールなので、タスク割当、ファイル読み込み、PDF生成、等の様々な処理が可能で、さらに[アドオン](https://questetra.zendesk.com/hc/ja/articles/360010635012)を使えば、Googleサービス、Line、Paypal、等の外部サービスとの連携も容易に実現できます。

かっちりしたマニュアル無いので、ちょいちょい詰まる所もありますが、参考になる業務フローの[テンプレート](https://questetra.zendesk.com/hc/ja/articles/360012492211)も豊富ですし、無料プランでもサポートに[問い合わせ](https://questetra.zendesk.com/hc/ja/requests/new)れば回答してくれるので、気軽に使い始められます。

色々なタスクを試して、便利のフローを作って見てください。


#🔷 参考
[Questetra Support](https://support.questetra.com/ja/)
[BPMNアイコン](https://support.questetra.com/ja/category/bpmn-icons/)