ワークフローから外部システムを操作しよう(課題起票編)

ここまでは GitHub から情報を読むだけでした。この記事からは書き込みに進みます。受け付けた改善要望を、GitHub の課題として自動で起票します。

読み取りと書き込みでは、リクエストの組み立て方が違います。

前回:第 2 回 情報取得編 — 業務データを乗せて GitHub から取ってくる

この回で作る工程

第 2 回までに作った流れの後ろに、次の工程を足します。

  • [データ更新]— リクエストボディに入れる JSON を組み立てます
  • [メッセージ送信中間イベント (HTTP)]— GitHub に課題を起票します(POST)

ヒューマンタスクは増えません。第 2 回で置いた「重複の確認」の後ろに、この回の工程を足します。

この回で追加するデータ項目

この回では、データ項目を 3 つ追加します。

  • 「要望の件名」(q_request_title、文字 (単一行))— 処理担当者が入力します
  • 「要望の内容」(q_request_detail、文字 (複数行))— 処理担当者が入力します
  • 「リクエストボディ」(q_request_body、文字 (複数行))— 組み立てた JSON を保持します

このほかに、第 2 回で用意した「要望の分類」(q_request_label)も使います。受け付けのときに処理担当者が選んだ分類を、そのまま起票する課題のラベルにします。

ここまでに用意したデータ項目と、各ヒューマンタスクでの編集の可否は次のとおりです。

工程を通る順に並べています。末尾は、通信のために使う裏方のデータ項目です。

フィールド名データ項目名データタイプ追加した回受け付けた要望の記録重複の確認
q_repoリポジトリ選択第 2 回編集可表示のみ
q_request_label要望の分類選択第 2 回編集可表示のみ
q_request_title要望の件名文字 (単一行)第 3 回編集可表示のみ
q_request_detail要望の内容文字 (複数行)第 3 回編集可表示のみ
q_request_bodyリクエストボディ文字 (複数行)第 3 回表示なし表示なし
q_responseレスポンス文字 (複数行)第 1 回表示なし表示のみ
q_errorエラー内容文字 (複数行)第 1 回表示なし表示のみ

「リクエストボディ」は[データ更新]が組み立てる中間データなので、フォームには出しません。送信がうまくいかないときだけ、一時的に「表示のみ」にして中身を確かめます。

うまくいかない書き方

工程のプロパティを開き、HTTP Method の欄を見てください。POST を選ぼうとすると、いくつかの選択肢が並んでいます。POST のうち、先頭にあるのは POST (application/x-www-form-urlencoded) です。

[HTTP Method]に並ぶ選択肢は、次の 7 つです。POST だけで 3 つあります。

  • GET
  • POST (application/x-www-form-urlencoded)
  • POST (multipart/form-data)
  • POST (リクエストボディを指定)
  • PUT (リクエストボディを指定)
  • PATCH (リクエストボディを指定)
  • DELETE

この形式は、Web ブラウザのフォームが送信するときの形です。[送信パラメータ]タブに title と body を並べて書けば、これで送れそうに見えます。

しかし、これで送っても GitHub は課題を作ってくれません。GitHub をはじめ、最近の多くのサービスは、送られてくる内容が JSON という形式で書かれていることを前提にしているためです。フォームの形では解釈できません。

このとき「レスポンス」のデータ項目は空のままで、「エラー内容」のデータ項目に次のような内容が入ります。

レスポンスコードが 2XX ではありません。
[レスポンスコード] 400
[レスポンス]
{"message":"Problems parsing JSON","documentation_url":"https://docs.github.com/rest/issues/issues#create-an-issue","status":"400"}

Problems parsing JSON、つまり「JSON として読もうとしたが読めなかった」という返答です。GitHub がこのリクエストを JSON として解釈しようとしていることが、返ってきた内容からも分かります。

外部のサービスと連携するときは、相手のドキュメントを読んで、送るべき形式がどちらなのかを最初に確かめてください。

JSON の組み立て

JSON は[データ更新]で組み立てられます。スクリプトを書く必要はありません。

[メッセージ送信中間イベント (HTTP)]の手前に[データ更新]を置き、「リクエストボディ」(q_request_body)に次のような式を設定します。

