Teamsメッセージのリアクション情報をボタンひとつで出力する

#はじめに
Microsoft Teams メッセージ右上のリアクション、活用していますか？
![スクリーンショット 2020-08-04 22.28.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/f9d31cba-4ffd-4698-1fbc-7b1ae14aae08.png)

ライトなコミュニケーション手段としてはもちろん、
「内容確認したら👍ください！」
「今日の勉強会に参加する人はスタンプ押しておいてください！」
等、簡易投票のような用途で使われている方も多いのではないでしょうか。
しかし、Teamsの標準機能ではメッセージのリアクションを「誰が」「いつ」「どの種類の反応を」行ったのか、一覧形式での確認が非常にしづらいです。
とは言ってもFormsやPolly等の別サービスを使うほどでもないし...
ということで、このリアクション情報を取得するフローをPower Automateで作ってみました。

##必要なサービス
* Microsoft Teams
* Power Automate
    * Office ライセンスで実現可能です！
    * Microsoft Teams > **選択したメッセージの場合** トリガーが必要です。もしかしたらお使いのテナントにまだロールアウトされていないかもしれません。その場合は気長にお待ちください。
* OneDrive for Business

##制限事項
* メッセージのうち、親メッセージ（最上位スレッド）のみ利用可能です。
* 返信メッセージのリアクションは集計できません。

#フロー全体像
以下の通り大きく分けて4ステップです。
![スクリーンショット 2020-08-05 1.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/85a7027a-eb2b-56f0-4209-d64812acbc3a.png)
では、これから各アクションを順を追って説明していきます。


#メッセージ取得
##トリガー
トリガーはMicrosoft Teams > **選択したメッセージに対して** を選択してください。

「アダプティブ カードの入力」は今回は設定不要です。そのままにしておきます。
（選択後の表示が「選択したメッセージの場合」に変わっていますが、気にせず）
![スクリーンショット 2020-08-04 22.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/e2b8d4c8-fb6b-222e-d498-78c698da43cc.png)

##変数を初期化
リアクション情報を格納するための変数を配列で定義しておきましょう。

* 種類：アレイ
* 値：（空白）

![スクリーンショット 2020-08-04 22.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/ed727daa-6ab7-029e-5bba-2c5d6a4f22a8.png)

##チャネル内メッセージ一覧の取得
トリガーの出力にリアクション情報が入っているのでは？と思いきや...
実際に出力してみると分かりますが、リアクションに該当する情報が含まれていません。
対して **メッセージを取得します** アクションであればリアクション情報を含む結果が出力として得られます。
よって、ここではトリガーの出力から得られるチームID・チャネルIDをキーとしてチャネル内の全てのメッセージを取得し、
後続アクションで必要なメッセージを絞り込むことにします。
Microsoft Teams > **メッセージを取得します** アクションを選択して以下の通り設定します。
![スクリーンショット 2020-08-04 23.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/120a8740-df6e-50b4-3dbf-429110af295a.png)

```text:チーム
triggerBody()?['entity']?['teamsFlowRunContext']?['channelData']?['team']?['aadGroupId']
```

```text:チャネル
triggerBody()?['entity']?['teamsFlowRunContext']?['channelData']?['channel']?['id']
```

##該当のメッセージ抽出
データ操作 > **アレイのフィルター処理** アクションを選択します。
前アクションで得られるチャネル内の全メッセージからトリガーのメッセージIDをキーとして、トリガーメッセージだけを抽出します。
![スクリーンショット 2020-08-04 23.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/d7a86747-3e73-f777-850e-56f7bc2036ee.png)

```text:差出人(from)
outputs('メッセージを取得します')?['body/value']
```

```text:条件の左辺
item()?['id']
```

```text:条件の右辺
triggerBody()?['entity']?['teamsFlowRunContext']?['messagePayload']?['id']
```
これでトリガーメッセージの詳細情報を取得することができました。

#リアクション抽出
さて、**トリガーメッセージ抽出** アクションの出力を確認すると、下の方に以下のような情報が見つかります。

```json:「トリガーメッセージ抽出」の出力（※抜粋）
"reactions": [
      {
        "reactionType": "surprised",
        "createdDateTime": "2020-08-03T14:58:07.031Z",
        "user": {
          "application": null,
          "device": null,
          "conversation": null,
          "user": {
            "id": "******",
            "displayName": null,
            "userIdentityType": "aadUser"
          }
        }        
      }
    ]
```

この"reactions"配列内に格納されているのがまさしくリアクションのデータです。
この部分だけ抜き出してしまいましょう。

