Teams の対話型通知ボット

Microsoft Teams Toolkit を使用すると、イベントをキャプチャし、対話型の通知として Microsoft Teams の個人用、グループ チャット、またはチャネルに送信するアプリケーションを構築できます。 通知はプレーン テキストまたは アダプティブ カードとして送信できます。 通知ボット テンプレートは、HTTP 投稿要求によってトリガーされたアダプティブ カードを使用して Teams にメッセージを送信するアプリを作成します。

アプリ テンプレートは TeamsFx SDK を使用して構築されています。これにより、要件を実装するために、Microsoft Bot Frameworkに対する簡単な一連の関数が提供されます。 たとえば、旅行代理店は、ユーザーが天気予報を常に最新の状態に保つためのアプリを Teams に構築します。 次のフローチャートでは、Teams アプリはアダプティブ カードを使用してユーザーに天気予報について通知します。

天気予報のサンプル通知シナリオ

ボット通知は、次のシナリオで送信できます。

  • チャネル内のすべてのユーザーに通知するか、同じコンテンツまたは関連コンテンツについてチャットする必要があります。

  • カード内の高度にカスタマイズ可能な UI

  • 迅速な応答、メディア コンテンツの追加、またはアクション ボタンが必要です。

  • スケジュールされた通知を送信する

  • アクティビティ、チャット、チャネル、アプリの両方でダブル バッジを点灯する

  • ソース コードにテンプレートを追加します。

  • ローカライズを手動で処理する。

メリット

  • TeamsFx SDK の API を使用して、個人用チャット、グループ チャット、チャネルでの通知を容易にします。

  • アダプティブ カードを使用して通知をカスタマイズすることで、ユーザー エクスペリエンスを向上させます。

  • AZURE FUNCTIONSを使用して HTTP やスケジュール タイマー トリガーなどの通知をトリガーする複数のメカニズムを提供します。

  • 通知カードボットと簡単に統合でき、ボット アプリ内で一貫性のあるユーザー エクスペリエンスを提供します。

注:

通知を送信する前に、ボット アプリケーションを対応するスコープでインストールする必要があります。

先頭に戻る

イベントに基づく通知

Bot Framework SDK には、Teams で事前にメッセージを送信する機能が用意されています。 TeamsFx SDK には、ボット イベントがトリガーされたときにボットの会話参照を管理する機能が用意されています。 TeamsFx SDK では、次のボット イベントが認識されます。

Event 動作
ユーザー、グループ、またはチームにボットを初めてインストールする場合。 ターゲット会話参照をストレージに追加します。
ボットがユーザー、グループ、またはチームからアンインストールされたとき。 ストレージからターゲット会話参照を削除します。
ボットによってインストールされたチームが削除されたとき。 ストレージからターゲット会話参照を削除します。
ボットによってインストールされたチームが復元されたとき。 ターゲット会話参照をストレージに追加します。
ボットがメッセージを送信する場合。 ターゲット会話参照が存在しない場合は、ストレージに追加します。

新しい通知イベントのサンプル

通知を送信すると、TeamsFx SDK によって、選択した会話参照から新しい会話が作成され、メッセージが送信されます。 高度な使用のために、会話参照に直接アクセスして、独自のボット ロジックを実行できます。

// list all installation targets
for (const target of await notificationApp.notification.installations()) {
    // call Bot Framework's adapter.continueConversationAsync()
    await target.adapter.continueConversationAsync(
        target.botAppId,
        target.conversationReference,
        async (context) => {
            // your own bot logic
            await context...
        }
    );
}

先頭に戻る

通知ボットのインストール

通知ボットは、必要なスコープに応じて、チームまたはグループ チャット、または個人用アプリとしてインストールする必要があります。 アプリにボットを追加する前に、インストール 先を選択する必要があります。

インストール スコープを追加する

その他のインストール オプションについては、「 既定のインストール オプションを構成する」を参照してください。 アンインストールについては、「 Teams からアプリを削除する」を参照してください。

