LINE Bot＋Power Automateで家庭内DXを促進するお手軽購入申請 ~フロー詳細

前回→ [LINE Bot＋Power Automateで家庭内DXを促進するお手軽購入申請を作ってみた](https://qiita.com/h-nagao/items/e30e8b2f068a5af25897)

# 今回はPower Automateの詳細です
前回は、全体としてどのような構成にしていて、ユーザーがどんな操作をするのかご紹介しました。
今回はこのLINEでの購入申請のキモである、Power Automateのフローを細かく紹介します。

![image.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F202779%2F2a5cdc48-130b-220f-c573-632d60bd92ef.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&w=1400&fit=max&s=8da600a12f722da2bdf1189fa1fa614a)

# 準備 (SharePointとForms)
承認のステータスと履歴を管理するためのデータソースはSharePointリストにしています。それほど件数発生しない前提で、お手軽に用意でき、Excelのようなロックの問題も考えなくてよいので。

## Forms
Formsのフォームが購入申請をするきっかけ・入力部になります。
LINE側では、Office 365のログイン利用しないので、匿名で回答できるようにしておきましょう。

|項目|種類|備考|
|:--|:--|:--|
|申請者を選ぶ|選択肢|パパ/ママ|
|購入品名|一行テキスト||
|購入金額|一行テキスト|数値に限定する|
|商品URL|一行テキスト||
|備考|複数行テキスト||

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/093670e1-564e-bcaa-e211-4c6532a8abfb.png)


Formsの準備はこれだけです。
念のため、URLにあるFormのIDをメモしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/c77766ef-84f7-adc5-7fc2-45720610d2bd.png)

## SharePoint
SharePointリストは基本的にForms側の設定と同一にします。ただし、購入申請の結果を残しておきたいので、承認ステータスに該当する列を追加しておきましょう。

|列名|種類|備考|
|:--|:--|:--|
|Title|一行テキスト|購入品名を入れる|
|Requester|一行テキスト|申請者名|
|Price|通貨|購入金額を入れる。Numberでも可|
|URL|一行テキスト||
|Comment|複数行テキスト|書式なし|
|Status|一行テキスト|選択肢でもよい。その場合は申請済み/承認/却下|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/fa192f83-8c72-55c3-eac6-7d4dba57e281.png)

#Power Automate
準備ができましたので、ここからフローを紹介していきます。
なお、今回は以前作成したLINE Messaging APIのカスタムコネクターを利用しています。
詳細は[こちら](https://mofumofupower.hatenablog.com/entry/2020/05/15/165215)

## 申請受信→承認者への通知
Formsへの入力をトリガーとして、SharePointへのデータ登録と、承認者へのメッセージ送信・申請者への申請完了通知を送ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/937cf7e6-f6d2-c6e8-5cbb-3ff46cc20c4a.png)

短いです。Compose (作成アクション) でFlex messageの本体を作っていますが、そこそこ長いので、Githubのファイルを参考にしてください。
ポイントは以下の部分です。

```flexmessage.json

        "contents": [
          {
            "type": "button",
            "style": "primary",
            "height": "sm",
            "action": {
              "type": "postback",
              "label": "OKです",
              "data": "action=承認&id=@{body('Create_item')?['ID']}",
              "displayText": "OKです"
            }
          },
          {
            "type": "button",
            "style": "secondary",
            "height": "sm",
            "action": {
              "type": "postback",
              "label": "ダメです",
              "data": "action=却下&id=@{body('Create_item')?['ID']}",
              "displayText": "ダメです"
            }
          },
          {
            "type": "spacer",
            "size": "sm"
          }
        ]
```
承認者がOK/NGのボタンをタップしたときのアクションです。
ここでは通常のメッセージではなく、[Postbackアクション](https://developers.line.biz/en/reference/messaging-api/#postback-action)を利用しています。
Postbackアクションでは、チャットに表示されるメッセージの他に、データ ("data"部分)を要求として送ることができます。
これを利用して、SharePointに作成したどのアイテムのステータス更新なのかをLINE (Webhookを受け取るフロー)に教えてあげます。

後述するメッセージを受け取るフローでは、このデータをもとにして、SharePointからのアイテム取得、action=XXXX部分でのステータス更新を行っています。

また、申請者へのPushメッセージ送信で、Toですが、これはFormsの回答がパパなのかママなのかで送るユーザーIDを変更しています。

```
@{if(equals(body('Create_item')?['Requester'],'パパ'),'ここにパパのLINEユーザーID','ここにママのLINEユーザーID')}
```
こうすることで、申請者に応じてメッセージの飛ばし先を変更できます。
承認者へのPushメッセージは上の条件を逆にしてください。

これで1本目が完成です。

**Flex messageのJSONは以下に置きました**
https://github.com/mofumofu-dance/PowerApps365/blob/master/Samples/PurchaseRequestFlow/RequestMessage.json

## メッセージ処理全般
短い方でもおなか一杯かもしれませんが、こっからが本番です。
LINEボットをPower Automate使って作るときには、HTTP要求受信のトリガーを必ず利用します。

往々にして、処理は長くなります。送られてくるデータが、メッセージなのか、Postbackなのか、Stickerなのか。あるいは誰から送られてきたかなどなど。そういった判定が入るためです。

今回のフローでも、条件分岐をいくつか入れていますが、基本的には、メインの処理では最初から最後までフローのアクションが実行され、例外パターンでは、条件分岐の片方でフローを終了させています。
こうすることで以降の処理は実行されず、例外/想定外のパターンの処理ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/8f9abc8e-6a88-6b62-9e5b-eccac3c79a68.png)