データ操作 > **選択** アクションを利用し、必要な情報のみ抽出します。
今回はリアクションタイプ・（ユーザー）id・リアクション日時をピックアップしました。
※開始(from)に指定する「トリガーメッセージ抽出」アクション出力は配列形式である為、first関数で配列の最初の項目のみ返すようにしています。
![スクリーンショット 2020-08-04 23.40.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/a7baf3f7-4860-84b1-5555-b90e4e2f7fb5.png)

```text:開始(from)
first(body('トリガーメッセージ抽出'))?['reactions']
```

```text:reactionType
item()?['reactionType']
```

```text:id
item()?['user']?['user']?['id']
```

```text:createdDateTime
item()?['createdDateTime']
```

#ユーザー情報取得
前項の"reaction"配列内の出力で分かる通り、リアクションしたユーザー情報はidしか取得できません。
Microsoft 365 ユーザー > **ユーザープロフィールの取得(V2)** アクションを利用して、idをキーにユーザー情報を取得しましょう。

ループ処理の中で各idからユーザー情報を取得し、CSVファイルに出力したい情報をkey:value形式でマッピングして配列変数に追加していきます。

今回はユーザー情報として表示名とメールアドレスをピックアップしました。
この段階でcreateDateTime（リアクション時間）も日本標準時にフォーマットしています。
この辺のデータ整形はお好みでどうぞ。
![スクリーンショット 2020-08-05 1.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/417eda92-bffd-cd7e-2013-f3da41a1cdd0.png)

```text:Apply&nbsp;to&nbsp;each.以前の手順から出力を選択
body('リアクション部分抽出')
```

```text:ユーザープロフィールの取得(V2).ユーザー(UPN)
items('Apply_to_each')?['id']
```

```json:配列変数に追加.値
{
 "displayName": "@{outputs('ユーザー_プロフィールの取得_(V2)')?['body/displayName']}",
 "Email": "@{outputs('ユーザー_プロフィールの取得_(V2)')?['body/mail']}",
 "reactionType": "@{items('Apply_to_each')?['reactionType']}",
 "createdDateTime": "@{convertTimeZone(items('Apply_to_each')?['createdDateTime'], 'UTC', 'Tokyo Standard Time', 'yyyy/MM/dd HH:mm:ss')}"
}
```

#CSVファイル出力
いよいよリアクション結果をCSVファイルとして出力します。

##CSVテーブル作成
リアクション情報を格納した配列変数の値をCSVテーブルに変換します。
データ操作 > **CSVテーブルの作成** アクションを使用して配列変数を指定するだけです。
![スクリーンショット 2020-08-05 0.08.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/3804c66d-a0a8-658c-8c05-2fdf80f6f6c3.png)

##CSVファイル作成
CSVファイルをOneDriveに保存します。
OneDrive for Business > **ファイルの作成** アクションを選択してください。
フォルダーのパス・ファイルはお好みの設定で大丈夫ですが、拡張子「.csv」を記入するのを忘れずに！
![スクリーンショット 2020-08-05 0.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/ca0718bf-b837-344e-a076-a38b39f0835e.png)

```text:ファイルコンテンツ
body('CSV_テーブル_回答者')
```

#完成！
フロー実行を許可するユーザーに対して「実行のみのユーザー」権限を付与したら、
メッセージ右上の三点リーダ>その他の操作>（フロー名） をクリックしてフローを実行しましょう。
![スクリーンショット 2020-08-05 0.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/83f33e87-977e-01a2-f9f0-97229b35ee97.png)
![スクリーンショット 2020-08-05 0.18.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/92e77f3d-8449-6caa-0a53-fda37c13fed2.png)

OneDriveの指定フォルダ内を見ると、CSVファイルが出力されているのが分かります。
![スクリーンショット 2020-08-05 18.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/6add7cc5-6dbb-2ae9-d039-38eb1ac619f3.png)
<img width="562" alt="スクリーンショット 2020-08-05 18.37.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686244/60a29bae-3c0a-f35d-e725-cc549acc313c.png">
リアクションしたユーザーと時間、リアクションの種類が一覧で簡単に確認できます！

#補足
##1. reactionTypeの値とアイコンの対応

| reactionType | アイコン |
|:-:|:-:|
| like | 👍 |
| heart | ❤️ |
| laugh | 😄 |
| surprised | 😲 |
| sad | 😟 |
| angry | 😡 |

##2. 拡張
詳しい設定は記載しませんが、このフローをベースに以下のような拡張も可能です。
ぜひトライしてみてください！

* 出力したCSVファイルの共有リンクを生成してメッセージで共有
* 未回答者一覧の出力（チームメンバー一覧取得→回答者を除去）
* 未回答者にメンション付きのメッセージ送信
* 上記をオプションとしてフロー実行ユーザーに選択させる（トリガーにAdaptive Cardsを設定）