#PowerAutomate で Teams チャットから画像を抜き出す

先日、こんなコトがありました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">あれ？ Microsoft Teams のチャネルのメッセージに貼り付けた画像って Power Automate でメッセージが追加された時のトリガー使って、後続のアクションで貼り付けた画像を指定する事って簡単にはできない！？ <a href="https://t.co/6rSIbTUdk5">pic.twitter.com/6rSIbTUdk5</a></p>&mdash; T A I C H I (@artbreak_taichi) <a href="https://twitter.com/artbreak_taichi/status/1498991649505955840?ref_src=twsrc%5Etfw">March 2, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

詳細は TL をご確認いただくとして・・・。

Teams の投稿するメッセージに、クリップボードの画像を張り付け（Ctrl + v）できるコトは皆さんご存知でしょうか？

チームのチャネルへファイルを直接ドラッグアンドドロップした場合は、そのチームのファイル（厳密には、チームの裏側にある SharePoint Online サイト（以降、SPO）のドキュメントライブラリ）へ自動的に保存されます。しかし、コピー＆ペーストでチャット欄へ張り付けた画像は、そのファイルには格納されません。
今回のネタは、そんなチームのチャネルへコピペされた「ファイル（＝SPO のライブラリ）に格納されない」画像を Power Automate で抜いてくる方法です。

# 注意
紹介するフローを実現するためには ***有償ライセンス*** が必要です。

# フロー全体像
Teams のチャネルへコピペされた画像を含むメッセージが投稿されたら、SPO のドキュメントライブラリへ”画像のみ”を保存するフローです。
![00-zentai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/8ca67dd2-6b67-902c-5366-a6ef6407dacc.png)
Apply to each が存在する理由がピンときた方はサスガです。後で説明しますゆえ、暫しお付き合いくだされ。

## 動作イメージ
左から、Teams のチャネル、前述のフロー、画像保存先のドキュメントライブラリです。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr">Teams ctrl+v img -&gt; Power Automate -&gt; DocLib <a href="https://t.co/TyiiY6Gc73">pic.twitter.com/TyiiY6Gc73</a></p>&mdash; やま (Yama) (@yamad365) <a href="https://twitter.com/yamad365/status/1499393754905849861?ref_src=twsrc%5Etfw">March 3, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ポイントの解説
是非、ご自分で手を動かして調べながら試してくださいね。

## 前提となる知識
まず、単純に「チャネルに新しいメッセージが追加されたとき」アクションと「作成」アクションのみを置いたフローで説明します。チャネルへ画像をペーストした結果を［メッセージ本文］で出力してみましょう。実行結果は下記のようになるハズです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/e1bdf737-6f19-d2be-fb7f-82089b586e8e.png)
コピペで投稿した画像は HTML タグの img で表現されてる状態が把握できると思います。チームの SPO にコピペで張り付けた画像が保存されていない、という事実が垣間見えましたね。

ちなみに、img タグの src で指定されているのは Graph API になります。
ほぅ、Graph API...メンドクサソウなにおいがしますね🤔

## ダブルコーテーションで Split
全体像で紹介したフローに戻って、冒頭の「作成」アクションが2つ並んでいる箇所です。コレの1つ目は単純にダブルコーテーション（"）を定義しているだけです。その次のアクションで Teams のメッセージ本文の中にある content の内容を [split](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=BA-MVP-5004053#split) 関数を利用して分割しています。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/2db1064f-3f15-99dd-683e-93c37fca43b4.png)

上記の関数はこのようなカタチです。

```
split(triggerOutputs()?['body/body/content'], outputs('ダブルコーテーション'))
```

ダブルコーテーションのために、わざわざ1つアクションかまして定義しているのは単純に可読性の理由です。「split(対象,'"')」と記述しても問題ありません。個人的に ’ と ” が連続してて読みづらいなぁ、と感じたのでヒト手間加えているだけです。

## Graph API の部分だけ抜き出す
Split された結果は配列になります。その配列から、Graph API の部分のみ抽出しています。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/2d732b1c-f139-d76b-a3ad-ebca3fad0774.png)
左辺は item() と記述しておけば OK です。

## Graph API を実行して画像を取得し保存
Graph API の部分のみ配列に抽出された状態になっているので、要素を1つずつ処理していきます。繰り返し（Apply to each）を置いたら、その中に「HTTP with Azure AD」の「HTTP 要求を呼び出します」アクションを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/71db3628-af3f-146b-02cf-09533cd68807.png)
下記のような状態になった場合は［基本リソース URL］と［Azure AD リソース URI］の両方に ” https://graph.microsoft.com ” を指定してサインインです。（ここは [Miyake Mito](https://twitter.com/MiTo60448639) さんに教えてもらいました。感謝！）
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/24f168be-9378-620e-4406-b77820698610.png)
HTTP 要求が実行できるようになるので、繰り返し処理の［現在のアイテム］を指定しましょう。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/a548a23b-4170-dfac-32ff-82afb4eefd42.png)
繰り返されている現在のアイテムには、Teams のメッセージから抽出した Graph API が含まれています。それを順番に実行していく、という流れです。仕上げに Graph API 経由で取得できた画像を目的の SPO サイトにあるドキュメントライブラリへ保存してフィニッシュです。API で取得できる情報は [base64ToBinary](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=BA-MVP-5004053#base64tobinary) 関数で画像として保存できます。

# まとめ
チャットメッセージへ添付されたファイルみたいな状態で、コピペされた画像が存在していれば Power Automate のアクションで素直に取得できたんでしょうが・・・。ここらへんは、Teams チャットが裏側ではどうなっているか？という公開情報などを眺めていると理由が妄想できるんじゃないかな、と個人的に考えています。

- Teams のチャットへペーストした画像は本文に img タグで埋め込まれる
- img タグの src は Graph API になっている
- チャットには複数の画像をコピペ可能

送信される画像が1つに限定できるのであれば、抽出も繰り返し処理も不要です。
Teams のチャットには複数の画像をペーストできますよね？
なので、複数画像も対応できるフローで紹介しました。

それでは、皆さま、素晴らしい Power Platform Life を！