TeamsにLINEのリンク一覧を再現【Power Automate】

## はじめに
皆様、**LINEのリンク一覧**をご存知でしょうか？
トーク画面の右上にある [≡]メニュー → リンク にある機能のことです。

https://guide.line.me/ja/chats-calls-notifications/chats/chatmenu.html#linkfile

過去に共有したリンクが一覧化されていて、
メッセージの長いやり取りからいちいち探さなくて済むのですごい便利なんですよね！
（ステマみたいな文章になってしまいました笑）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/b8da8f7f-ba17-d081-ab5f-7dc0480cb0cf.png)

けどこの機能、LINEにはあるのにTeamsには無いんです。
ということでLINEとTeamsの機能差を埋めるためにPower Automateを使って実現した事例を紹介したいと思います。

## 構成
Teams、Power Automate、Data Verse、Power Appsのサービスを使って構成しています。

メッセージが投稿されたタイミングで、Power Automateのトリガーを起動、
内部でリンク情報を抽出し、それをData Verseに保存しています。
Power AppsではData Verseに保存した情報を使って一覧化しています。
またTeamsのタブに作成したPower Appsを登録すれば、Teamsから使用できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/17533e33-f8fc-b2f3-ba71-a39ef968cc68.png)

## 実装内容
大まかな流れは以下の通りです。
１．トリガーの設定
２．メッセージ本文からaタグを抽出、aタグリストに追加
３．aタグリスト分ループを開始
４．aタグからURLを取得
５．[LinkPreview](https://www.linkpreview.net/)を使ってURLのタイトルとサムネイルを取得
６．取得した情報をまとめ、テーブルに行を追加

全体のコネクタ数がやや多いため
変数の初期化などは省略し、重要な箇所のみご説明させていただきます。

### １．トリガーの設定
LINEと同様に、リンクを共有したタイミングで一覧表に追加してほしいので、
「**チャネルに新しいメッセージが追加されたとき**」トリガーを設定しました。

注意点としては、メッセージにリンクが含まれている/いない問わず、
トリガーが実行されてしまうので、後続の処理でリンクが含まれているかの判定を行う必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/549ee0bc-d23d-0580-e961-0829599516a9.png)

### ２．メッセージ本文からaタグを抽出、aタグリストに追加
トリガーから取得できたメッセージ本文を解析すると、
以下のようにaタグが埋め込まれていることがわかるかと思います。
`<a href="アドレス" rel="noopener noreferrer">アドレス/表示するテキスト</a>`

本文にaタグ以外の文言やaタグが複数含まれていることを考慮し、
まずは**split関数**を使ってメッセージ本文を**aタグごとにざっくり分割**します。
```
split(variables('コンテンツ'),'</a>')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/4bde512e-7735-af71-4879-a80c5b18b540.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/e0dcff7d-a8ee-c198-2f54-10df44d50567.png)

### ３．aタグリスト分ループを開始
ループの対象をaタグリストに設定し、「<a href=」が含まれているかの判定を行います。
結果がTrueの場合のみ後続の処理を実行します。
またトリガーの設定で注意点としてあげたリンクが含まれているかの判定はこちらで行っております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/11bb4973-1124-846e-74e9-e8df56d83e55.png)

### ４．aタグからURLを取得
aタグが含まれていると判定されたので、次はURL部分のみを取得するようにします。
以下の4つの変数を用意し、以下の関数を設定します。

```
開始位置：Integer型
add(indexOf(items('aタグ'),'href="'),6)

終了位置：Integer型
indexOf(items('aタグ'),'" rel=')

差：Integer型
sub(variables('終了位置'),variables('開始位置'))

Aタグ：String型
substring(items('aタグ'),variables('開始位置'),variables('差'))

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/f69e6b3c-2cfe-0d15-c90a-0b6e5c782f0a.png)

それぞれの関数の役割は以下の通りです。
開始位置：アドレスのhttp://~ が始まる「h」の位置を特定
終了位置：アドレスの最後の文字の位置を特定
差：アドレスの長さ（文字数）を取得
Aタグ：開始位置からアドレスの長さ分、文字列を取得

`<a href="アドレス" rel="noopener noreferrer">アドレス/表示するテキスト</a>`

### ５．[LinkPreview](https://www.linkpreview.net/)を使ってURLのタイトルとサムネイルを取得
この記事では詳細なことは記載しませんが、
LinkPreview APIを使用するとURLの様々な情報を取得する事が出来ます。
API使用料は無料なので、気になる方は上記リンクから会員登録を行ってください。

本題に戻りますが、私の場合は以下のように設定し、HTTP POSTを実行しております。
Quriesの中のkeyは会員登録した際に提供されるAPIキーをそのまま登録しております。
POSTに成功した場合、サムネイルなどの情報が手に入ります。
※もちろん社内リンクなどに対して実行した場合はPOSTに失敗します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/64548609-6f71-d8bc-74da-7b90b9b5ec57.png)

### ６．取得した情報をまとめ、テーブルに行を追加
最後に以下の情報をまとめ、Data Verseのテーブルにレコード追加します。

Name：メッセージの送信者名
Date：メッセージの送信日
Link：URL
Preview：リンク先のサムネイル（HTTP POSTに成功した場合のみ）
TeamsLink：メッセージのリンク
Title：リンク先のタイトル（HTTP POSTに成功した場合のみ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/a9bc479d-beef-c017-8977-38313114228b.png)

## 完成
あとはPower Appsで画面を作成すれば完成です！（これが一番大変かもしれませんが…）

チャネルで共有したリンクが一覧表の方にも反映されるようになりました◎
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/0b491748-a9ab-a34e-f773-7ded1ad23ba8.png)

画面左のアイコン/タイトルをクリックすればリンク先のサイトが開き、
画面右のTeamsアイコンをクリックすれば、Teamsの送信元メッセージが開くように作っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/34b11b11-da3e-3c22-6163-ce653f6d7360.png)

## 評価
個人的には機能を100%再現できたことは嬉しかったです。

ただ今のPower Automateの実装内容ですと、以下のような問題があります。
・内部で**TeamsのチャネルIDを指定**しているため、**1つのチャネルでしか使えない**
・「**チャネルに新しいメッセージが追加されたとき**」トリガーの仕様上、**返信メッセージは1回目のみ**しかトリガー対象にならない
※同一メッセージ内で返信が複数回続いても、2回目以降の返信についてはトリガーが実行されない

2つ目については結構重たい問題なので、
まずはユーザーID、TeamsのチームID、チャネルIDを使って、
**どのチームで誰が発信したメッセージか**を管理、表示制御できるようにしたいと思います。

## さいごに
いかがだったでしょうか。
他にもPower Automateを使って実現してほしい機能があればリクエストください。