Workflowsを使って、pythonコードからTeamsにメッセージを送信

本記事は「 [TTDC Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ttdc) 」 6 日目の記事です。

## はじめに  
TeamsのIncomingWebhook(Office 365コネクタ)が近いうちに廃止されるようなので、代わりにWorkflowsを使ってpythonコードからTeamsへのメッセージ送信をしてみました。  
本記事ではその手順を紹介します。  
▼送信結果はこんな感じです。  
![送信カード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/b3436c59-ad39-e6c6-f264-1850a0d1fb3e.png)


### Workflowsとは  
Teamsの拡張機能の一つです。  
Workflowsを使用することで、Teamsに接続する繰り返しのタスクまたはプロセスを自動化できます。  


## 用意するもの  
- python環境(今回は3.12)  
- Microsoft Teamsアカウント  


## 必要なライブラリ  
- requests==2.32.3  


## 手順  
### Teams側の設定  
まずはメッセージを受け取る側の設定を行います。  
Teamsのアプリを起動しましょう。  
- フローの作成  
1. メッセージの送信先にしたいチャネルを右クリックして表示されたメニューから「ワークフロー」をクリックします。  
    ![teams設定_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/c248f819-f133-9b29-9724-efe892763bd1.png)  

1. ポップアップが表示されるので、「Webhook 要求を受信するとチャネルに投稿する」をクリックします。  
    ![teams設定_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/65af1b28-bd6e-2b41-63b5-733188090377.png)  

1. フローの名前を入力し、「次へ」をクリックします。  
    今回は「ttdc_qiita」という名前にします。  
    ![フロー作成_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/34d6df2a-76cf-0edb-cc45-8860c5b6717b.png)  

1. 送信先のチーム名とチャネル名が表示されていることを確認し、「ワークフローを追加する」をクリックします。  
    ![フロー作成_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/c8f1f17e-a95a-7196-1ab6-59c7b47bc465.png)  

1. ワークフローが正常に作成されると、urlが発行されます。  
    これが後ほど、送信先のurlとなるため、コピーして取っておきましょう。  
    ※ コピーし損ねても後ほど別の画面で確認可能です。  
    ![フロー作成完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/4aca3659-4ed7-f86f-ec34-cb08d2e09b8f.png)  

1. 手順2の画面から管理画面に移り、フローの設定を行います。  
    ![管理画面へ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/df521020-7640-4734-92e0-f45e6943f3cd.png)  

1. フローの「状況」のトグルをonにし、右側のメニューボタンから編集画面に移動します。  
    ![フロー設定_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/186c6c7a-bbfb-448c-cd66-6a540543d076.png)  
    ※トグルをonにする際に、下のようなエラーが出る場合は管理者側の設定変更が必要です。  
    業務で使う場合は会社のIT部門に相談しましょう。  
    ![エラー表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/2b9058b7-e01f-9445-3e6f-9681a8daf2e7.png)  

1. フローの詳細設定を行います。  
    編集画面に移動すると、設定用のボックスが閉じた状態で表示されています。  
    それぞれをクリックして開きましょう。  
    ![フロー設定_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/2f7daf9a-8ff7-8fd9-c42e-3b5ecf93c5eb.png)  

    下の画像を参考に設定し、「保存」をクリックします。  
    (基本的にデフォルトの状態のままで、[Post Card in chat or channel]>[投稿者]の欄を「ユーザー」に変更するだけでOKです。)  
    ※ここで、送信先のurlを再び参照することができます。  
    ![フロー設定_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/2446ff55-3fa7-235a-be7d-8c4af68d342a.png)  


### pythonコード  
次に送信側のコードを作成します。  
- メッセージの設定  
    送信カードはアダプティブカード形式で作成します。  
    [公式のページ](https://learn.microsoft.com/ja-jp/power-automate/create-adaptive-cards)にサンプルがあります。  
    ▼今回はシンプルに、タイトルとテキストのみの構成にしてみました。  
    ```
    msg = {
        "attachments": [
            {
            "contentType": "application/vnd.microsoft.card.adaptive",
            "content": {
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "type": "AdaptiveCard",
                "version": "1.2",
                "body": [
                {
                    "type": "TextBlock",
                    "text": title,
                    "size": "Large",
                    "weight": "Bolder"
                },
                {
                    "type": "TextBlock",
                    "text": text, 
                    "wrap": True,
                    "markdown": True
                }
                ]
            }
            }
        ]
        }
    ```
    
    <br>
    
    上記に加え、送信用のスクリプトも含めた全体像はこちらです。  
    urlには、Teams側の設定時に取得した送信先urlを設定してください。  
    title, textの内容を変更すると、Teamsへの送信内容に反映されます。  
    ▼`teams_messaage.py`
    ```
    import requests
    import json

    def send_message(url, msg):
        # POSTリクエストを送信
        response = requests.post(
            url=url,
            data=json.dumps(msg),
            headers={"Content-Type": "application/json"}
        )
        return response

    if __name__=='__main__':

        ######### ここを変更する #########
        url = "送信先のurlを貼る"
        title = "タイトル"
        text = f"＊＊＊メッセージ欄＊＊＊"
        #################################
        
        msg = {
        "attachments": [
            {
            "contentType": "application/vnd.microsoft.card.adaptive",
            "content": {
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "type": "AdaptiveCard",
                "version": "1.2",
                "body": [
                {
                    "type": "TextBlock",
                    "text": title,
                    "size": "Large",
                    "weight": "Bolder"
                },
                {
                    "type": "TextBlock",
                    "text": text,
                    "wrap": True,
                    "markdown": True
                }
                ]
            }
            }
        ]
        }
        response = send_message(url, msg)

        # レスポンスを確認
        if response.status_code == 200:
            print("メッセージを送信しました")
        elif response.status_code == 202:
            print("メッセージの送信を受け付けました")
        else:
            print(f"エラーが発生しました: {response.status_code}, {response.text}")
    ```

    このスクリプトを実行すると、チャネルへのメッセージ通知がされるはずです。  
    ![送信カード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944860/b3436c59-ad39-e6c6-f264-1850a0d1fb3e.png)　


## まとめ
pythonを使ってTeamsにメッセージ送信を行うことができました。  
IncomingWebhookと同様、別のコードと組み合わせることで実行結果の共有や定期実行しているシステムの動作の監視など、さまざまな応用ができそうです。


## 
今回の記事は以上になります。  
最後まで読んでいただき、ありがとうございました！  

今後も機械学習の活用を始め、開発環境やシミュレーションなど幅広く技術情報発信をしていく予定です！  
最後になりますが、本記事の内容に誤りなどあれば、コメントにてご教授お願いいたします。  


## 参考
[Retirement of Office 365 connectors within Microsoft Teams【Microsoft Teams 内の Office 365 コネクタの廃止】](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/)

[アダプティブカードを初めて作成する](https://learn.microsoft.com/ja-jp/power-automate/create-adaptive-cards)