先頭に戻る

通知をカスタマイズする

次のカスタマイズを行って、ビジネスニーズに合わせて通知テンプレートを拡張できます。

イベント ソースからトリガー ポイントをカスタマイズする

次のトリガーをカスタマイズできます。

  • Restify ベースの通知:

    • HTTP 要求がエントリ ポイントに src/index.js 送信されると、既定の実装によってアダプティブ カードが Teams に送信されます。 このイベントをカスタマイズするには、 を変更します src/index.js。 一般的な実装では、API を呼び出して、必要に応じてアダプティブ カードを送信できるイベント、データ、またはその両方を取得できます。 トリガーを追加するには、次の操作を実行します。

      • 新しいルーティングをCreateします。 server.post("/api/new-trigger", ...)
      • cronnode-schedule、またはその他のパッケージなど、広く使用されている npm パッケージからタイマー トリガーを追加します。

      注:

      既定では、Teams Toolkit は に 1 つの restify エントリ ポイントを src/index.jsスキャフォールディングします。

  • Azure Functionsベースの通知:

    • トリガーを選択 timer すると、既定で実装されている Azure Function タイマー トリガー src/timerTrigger.ts は、30 秒ごとにアダプティブ カードを送信します。 ファイル *Trigger/function.json を編集してプロパティを schedule カスタマイズできます。 詳細については、 Azure 関数のドキュメントを参照してください

      タイマーによってトリガーされる通知のサンプル

    • トリガーを選択 http すると、HTTP 要求によって通知がトリガーされ、既定の実装によってアダプティブ カードが Teams に送信されます。 このイベントは、 を src/*Trigger.tsカスタマイズして変更できます。 この実装では、API を呼び出してイベント、データ、またはその両方を取得でき、必要に応じてアダプティブ カードを送信できます。

      HTTP によってトリガーされる通知のサンプル

  • Azure 関数トリガー:

    • Event Hub イベントが Azure Event Hub にプッシュされたときに通知を送信するトリガー。

    • Cosmos DB は、Cosmos ドキュメントの作成または更新時に通知を送信するトリガーです。

サポート トリガーの詳細については、「Azure Functionsサポート トリガー」を参照してください。

通知コンテンツをカスタマイズする

このファイル src/adaptiveCards/notification-default.json は、既定のアダプティブ カードを定義します。 アダプティブ カード デザイナーを使用すると、アダプティブ カード UI を視覚的に設計できます。 は src/cardModels.ts 、アダプティブ カードのデータの読み込みに使用されるデータ構造を定義します。 カード モデルとアダプティブ カードの間のバインドは、アダプティブ カード内の に${title}マップなどのCardData.title名前を照合することによって行われます。 プロパティとそのバインドを追加、編集、または削除して、必要に応じてアダプティブ カードをカスタマイズできます。

必要に応じて新しいカードを追加することもできます。 と を使用して動的コンテンツのリストまたはテーブルを使用してColumnSetさまざまな種類のアダプティブ カードを構築する方法の詳細については、「アダプティブ カード通知のサンプル」を参照してください。FactSet

通知の送信先をカスタマイズする

通知を次のターゲットに送信するようにカスタマイズできます。

  • 個人用チャットへの通知:

    // list all installation targets
    for (const target of await notificationApp.notification.installations()) {
        // "Person" means this bot is installed as Personal app
        if (target.type === "Person") {
            // Directly notify the individual person
            await target.sendAdaptiveCard(...);
        }
    }
    

  • グループ チャットへの通知:

    // list all installation targets
    for (const target of await notificationApp.notification.installations()) {
        // "Group" means this bot is installed to a Group Chat
        if (target.type === "Group") {
            // Directly notify the Group Chat
            await target.sendAdaptiveCard(...);
    
                // List all members in the Group Chat then notify each member
                const members = await target.members();
                for (const member of members) {
                    await member.sendAdaptiveCard(...);
                }
            }
    
    }
    

  • チャネルへの通知:

    // list all installation targets
    for (const target of await notificationApp.notification.installations()) {
        // "Channel" means this bot is installed to a Team (default to notify General channel)
        if (target.type === "Channel") {
            // Directly notify the Team (to the default General channel)
            await target.sendAdaptiveCard(...);
    
            // List all members in the Team then notify each member
            const members = await target.members();
            for (const member of members) {
                await member.sendAdaptiveCard(...);
            }
    
            // List all channels in the Team then notify each channel
            const channels = await target.channels();
            for (const channel of channels) {
                await channel.sendAdaptiveCard(...);
            }
        }
    }
    

  • 特定のチャネルへの通知:

    // find the first channel when the predicate is true.
    const channel = await notificationApp.notification.findChannel(c => Promise.resolve(c.info.name === "MyChannelName"));
    
    // send adaptive card to the specific channel.
    await channel?.sendAdaptiveCard(...);
    

    注:

    未定義の出力を防ぐには、チームの [全般] チャネルにボット アプリをインストールしてください。

  • 特定のユーザーへの通知:

    // find the first person when the predicate is true.
    const member = await notificationApp.notification.findMember(m => Promise.resolve(m.account.name === "Bob"));
    
    // send adaptive card to the specific person. 
    await member?.sendAdaptiveCard(...);
    

    注:

    未定義の出力と通知が見つからないのを防ぐには、通知のインストール スコープに特定のユーザーを含める必要があります。

先頭に戻る

初期化をカスタマイズする

通知を送信するには、作成 ConversationBot する必要があります。

注:

コードはプロジェクトで生成されます。

/** Javascript/Typescript: src/internal/initialize.*s **/
const notificationApp = new ConversationBot({
    // The bot id and password to create CloudAdapter.
    // See https://aka.ms/about-bot-adapter to learn more about adapters.
    adapterConfig: {
        MicrosoftAppId: config.botId,
        MicrosoftAppPassword: config.botPassword,
        MicrosoftAppType: "MultiTenant",
    },
    // Enable notification
    notification: {
        enabled: true,
    },
});