{
  "title": "#{#escaper.escapeJson(#q_request_title)}",
  "body": "#{#escaper.escapeJson(#q_request_detail)}",
  "labels": ["#{#escaper.escapeJson(#q_request_label?.get(0)?.value)}"]
}

形そのものは、そのまま書いてしまって構いません。可変にしたいのは値の部分だけです。

labels に渡しているのは、「要望の分類」の選択肢 ID です。第 2 回で、GitHub のラベル名(enhancement など)を選択肢 ID 側に、日本語を表示ラベル側に入れておきました。GitHub が受け取れるのは前者なので、?.get(0)?.value と書いて選択肢 ID を取り出します。選択型のデータ項目は複数選択にも対応しているため、選ばれた選択肢のリストとして扱われます。.value だけでは取り出せません。

先頭の ? は、まだ何も選ばれていない場合に式全体を空にするための記述です。「要望の分類」は必須にしてあるので実行時に空になることはありませんが、それでもこの ? は省けません。工程の設定を保存する時点で設定バリデーションのエラーになるためです。設定のチェックは、データ項目が空の状態で行われます。

これで、第 2 回で重複の確認に使った分類が、そのまま起票時のラベルになります。処理担当者が「不具合」を選んだケースなら、bug のラベルが付いた課題が作られます。

値を埋め込むときは escapeJson を必ず通してください。これを使わず #{#q_request_title} とだけ書くと、処理担当者が要望の内容に引用符や改行を入れたときに、JSON の構造が壊れます。

escapeJson は、値に含まれる引用符・改行・タブなどを、JSON の中に置いても安全な書き方に変換してくれます。外から入ってくる値を JSON に埋め込むときは、必ず通してください。

同じ考え方の関数として、escapeXml、escapeHtml、escapeMarkdown なども用意されています。埋め込む先の形式に合わせて使い分けます。

送信の設定

[メッセージ送信中間イベント (HTTP)]の設定に戻ります。

アクセス URL は、課題を作る先のリポジトリです。リポジトリの部分は、第 2 回と同じく「リポジトリ」の選択肢 ID を差し込みます。

https://api.github.com/repos/yourname/#{#q_repo?.get(0)?.value}/issues

HTTP Method には POST (リクエストボディを指定) を選びます。すると[リクエストボディとして送信するデータ項目]の欄が現れるので、先ほどの「リクエストボディ」を指定します。

続けて[リクエストボディの Content-Type]の欄が現れますが、こちらは application/json が既定で入ります。GitHub が求めているのもこの形式なので、そのままで構いません。

[ヘッダ]タブの設定は第 1 回のままで構いません。[使用する認証設定]に「GitHub 練習用」を選び、Accept と X-GitHub-Api-Version の 2 つを添えます。

動作の確認

ケースを開始し、要望の件名と内容を入力して「受け付けた要望の記録」を処理し、続いて「重複の確認」も処理してください。工程を通過すると、GitHub のリポジトリに課題が 1 件増えているはずです。

「レスポンス」のデータ項目には、作られた課題の情報が入っています。

{
  "number": 2,
  "title": "検索結果の表示件数を増やしたい",
  "state": "open",
  "html_url": "https://github.com/yourname/workflow-practice/issues/2",
  ...

このうち number と html_url は、この後の回で使います。number は課題を後から操作するための番号、html_url は処理担当者に知らせるためのリンクです。

課題ができない場合、「レスポンス」のデータ項目には何も入りません。代わりに「エラー内容」のデータ項目に、返ってきたステータスコードと GitHub からの応答本文が保存されます。422 が返っているなら、送った JSON の中身に問題があります。escapeJson の付け忘れや、閉じ括弧の過不足が考えられます。「リクエストボディ」のデータ項目は、手前の工程で組み立てた時点で保存されているので、送信に失敗した後でも中身が残っています。フォームに表示させて確認してください。

次回

課題を作れるようになりました。次回は、作った後です。進捗をコメントとして書き込み、対応が終わったらワークフローの側から課題を閉じます。

第 4 回 更新・削除編 — 作った課題を後から操作する(近日公開予定)

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む