

準備編では、Questetra BPM Suite から GitHub ワークフローを起動できるところまで作りました。起動のリクエストで判るのは「実行が始まった」ことだけで、結果は判りません。
この記事では[受信タスク (HTTP)]を置いて、GitHub ワークフローの実行結果を受け取ります。受け取ると同時に、ケースは次の工程へ進みます。
この記事は連載「外部システムからの連絡でケースを進めよう」(全 4 回)の第 2 回です。
前回:準備編
2 つの受信タスクの使い分け
外部システムから HTTP リクエストを受けて進む工程は 2 種類あります。
| [受信タスク (HTTP)] | [受信タスク (Webhook)] | |
|---|---|---|
| 受け取り方 | POST のパラメータ | リクエストボディをそのまま |
| ケースの特定 | POST のパラメータ processInstanceId | 受信 URL のパス(ケースごとに異なる) |
| 成功時の応答 | HTTP 200(本文なし) | 業務データを差し込んだ応答を返せる |
| API キー | 工程に設定する固定値(全ケース共通) | データ項目の値。固定にも、ケースごとに変えることも可能 |
| 選ぶ場面 | 送信する側を自分で用意できる | 送る形式を変えられない、または相手が応答を必要とする |
この記事で扱うのは[受信タスク (HTTP)]です。送信する側(この記事では GitHub ワークフロー)を自分で書けるので、パラメータの名前をこちらの都合に合わせられます。[受信タスク (Webhook)]は返答編で説明します。
この記事で足す工程
準備編で作ったアプリの、[メッセージ送信中間イベント (HTTP)]と[終了イベント]の間に 3 つ足します。
- [受信タスク (HTTP)]「ビルド結果の受信」
- [分岐 XOR ゲートウェイ]「成功か失敗か」
- ヒューマンタスク「リリースの承認」
[分岐 XOR ゲートウェイ]には、「ビルド結果」が success という条件の経路を 1 本置き、「リリースの承認」へつなぎます。既定の[その他]の経路は[終了イベント]へつなぎます。ビルドが失敗(failure / cancelled)したケースを承認に進める必要はありません。
受け取る値を入れるデータ項目も 2 つ追加します。次の表の「第 2 回」の行です。上から、受信で埋まる項目、通信のために使う裏方の項目の順に並べています。[受信タスク (HTTP)]では、受け取るデータ項目を「編集可」にします。
| フィールド名 | データ項目名 | データタイプ | 追加した回 | リリース申請 | ビルド結果の受信 | リリースの承認 |
|---|---|---|---|---|---|---|
| q_result | ビルド結果 | 文字 (単一行) | 第 2 回 | 表示なし | 編集可 | 表示のみ |
| q_log_url | 実行ログ URL | 文字 (単一行) | 第 2 回 | 表示なし | 編集可 | 表示のみ |
| q_dispatch_body | 起動リクエストボディ | 文字 (複数行) | 第 1 回 | 表示なし | 表示なし | 表示なし |
| q_error | 起動エラー内容 | 文字 (複数行) | 第 1 回 | 表示なし | 表示なし | 表示なし |
「ビルド結果」には、実行中は running、終了時は job.status の値(success / failure / cancelled)が入ります。どちらのデータ項目も、承認する人が見るための値なので「表示のみ」です。
受け取る前に必要な設定
Questetra BPM Suite は、初期状態では[受信タスク (HTTP)]と[受信タスク (Webhook)]あての HTTP リクエストを外部からすべて拒否します。許可は[システム設定]>[IPアドレス制限]で登録します。この設定を行えるのはシステム管理権限を持つアカウントです。ワークフローアプリを作成できる権限とは別なので、権限がない場合はシステム管理者に依頼します。
登録するのは[メッセージ開始イベント/受信タスク設定]の 1 行です。
- [パスプレフィックス]— 選択肢[受信タスク (HTTP) – 特定ノード]を選ぶと
/System/ReceiveTask/HttpPost/(processModelInfoId)/(nodeNumber)/の形で入るので、括弧の部分を受信 URL のアプリ ID とノード番号に置き換えます。開けるのはこの工程だけにし、全アプリや特定アプリの単位で開けないでください - [接続が許可されているネットワーク]—
0.0.0.0/0
GitHub Actions の送信元は絞れません。GitHub が公開している実行環境の IPv4 範囲は 5,000 件を超え(2026 年 9 月時点)、1 行に登録できるネットワークは 100 件までです。そのためこの工程はすべての外部ネットワークに開き、受信 URL を守るのは API キーだけになります。API キーは推測されにくい値にし、受信 URL と API キーを記録に残さないよう扱ってください。送信元を絞れる相手なら、0.0.0.0/0 の代わりにその範囲を CIDR 表記(IPv4 のみ)で列挙します。
保存すると、工程のプロパティ画面の[受信パラメータ、IP アドレス制限]を押すと開く画面の[接続が許可されているネットワーク]に、登録した値が表示されます。画面の操作は「IPアドレス制限を設定する」で説明しています。
[受信タスク (HTTP)]の設定
ワークフローアプリに[受信タスク (HTTP)]を配置し、受け取る値を決めます。
API キー — 受信 URL に付ける鍵です。任意の値を設定するか、自動生成させます。半角英数で最大 100 文字です。工程に設定する値なので、全ケースで共通です。ケースごとに変えたい場合は、返答編の[受信タスク (Webhook)]を使います。
受信パラメータ — 工程に受信パラメータを登録する欄はありません。この工程の[編集の可否]で「編集可」にしたデータ項目が、そのフィールド名のパラメータで受け取れます。この記事では次の 2 つを受け取ります。
| パラメータ名 | 書き込み先のデータ項目 | 内容 |
|---|---|---|
q_result | 「ビルド結果」 | job.status の値(success / failure / cancelled) |
q_log_url | 「実行ログ URL」 | GitHub ワークフローの実行ページの URL。「途中経過だけを書き込む」の節で埋めます |
受信パラメータの名前は、値を書き込むデータ項目のフィールド名と同じにします。フィールド名は q_ で始めるので、送信する側もその名前で送ります。
受け取るデータ項目は、この工程で「編集可」に設定します(演算式設定を持つ数値型のデータ項目は、この設定を選べません)。
受信 URL — 工程のプロパティ画面から確認できます。次の形式です。
https://{ドメイン}/System/ReceiveTask/HttpPost/{アプリID}/{ノード番号}/receive?key={APIキー}
受信 URL をデータ項目に組み立てて外部へ渡すときは、ドメインの部分をシステム定数で書けます(${var[applicationRoot]}System/ReceiveTask/HttpPost/{アプリID}/{ノード番号}/receive)。ドメイン名を設定に埋め込まずに済みます。${…} はシステム定数の記法で、#{…} の SpEL 式とは別のものです。${var[applicationRoot]} は https:// から末尾のスラッシュまでを含むので、続けて書くパスの先頭にスラッシュは付けません。
[受信タスク (Webhook)]の受信 URL については、返答編で説明します。
API キーは、URL のクエリ文字列 ?key= でも、POST のパラメータ key でも渡せます。この記事の例では、URL とキーを別々に保管できるようパラメータで送ります。ケース ID は、受信のリクエストでは POST のパラメータ processInstanceId で渡します。
リクエストは POST です。application/x-www-form-urlencoded または multipart/form-data で送ります。成功すると HTTP 200 が返りますが、応答の本文はありません。失敗した場合は 400 番台のステータスコードが返ります。
ケースを特定する processInstanceId
受信 URL に含まれるのは、アプリ ID とノード番号までです。どのケースかは URL に現れません。同じ工程で待っている何件ものケースが 1 つの URL を共有するので、どのケースを進めるのかをリクエストに含める必要があります。それがパラメータ processInstanceId です。
curl https://example.questetra.net/System/ReceiveTask/HttpPost/1234/5/receive \
-d "processInstanceId=456" \
-d "key=XYZXYZ" \
-d "q_result=success"
外部システムは、自分が処理しているのがどのケースの依頼なのかを覚えておく必要があります。処理を投げるときにケース ID を渡し、折り返すときに返してもらう、という往復です。準備編で inputs にケース ID の欄を用意したのは、このためでした。
GitHub ワークフローの最後で折り返す
準備編で作った release-check.yml の check ジョブの最後に、Questetra BPM Suite へ結果を送るステップを足します。ここではステップだけを抜き出しています。ファイル全体は、この記事で足すものが揃ったところで再掲します。
- name: 結果を Questetra BPM Suite へ折り返す
if: always()
run: |
curl -sS --fail-with-body -X POST "${{ secrets.QUESTETRA_RECEIVE_URL }}" \
-d "key=${{ secrets.QUESTETRA_API_KEY }}" \
-d "processInstanceId=${{ inputs.case_id }}" \
-d "q_result=${{ job.status }}"
if: always() を付けています。 これがないと、テストが失敗した時点で GitHub ワークフローが打ち切られ、折り返しのステップが実行されません。ケースは待ち続けることになります。失敗したことも連絡してもらう必要があります。
受信 URL と API キーは、リポジトリのシークレットに登録します。 シークレットの値はログに出ても伏せ字になりますが、inputs で渡した値は伏せられません。API キーを inputs で渡してはいけません。リポジトリの[Settings]>[Secrets and variables]>[Actions]で、次の 3 つを登録してください。3 つ目は、このあとの「折り返しが早すぎるとき」で使います。この画面には[Repository secrets]と[Environment secrets]の 2 つの欄があります。ここでは[Repository secrets]に登録します。[Environment secrets]は、ジョブに environment: を指定したときだけ参照できるので、指定していないこの記事のジョブからは読めず、${{ secrets.… }} が空になります。Organization のリポジトリでは、Organization 側で共有するシークレットもあります。
| シークレット名 | 登録する値 |
|---|---|
QUESTETRA_RECEIVE_URL | 受信 URL の ?key= より前まで(https://…/receive) |
QUESTETRA_API_KEY | API キーの値 |
QUESTETRA_CHECK_URL | 受信 URL の /receive を /receive/check に変え、?key= より前まで |

途中経過だけを書き込む
処理に時間がかかる場合、完了を待たずに途中経過だけをケースに書き込みたいことがあります。パラメータに saveOnly=true を加えると、データ項目への書き込みだけが行われ、トークンは工程に留まります。必須チェックも行われません。タスク処理での[保存して中断]と同じ動作です。
実行ログの URL は、GitHub ワークフローが始まった時点で判ります。最初のステップで先に送っておけば、実行中のケースからログを開けます。あわせて「ビルド結果」にも running を入れておきます。check ジョブの先頭に、次のステップを足します。
- name: 実行中であることを先に知らせる
run: |
curl -sS --fail-with-body -X POST "${{ secrets.QUESTETRA_RECEIVE_URL }}" \
-d "key=${{ secrets.QUESTETRA_API_KEY }}" \
-d "processInstanceId=${{ inputs.case_id }}" \
-d "saveOnly=true" \ -d "q_result=running" \
-d "q_log_url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
running は、job.status が返す値のどれとも重ならない値にしています。 「ビルド結果」が running になっていれば、ケースを開いた人は「起動は届いていて、まだ実行中」だと判ります。この値は最後の折り返しで上書きされます。同じデータ項目に何度書き込んでも構いません。
この呼び出しではトークンは進みません。工程を通過するのは、最後の折り返しのときです。
ただし、このステップは GitHub ワークフローの先頭で走ります。Questetra BPM Suite 側でトークンが[受信タスク (HTTP)]に届く前に、このリクエストが到着することがあります。次の節で対処します。
折り返しが早すぎるとき
[メッセージ送信中間イベント (HTTP)]が GitHub ワークフローを起動してから、トークンが[受信タスク (HTTP)]に届くまでには、わずかに時間がかかります。その前にリクエストが到着すると、工程はまだリクエストを受け付けられる状態にないので、400 番台のエラーになります。そのあとトークンが工程に届き、ケースは連絡を受け取れないまま待ち続けます。テストをまだ書いていない練習用のリポジトリでは GitHub ワークフローが数秒で終わるので、最後の折り返しでも起こり得ます。
受け取れる状態かどうかは、送る前に確かめられます。 受信 URL の /receive の後ろに /check を足した URL に問い合わせます。工程のプロパティ画面の[受信パラメータ、IP アドレス制限]を押すと開く画面に、「受信可否確認 API」として表示されます。この確認ではケース ID もクエリ文字列で渡します。
https://{ドメイン}/System/ReceiveTask/HttpPost/{アプリID}/{ノード番号}/receive/check?key={APIキー}&processInstanceId={ケースID}
確かめるのは、GitHub ワークフローが Questetra BPM Suite へ送る最初のリクエストの前だけで足ります。一度受け取れる状態になれば、トークンは最後の折り返しまでその工程に留まるので、後のリクエストで確かめ直す必要はありません。この記事では、受け取れる状態になるまで待つステップを独立させ、「実行中であることを先に知らせる」の前に置きます。
- name: 受信タスクが受け取れる状態になるまで待つ
run: |
for i in $(seq 1 30); do
if curl -sf "${{ secrets.QUESTETRA_CHECK_URL }}?key=${{ secrets.QUESTETRA_API_KEY }}&processInstanceId=${{ inputs.case_id }}"; then
exit 0
fi
echo "まだ受け取れないので 10 秒待ちます"
sleep 10
done
echo "受信タスクが受け取れる状態になりません"
exit 1
受け取れる状態なら成功の応答が返るので、curl -sf の成否でそのまま判定できます。API キーとケース ID は、どちらもクエリ文字列で渡します。例では 10 秒間隔で 30 回までとし、上限まで待っても受け取れる状態にならなければ exit 1 でステップを失敗させます。折り返す相手がいないまま処理を続けても意味がないので、ここで止めて気づけるようにします。ケースが取り消されていた場合も、この上限で GitHub ワークフローが終わります。
このステップが失敗すると、後続のステップは実行されません。最後の折り返しだけは if: always() を付けているので実行されますが、受け取る側がいないのでこれも失敗します。ジョブ全体が失敗として残るので、GitHub の実行一覧で気づけます。
この記事で足したものをすべて含めると、release-check.yml は次のようになります。
name: release-check
on:
workflow_dispatch:
inputs:
case_id:
description: Questetra BPM Suite のケース ID
required: true
type: string
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: 受信タスクが受け取れる状態になるまで待つ
run: |
for i in $(seq 1 30); do
if curl -sf "${{ secrets.QUESTETRA_CHECK_URL }}?key=${{ secrets.QUESTETRA_API_KEY }}&processInstanceId=${{ inputs.case_id }}"; then
exit 0
fi
echo "まだ受け取れないので 10 秒待ちます"
sleep 10
done
echo "受信タスクが受け取れる状態になりません"
exit 1
- name: 実行中であることを先に知らせる
run: |
curl -sS --fail-with-body -X POST "${{ secrets.QUESTETRA_RECEIVE_URL }}" \
-d "key=${{ secrets.QUESTETRA_API_KEY }}" \
-d "processInstanceId=${{ inputs.case_id }}" \
-d "saveOnly=true" \
-d "q_result=running" \
-d "q_log_url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
- uses: actions/checkout@v4
- name: テストの実行
run: echo "ここでビルドとテストを走らせます"
- name: 結果を Questetra BPM Suite へ折り返す
if: always()
run: |
curl -sS --fail-with-body -X POST "${{ secrets.QUESTETRA_RECEIVE_URL }}" \
-d "key=${{ secrets.QUESTETRA_API_KEY }}" \
-d "processInstanceId=${{ inputs.case_id }}" \
-d "q_result=${{ job.status }}"
送信する側を変えられないときは、ワークフローアプリ側で受け止めます。 相手が外部サービスで、送る前の確認や再試行を組み込めない場合です。[分岐 AND ゲートウェイ]で起動と待ち受けを並列に置き、送信の経路に[タイマー中間イベント]を入れて送信を遅らせます。分岐した時点で待ち受けの経路にトークンが置かれ、さらに送信が遅れるので、折り返しは間に合います。
並列にするときの注意が 2 つあります。ひとつは、送信が失敗すると待ち受けの経路にトークンが残り続けることです。締め切りを設定しておいてください。締め切りの設定の仕方は、締め切り・エラー対処編で説明します。もうひとつは、2 つの経路が同じデータ項目に書き込まないようにすることです。
うまくいかないときの確認
リクエストを送ったのに工程が進まない場合、まず次を確認してください。
- [IPアドレス制限]で送信元が許可されているか(「受け取る前に必要な設定」の節)
processInstanceIdが、いま待っているケースの ID と一致しているか- 必須の設定になっているデータ項目が、送ったパラメータで埋まっているか
- 工程を進めたいリクエストに
saveOnly=trueが残っていないか(付いていると、成功の応答が返ってもトークンは進みません)
折り返しの curl に --fail-with-body を付けておくと、受信が失敗したときに GitHub ワークフローのステップも失敗し、応答の本文がログに残ります。これがないと、Questetra BPM Suite が受け取れていなくても GitHub ワークフローは成功として終わるので、送った側からは気づけません。
原因の切り分け方は、締め切り・エラー対処編で説明します。
連載・参考
連載「外部システムからの連絡でケースを進めよう」
- 準備編
- 折り返し編(この記事)
- 返答編
- 締め切り・エラー対処編
参考