先頭に戻る

アダプターをカスタマイズする

独自のアダプターを作成してカスタマイズすることも、初期化後にアダプターをカスタマイズすることもできます。 アダプターを作成するためのコード サンプルを次に示します。

// Create your own adapter
const adapter = new CloudAdapter(...);

// Customize your adapter, e.g., error handling
adapter.onTurnError = ...

const notificationApp = new ConversationBot({
    // use your own adapter
    adapter: adapter;
    ...
});

// Or, customize later
notificationApp.adapter.onTurnError = ...

先頭に戻る

記憶域を追加する

ストレージを使用して通知接続を実装できます。 次のコード サンプルを使用して、独自のストレージを追加できます。

// implement your own storage
class MyStorage implements NotificationTargetStorage {...}
const myStorage = new MyStorage(...);

// initialize ConversationBot with notification enabled and customized storage
const notificationApp = new ConversationBot({
    // The bot id and password to create CloudAdapter.
    // See https://aka.ms/about-bot-adapter to learn more about adapters.
    adapterConfig: {
        MicrosoftAppId: config.botId,
        MicrosoftAppPassword: config.botPassword,
        MicrosoftAppType: "MultiTenant",
    },
    // Enable notification
    notification: {
        enabled: true,
        storage: myStorage,
    },
});

ストレージが指定されていない場合は、通知接続を格納する既定のローカル ファイル ストレージを使用できます。

  • .notification.localstore.json ローカルで実行されている場合。
  • ${process.env.TEMP}/.notification.localstore.jsonが 1 に設定されている場合 process.env.RUNNING_ON_AZURE

既定のローカル ファイル ストレージを使用している場合、Azure Web アプリは、再起動または再デプロイ中にローカル ファイルをAzure Functions クリーンします。 また、Teams からボットをアンインストールしてからインストールして、ストレージへの接続を再度追加することもできます。

