チャネルのスレッドとSharePointリストを連携させる（更新フロー編）

# はじめに
この記事は①概要編 ②受付フロー編 ③更新フロー編 の3本立てのうち、③更新フロー編です。
今回で一連の解説は終わりになります。

https://qiita.com/ksgiksg/items/748e792f6a082ece33c6

https://qiita.com/ksgiksg/items/7c55ed74a74a668f3432

<details><summary>更新フローの全体図</summary>

![make.powerautomate.com_environments_Default-b794cd83-44cc-447c-856e-a27e55624c65_flows_a7c6df30-8ce0-4e3a-b20f-faca1c8a1936(PowerAutomate).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/35779b45-efbe-71c6-b495-646e69bb4f5a.png)
</details>

# フローの解説

## When someone responds to an adaptive card
まずはトリガーです。
Teamsコネクタの[誰かがアダプティブ カードに応答した場合]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/1c7f7cbc-5cc9-4f4f-8e0d-dfb28c9e8917.png)
急に英語になるのは何なのでしょうか…？
…気にせず続けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/62ae7b8f-2993-d699-3ea4-308e537b9b43.png)
[アダプティブ カードの入力]に前回受付フローで作成したアダプティブカードの本文(JSON)を、[カードの種類 ID]も同様に前回と同じCard Type IDを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/5c3da82f-ed16-fc18-7f54-1b4f13e674d9.png)

[アダプティブ カードの入力]は一見意味がないように思えましたが、入力することでスキーマが形成され、後続のアクションに動的な値としてカードのInputを使用することができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/6c56ca0e-5502-c8dd-e1f8-2d03018d4960.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/b8d354b9-c013-7a61-5e09-579bcb9b1d5b.png)

## メッセージ詳細を取得する
アダプティブカードの中身を取得するために、まずはメッセージ詳細を取得します。
triggerBodyにメッセージID,TeamID,ChannelIDがそれぞれ含まれていますので、動的な値から設定します。ChannelIDだけは動的な値から選択できなかったので、直接数式を記述しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/61ebff74-68d4-4658-71da-d74c5607da51.png)
```JSON:parameters
{
    "messageId": "@triggerBody()?['entity']?['teamsFlowRunContext']?['messagePayload']?['id']",
    "threadType": "channel",
    "body/recipient/groupId": "@triggerBody()?['entity']?['teamsFlowRunContext']?['channelData']?['team']?['aadGroupId']",
    "body/recipient/channelId": "@triggerBody()?['entity/teamsFlowRunContext/ChannelData/Channel/Id']"
}
```

いったんここまでの状態で、テスト実行をしてみます。
[メッセージ詳細を取得する]アクションの出力をよくよく確認すると、アダプティブカードの中身が文字列として返ってきているのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/e97be2c8-7930-e451-2b68-25b0a0eb5c4e.png)

## カードの中身を取り出す
以下の数式でアダプティブカードの中身を取り出します。
attachmentsプロパティが配列になっているのでfirst関数で単一要素にし、取り出したcontent文字列をjson関数でオブジェクトに変換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/3d0228aa-a800-188c-518e-7473854d6f28.png)
```PowerFx:作成 -Card JSON-
json(
    first(
        body('メッセージ詳細を取得する')?['attachments']
    )?['content']
)
```

またテスト実行し、jsonオブジェクトを確認します。
そうすると、アダプティブカードを作成した時と同じ構成の内容が取得できたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/a0b1e12b-759e-12a3-8879-f1dd2d1accba.png)
ここから目的の値、先頭に記載しておいたリストアイテムのIDを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/114f9d49-3708-e42f-844b-dc0c8b0b438f.png)

jsonオブジェクトのbodyは、itemsプロパティの階層となっており、固有のプロパティ名から目的の値にアクセスすることができません。なので、「bodyのx番目のitemsのy番目のitemsの…」と、並び順と階層で指定していきます。
サンプルと同じ構成のカードであれば、目的の値は先頭に配置されているため、以下の式で取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/aa890745-b977-5db3-ace4-f0c47d172377.png)
```PowerFx:作成 -Card JSON-
first(
    first(
        outputs('作成_-Card_JSON-')?['body']
    )?['items']
)?['text']
```
JSONと仲良しであれば、先頭のようなわかりやすい位置でなくとも自在に値を取得できるはずなので、カードから様々な情報を取得できるとさらに応用が効くと思います。

https://qiita.com/h-nagao/items/df95ea912f81a911cdee

## 項目の更新
リストアイテムのIDが取得できたら、あとは更新するだけです。
IDに先ほどアダプティブカードから取得したIDを入力し、アダプティブカードのInput(今回の例ではドロップダウンボックスから入力されたStatus)で更新させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/ae314390-94ab-9267-8169-0a669bf8158e.png)

## 後処理
チャネルを起点としたリストの更新は以上で完了ですが、このままではチャネルから更新ボタンを押した人へのリアクションがないため、ちゃんと更新できたかがわかりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/5bac8d02-4f50-bdd9-192b-5aea741bed61.png)

なので、更新したことがわかるようなメッセージを返信として追加することにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/d3b0707b-03f3-d482-6da4-d0592863ea5d.png)

また、完了Statusになった後は状況を更新させる必要がないため、[チャットやチャネルのアダプティブ カードを更新する]アクションでカードを更新し、更新ボタンを消しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/a818d6f4-6903-6d53-98a7-c409d042c867.png)
(2パターンのみの分岐なので、スイッチではなく条件分岐でよかったのですが、初めは更新Statusごとに処理を分けようとしていた名残でスイッチになっています)

# おわりに
解説は以上です。
いかがだったでしょうか？アダプティブカードのjsonから中身を取り出す泥臭い方法でしたが、アダプティブカードの応答を複数のカードから受け取れるようになるので、[誰かがアダプティブ カードに応答した場合]トリガーの可能性が広がるとよいなと思います。

# おまけ
解説記事を書いている途中で、SharePointリスト側にチャネルに投稿したメッセージIDを保存しておけばjsonを解析する必要がないことに気が付きました…。
(絶対にそっちの方が簡単。。。)

リストに保存した情報は更新される可能性があるのに対し、リストIDとアダプティブカードは普通には更新できないので、この方法を使うメリットもあるのかな？あったらいいな。。。😇