Power Automate でTeamsカスタム絵文字付きメッセージを投稿する

# はじめに

組織独自で登録して使用できる`カスタム絵文字`をPower Automate から投稿するフローです。
応用してPower Appsからも投稿できると思います。

https://support.microsoft.com/ja-jp/office/microsoft-teams%E3%81%A7%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E7%B5%B5%E6%96%87%E5%AD%97%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B-84feb1c4-6d2b-4ecd-8e55-a93c828fc53a

:::note warn
ここで説明する方法は、公式ドキュメントなどから参照した情報ではなく、**筆者独自に調査**したものです。
運用環境で使用される場合は、十分配慮の上ご検討ください。
:::



# カスタム絵文字を調べる
カスタム絵文字を投稿するには、カスタム絵文字を特定する２つの情報が必要です。
ここでは便宜上、`Name`と`Id`としておきます。

`Name`は絵文字を登録するときの名前です。これとは別に識別子っぽい`Id`の情報が必要となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/046f0fd2-4793-4c9e-b6b5-584a73cb7a70.png)

まずはこの２つの情報を調べるフローを作成します。

## メッセージの詳細を取得
カスタム絵文字を含むメッセージの詳細を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/0f59e9e7-86d2-4e79-8495-81382e2bef10.png)

`選択したメッセージに対して(V2)`トリガーを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/a7f98d80-7919-4055-96ac-353838fcd53d.png)

続いて`メッセージ詳細を取得する`を使用して、カスタム絵文字がどんな風に表現されているか調べてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/e4781c01-e8b5-4c7b-bfe6-0c7bd6c28320.png)

## カスタム絵文字の表現
本文(`body/content`)は以下のようになっていました。
```html:body/content
<p>絵文字だよ<customemoji       
    id="ZXhjZWw7MC13dXMtZDUtN2Q0NjY5NDdiNmMwZTU0NmQyMTE4OTc3M2QxZmJmOTU="
    alt="excel"
    source="https://us-prod.asyncgw.teams.microsoft.com/v1/objects/0-wus-d5-7d466947b6c0e546d21189773d1fbf95/views/imgt2_anim">
    </customemoji>
</p>
```

上記の例では`customemoji`タグの`alt`属性`excel`が`Name`、`source`属性の中の`0-wus-d5-7d466947b6c0e546d21189773d1fbf95`が`Id`となります。

また、`ZXhjZWw7MC13dXMtZDUtN2Q0NjY5NDdiNmMwZTU0NmQyMTE4OTc3M2QxZmJmOTU=`をbase64でデコードすると、以下のようになります。

```plaintext:デコードしたテキスト
excel;0-wus-d5-7d466947b6c0e546d21189773d1fbf95
```

どちらからとっても良いのですが、両方含まれてお得なデコードしたテキストから取得することにしました。

## 本文から情報を取り出す
カスタム絵文字のタグが複数あってもいいように、本文を`<customemoji id="`で区切って配列を作成します。
`<customemoji id="`より前の最初のテキストは不要なので、`skip`関数で省いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/70ae57a9-6551-4141-9209-6e0025e98883.png)
```powerfx:作成
skip(
    split(
        outputs('メッセージ詳細を取得する')?['body/body/content'],
        '<customemoji id="'
    ),
    1
)
```

それぞれの絵文字のタグから、`<customemoji id="`より後ろ、次の`"`より前のテキストを抽出するため、選択アクションでそれぞれの配列要素をさらに`split`し、base64でデコードして、`;`でさらに区切って前の方を`Name`後ろの方を`Id`とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/21cbffa2-e809-4b70-afb9-21c231475b47.png)

```powerfx:選択/Name
split(
    decodeBase64(
        split(
            item(),
            '"'
        )?[0]
    ),
    ';'
)?[0]
```

```powerfx:選択/Id
split(
    decodeBase64(
        split(
            item(),
            '"'
        )?[0]
    ),
    ';'
)?[1]
```
確認のためTeamsチャットで送りました。
一度調べたカスタム絵文字の情報は、SharePointリストなどに保管しておくと使いやすいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/fefccf2e-4fd6-4c92-891d-ff60b71f516b.png)


とりあえず、この情報があれば投稿もできるので、次に進みましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/19a54c3a-1cfc-4cb2-94dd-e393cdab65ea.png)


# カスタム絵文字を投稿する
カスタム絵文字を表現するHTMLが必要です。
`Name`と`Id`を使って以下のように作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/b1fd5640-cacd-4d94-a799-8b11adc24640.png)

```html:customEmoji
<img alt="@{variables('Name')}" itemid="@{variables('Name')};@{variables('Id')}" itemtype="http://schema.skype.com/CustomEmoji" src="https://us-prod.asyncgw.teams.microsoft.com/v1/objects/@{variables('Id')}/views/imgt2_anim" style="width:20px;height:20px;">
```
あとはこのタグを使って投稿するだけです。
メッセージ内に埋め込んで投稿しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/0593edb1-e103-4a6c-8ca6-1716a23200a9.png)

投稿できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2572227/fd9cc632-e9d1-40b8-918a-aac0f617d782.png)

# おわりに
とりあえず投稿はできましたが、あらかじめ情報を調べておかないといけないのが大変ですね。
一覧取得できるアクションやAPIがあればいいのですが…

ちなみに私は組織の絵文字の管理者権限で、すべての絵文字の情報をあらかじめ取得して公開するようにしておきました。（強権）

よりよい方法があれば教えてください！