NotificationTargetStorage 、Bot Framework SDK の カスタム ストレージとは異なります。 通知ストレージには、、writeおよび の機能が必要readですが、Bot Framework SDK のストレージにはread、、write、および delete 機能があり、機能がありませんlistlistdelete

Azure BLOB ストレージの詳細については、 通知ストレージの実装サンプルに関するページを参照してください。

注:

  • 運用環境では、独自の共有ストレージを使用することをお勧めします。
  • 独自の Bot Framework SDK のストレージ (たとえば) を実装する場合は、 botbuilder-azure-blobs.BlobsStorage通知用に別のストレージを実装する必要があります。 同じ BLOB 接続文字列を別のコンテナーと共有できます。

先頭に戻る

通知 API の認証を追加する

HTTP トリガーを選択した場合、スキャフォールディングされた通知 API では認証または承認が有効になっていません。 運用環境で API を使用する前に、API の認証または承認を必ず追加してください。 次のいずれかのアクションを実行できます。

API の認証または承認ソリューションが増える場合があります。必要に応じて選択できます。

先頭に戻る

既存の API に接続する

必要な SDK がなく、コードで外部 API を呼び出す場合は、Teams: Microsoft Visual Studio Code Teams Toolkit 拡張機能の API コマンドに接続 するか、 TeamsFx CLI の teamsfx add api-connection コマンドを使用して、ターゲット API を呼び出すコードをブートストラップできます。 詳細については、「 既存のサード パーティ製 API を統合する」を参照してください。

Teams ボット アプリケーションまたは Teams 受信 Webhook

TeamsFx では、システムから Teams に通知を送信するのに役立つ 2 つの方法がサポートされています。

  • Teams ボット アプリをCreateします。
  • Teams 受信 Webhook をCreateします。

次の表では、2 つの異なる方法の比較を確認できます。

  Teams ボット アプリ Teams 受信 Webhook
個々のユーザーにメッセージを送信する ✔️
メッセージ グループ チャット ✔️
メッセージ パブリック チャネル ✔️ ✔️
メッセージ プライベート チャネル ✔️
カードメッセージを送信する ✔️ ✔️
ウェルカム メッセージを送信する ✔️
Teams コンテキストを取得する ✔️
Teams でインストール手順を要求する ✔️
Azure リソースを要求する Azure Bot Service

受信 Webhook 通知

受信 Webhook は、アプリから Teams へのメッセージの投稿に役立ちます。 任意のチャネルでチームに対して受信 Webhook が有効になっている場合、HTTPS エンドポイントが公開されます。これは正しい形式の JSON を受け入れ、そのチャネルにメッセージを挿入します。 たとえば、DevOps チャネルで受信 Webhook を作成し、ビルドを構成し、サービスを同時にデプロイおよび監視してアラートを送信することができます。 TeamsFx には、次の操作に役立つ 受信 Webhook 通知サンプル が用意されています。

  • Teams で受信 Webhook をCreateします。
  • アダプティブ カードを使用して受信 Webhook を使用して通知を送信します。

先頭に戻る

アクティビティ フィード通知を送信する

アプリのアクティビティ フィード通知を送信する場合は、Microsoft Graph のアクティビティ フィード通知 API を使用できます。 詳細については、「 Microsoft Teams のユーザーにアクティビティ フィード通知を送信する」を参照してください。

FAQ


ボット アプリが Teams にインストールされているにもかかわらず、通知のインストールが空になるのはなぜですか?

Teams は、最初のインストール時にのみイベントを送信します。 通知ボット サービスが起動される前にボット アプリが既にインストールされている場合は、インストール イベントがボット サービスに到達しなかったか、省略されます。

この問題は、次の方法で解決できます。

  • 個人用ボットにメッセージを送信するか、グループ チャットまたはチャネルでボットをメンションします。これにより、適切なインストール情報を使用してボット サービスに再度アクセスできます。
  • Teams からボット アプリをアンインストールし、再実行するか再起動します。 インストール イベントをボット サービスに再送信できます。

