TeamsのIncoming Webhookが廃止になるらしいので新手順でNode.jsから送信

TeamsのIncoming Webhookが廃止になるらしいですね。

https://dev.classmethod.jp/articles/teams-webhook-markdown-workflows/

## 今までとURLの発行手順が違う

### 今まで
これまでのやり方だとTeamsからアプリ => Incoming WebhookでURLを発行していました。

### 新手順 - ワークフロー

新しい手順ではワークフローというカテゴリがアプリとは別にできていてそこから進みます。

> ![CleanShot 2025-04-22 at 20.30.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/46997264-00e2-4867-b2ee-0eee874117e0.png)

Teamsから **`ワークフロー => 通知 => Webhook要求を受信するとチャネルに投稿する`** を選択します。

> ![CleanShot 2025-04-22 at 20.35.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/7d7180e2-c37e-449f-befa-2f4eef71b179.png)
> 割と探しにくい......

"XXXから通知..."など、ワークフロー名を入れましょう。

> ![CleanShot 2025-04-22 at 20.36.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/de12a9d8-1a60-47ac-9034-c553d9cd28ee.png)
> 接続確認で少しロード時間がかかります。

送信するチャネルがあるチームを選択し、チャネルを選択します。

> ![CleanShot 2025-04-22 at 20.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/da96aa15-780d-43b9-9992-c8ac484c85d4.png)

するとWebhookURLが生成されます。

> ![CleanShot 2025-04-23 at 13.35.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/02a11a85-d0b7-4cbc-8c06-1c19d0fdd15b.png)

`https://prod-24.japaneast.logic.azure.com:443/workflows/xxxxxxxxxxxxxxxxxxxxxxx/triggers/manual/paths/invoke?api-version=~~` こんな雰囲気のURLが生成されます。


## 今までと送信するJSONが違う

### 今までのJSON
以前はこんな感じで送っていました。

https://qiita.com/n0bisuke/items/d5da6776d42ab1fce7a3


```json
{
    "@type": "MessageCard",
    "@context": "https://hogehoge.com/hogehoge.png",
    "themeColor": "0076D7",
    "summary": "ディスカッション",
    "sections": [{
        "activityTitle": "Larry Bryant created a new task",
        "activitySubtitle": "On Project Tango",
        "activityImage": "https://hogehoge.com/xxxxx.png",
        
        "facts": [{
            "name": "投稿者",
            "value": "うこ"
        }, {
            "name": "URL",
            "value": "https://hogehoge.com/xxxx/yyy"
        }, {
            "name": "Status",
            "value": "Not started"
        }],
        "markdown": true
    }]
}
```

### 新しいWebhookのJSON

こちらの記事を元にしています。

https://blog.devplatform.techmatrix.jp/blog/teams_workflows_notification/

[アダプティブカード形式](https://learn.microsoft.com/ja-jp/power-automate/overview-adaptive-cards)という形式で送る必要がある模様です。

```json
{
  "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": "メッセージ",
            "wrap": true,
            "markdown": true
          }
        ]
      }
    }
  ]
}
```

## Node.jsから送ってみる

さっとo4-miniに書いてもらいました。

ちなみにNode.jsはv23.11.0です。

```js
// sendTeamsAdaptiveCard.mjs
// 実行例: WEBHOOK_URL='<署名付き URL>' node sendTeamsAdaptiveCard.mjs

// ① Webhook URL（環境変数推奨）
const WEBHOOK_URL = process.env.WEBHOOK_URL ?? '<署名付き URL>';

if (!WEBHOOK_URL.startsWith('https://')) {
  console.error('❌ WEBHOOK_URL が未設定、または形式が正しくありません。');
  process.exit(1);
}

// ② Adaptive Card ペイロード（Python サンプルと同一）
const payload = {
  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: '## Workflow経由のTeamsへの通知テストです。\n\n* 通知の詳細1です。\n* 通知の詳細2です。',
            wrap: true,
            markdown: true
          }
        ]
      }
    }
  ]
};

// ③ POST
try {
  const res = await fetch(WEBHOOK_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  });

  if (res.ok) {
    console.log('✅ メッセージが送信されました');
  } else {
    const text = await res.text();
    throw new Error(`Status ${res.status}: ${text}`);
  }
} catch (err) {
  console.error('❌ 送信に失敗しました:', err);
}
```

```bash
$ node sendTeamsAdaptiveCard.mjs
✅ メッセージが送信されました
```

これでうまく送信されると以下のように通知されます。

> ![CleanShot 2025-04-23 at 13.45.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/e6c1c660-18d5-496d-b4f2-29a8efbad9ca.png)

## まとめ

TeamsのWebhook通知のやり方が変わりました。
変わったけどそこまでめんどくさくなったって感じでもないので新手順に慣れておけばOKかなと思います。

## 補足

### "チャンネルに送信する"と"チャットに送信する"が紛らわしい

ちなみに特定のチャネルではなく、個別チャットやグループチャットに送信したい場合は"チャットに送信する"を選択します。ここが見た目一緒でちょっとした文字列の違いとなって分かりにくいので注意しましょう。

![CleanShot 2025-04-22 at 20.34.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/996f1e21-381a-4667-b32b-748335aca79b.png)

### 作ったワークフローを編集したい

Teamsのワークフローメニューから管理できます。

> ![CleanShot 2025-04-23 at 13.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ac8efd7f-926f-4598-87f6-2654d8515252.png)

ここまでくるともろUIgPower Automateですね

> ![CleanShot 2025-04-23 at 13.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/2dc10ebf-3ca8-4db1-8680-bdd46d78483b.png)