### 1. Webhook受信～アイテムの検索
LINE上でのbotとの会話で、承認者側がOK/NGを押すか、「Id:XXXX/承認」のようにメッセージを打つことで、承認/却下が進むようにしています。ここでは、まずそれらのデータ/メッセージを分割してSharePointリストからアイテムを取得しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/8e7002e7-a79b-e9d3-e696-17651c9590d4.png)


条件分岐部分には

```
first(triggerBody()?['events'])?['postback']?['data']
```
が使われています。
eventsが配列になっていて、その0番目を使うので、```first(triggerBody()?['events'])``` **この組み合わせは頻出です。**

### 2. エラー対応x2
今回のフローでエラーがでるとすると、アイテムがない または （これはエラーではないけど）すでに承認/却下済み というケースかと思います。この2種に備えて、ステップを入れておきます。

エラーの対応は、実行条件でやるとなかなか良いという知見を得たので、それに倣って。

- SharePointのアイテム取得に失敗したら、「アイテムないよ」の返信を送ってフロー終了
- アイテムはあるけど、すでに承認/却下済み だったら「そのアイテムはすでにXXしているよ」の返信を送ってフロー終了

この２つを立て続けにやっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/87b7fabd-e7d3-b9be-7d86-4d9dadbb3254.png)

### 3. ステータス更新～結果報告

前段で処理が終了していないということは、アイテムが存在していて、かつ未処理であるとわかります。
ですので、ここでは対象のIDのアイテムをステータス更新して、結果を承認者にはReply、申請者にはPushで送っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/b67ad754-4882-70f0-8b0f-2116a2878f0c.png)

### 4. おまけ：一覧表の更新

最後はすこし面倒ですが、SharePointのアイテム一覧から、承認ステータスごとにHTMLのテーブルを作ってBlobストレージに保存するという処理です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/9a79eb94-4e31-a460-0393-94732ac83d5a.png)

例によって、HTMLが長いので省略しています。
ポイントは、
- まずリストからアイテムを複数取得
- ステータスが申請済み・承認・却下化に応じて並列処理
- Selectアクションで **["< tr > ~~~~~ </ tr > ",.....," < tr > ~~~~ </ tr > "]**のような配列を、文字列結合でつくる
- Joinを*null*で行って**< tr >**を結合 
- うまい具合にHTML作ってBlobに保存

です。
※HTML (Blobのコンテンツ)もGithubにサンプルとしておきました。ご自由にどうぞ
https://github.com/mofumofu-dance/PowerApps365/blob/master/Samples/PurchaseRequestFlow/ApprovalHistory.html

# まとめ
今回は家庭内のちょっと面倒なアナログプロセスを、LINE botとPower Automate、FormsでDXしてみました！
サービスに備わっている機能では賄うのが難しい場合には、いろいろなサービスを組み合わせることで、コードを書くことなしに不自由を補うことができます。

Power Appsにせよ、Automateにせよ、特定のサービスだけにこだわらず、いろいろ組み合わせて使えればもっと幸せかもです！
ご質問はTwitterまでお願いします。