通知ターゲット接続は永続化ストレージに格納されます。 既定のローカル ファイル ストレージを使用している場合、すべてのインストールは の下に .notification.localstore.json格納されます。

注:

独自のストレージを追加する方法の詳細については、「ストレージの 追加」を参照してください。


通知の送信時に不適切な要求または正しくない引数エラーが発生する理由

通知のインストールがボット ID またはパスワードと一致しない場合は、 会話 ID の暗号化解除に失敗するエラーを 受け取ることができます。 このエラーの原因の 1 つは、ローカル状態のクリーニングまたは再プロビジョニングによってボット ID またはパスワードが変更されていることです。

この問題は、通知ストレージをクリーニングすることで解決できます。 クリーニング後、ボットを再インストールするように Teams に通知し、新しいインストールが最新の状態であることを確認します。 各保存済み通知インストールは、1 つのボットにバインドされます。 通知ストレージをチェックできる場合、そのボット フィールドは、実行中のボット (同じ GUID を持つボット ID など) と一致する必要があります。

注:

ローカル ストレージの場合、既定の場所は です .notification.localstore.json


ボット アプリの再起動または再デプロイ後に通知ターゲットが失われるのはなぜですか?

通知ターゲット接続は永続化ストレージに格納されます。 既定のローカル ファイル ストレージを使用している場合、Azure Web アプリは、再起動または再デプロイ中にローカル ファイルをAzure Functions クリーンします。 また、Teams からボットをアンインストールしてからインストールして、ストレージへの接続を再度追加することもできます。 運用環境では、独自の共有ストレージを使用することをお勧めします。


API 'findChannel'()を使用しているときに未定義のエラーが返されるのはなぜですか?

ボット アプリがチャネルではなく他のチャネルにインストールされると、未定義のエラーが発生する General 可能性があります。 このエラーを解決するには、Teams からボット アプリをアンインストールし、再実行して再起動します。 再デバッグして再起動したら、ボット アプリがチャネルに General インストールされていることを確認します。


通知プロジェクトにボットがインストールされているすべてのターゲットを知ることができますか?

チーム、グループ、またはチャットにインストールされているアプリを一覧表示する Microsoft Graph API があります 。 必要に応じて、対象となるインストール済みアプリにチーム、グループ、チャットを繰り返します。 通知プロジェクトでは、永続化ストレージを使用してインストール ターゲットを格納します。 詳細については、「 イベントに基づく通知」を参照してください。


Azurite リッスン ポートをカスタマイズする方法

使用されているポートが原因で Azurite が終了した場合は、別のリッスン ポートを指定し、 で local.settings.json接続文字列AzureWebJobsStorage更新できます。


コマンドと応答をサポートするように通知ボットを拡張する方法
  1. 通知機能を bot\src\internal\initialize.ts(js) 有効にするには、初期化に移動して更新します conversationBot

    通知機能を有効にする会話ボットの初期化。

  2. ボットにコマンドを追加するには、「 Teams のコマンド ボット」の手順に従います。


ワークフロー ボットアダプティブ カード アクションを追加して通知ボットを拡張する方法

アダプティブ カード アクション ハンドラー機能を使用すると、アプリは、エンド ユーザーによってトリガーされるアダプティブ カード アクションに応答して、シーケンシャル ワークフローを完了できます。 アダプティブ カードには、一部の API の呼び出しなど、ユーザーの入力を求める 1 つ以上のボタンがカードに用意されています。 その後、アダプティブ カードは会話で別のアダプティブ カードを送信し、カードアクションに応答します。

アダプティブ カード アクションをコマンド ボットに追加する方法の詳細については、「Teams のワークフロー ボット」を参照してください。


先頭に戻る

ステップ バイ ステップのガイド

Teams 通知ボットを構築するには 、ステップバイステップ ガイドに従います。

関連項目