Teams のワークフロー ボット

ワークフロー ボットを使用すると、ユーザーはアダプティブ カードと対話できます。 アダプティブ カード アクション ハンドラーを使用すると、アダプティブ カードを Teams アプリで会話できます。 インシデント管理、チケット発行、承認ワークフロー、プロジェクト管理カードなどのユーザー エクスペリエンスを強化するために、ユーザーが複数のシナリオでワークフロー ボットを作成できます。 ワークフロー ボットを使用して作業項目を作成して割り当て、コンテンツを Azure DevOps または Jira システムに同期できます。

ワークフロー ボットは、さまざまなスコープに応じて、チーム、グループ チャット、または個人用アプリにインストールできます。 既定のコマンド ロジックはアダプティブ カードを返します。 このロジックは、ビジネス要件を使用してカスタマイズできます。 カスタマイズするには、既存の API を呼び出す必要があります。

利点:

  • 会話のコンテキストを離れることなく、ビジネス プロセスと反復的なワークフローを自動化します。

  • 追加のカードを送信することなく、さまざまなカードを介して順次ワークフローを使用するユーザーをサポートします。

  • ユーザー固有の最新のビューを提供します。

  • TeamsFx SDK を使用してプログラミング モデルを簡略化します。

    注:

    アプリを追加するときに、インストールする機能を選択できます。 詳細については、「既定の インストール オプションを構成する」を参照してください。

ユーザーによってトリガーされるアダプティブ カードに応答するワークフロー ボットを作成できます。 TeamsFx SDK を利用するアダプティブ カード アクション ハンドラーは、ユーザーによってトリガーされるアダプティブ カード ユニバーサル アクション Action.Execute 実行できます。 会話内のこのそれぞれのカード アクションに応答して、アダプティブ カード アクション ハンドラーは別のアダプティブ カードを送信します。

Teams のワークフロー ボットの最終的な出力を示すスクリーンショット。

カード アクション ハンドラー

ワークフロー ボットの作成を簡略化するために、TeamsFx SDK にはアダプティブ カード アクション ハンドラー TeamsFxAdaptiveCardActionHandlerが用意されています。 Bot Framework を学習せずにカード アクションに応答するには、ワークフロー ボットの開発にのみ集中できます。

次の図は、TeamsFx SDK を使用してアダプティブ カード アクションに応答する方法を示しています。

図は、ワークフロー ボット カードのアクション ハンドラーを示しています。

  1. アクション カード: ユーザーが呼び出すことができるアクション ( DoStuffなど) を定義するカード。
  2. カード アクション ハンドラー: ユーザーが対応するカード アクションを呼び出すとトリガーされ、その triggerVerb はアダプティブ カード アクションの verb プロパティと同じです。 応答カードを送信してアクションに応答できます。
  3. 応答カード: ユーザーがアクション カードからアクションを呼び出したときにアクションに応答するカード。

TeamsFx SDK でカード アクションを処理するには、各カード アクション ハンドラーで TeamsFxAdaptiveCardActionHandler インターフェイスを実装する必要があります。


TeamsFxAdaptiveCardActionHandler 
{
    /**
     * The verb defined in adaptive card action that can trigger this handler.
     */
    triggerVerb: string;

    /**
     * Specify the behavior for how the card response will be sent in Teams conversation.
     * The default value is `AdaptiveCardResponse.ReplaceForInteractor`, which means the card
     * response will replace the current one only for the interactor.
     */
    adaptiveCardResponse?: AdaptiveCardResponse;
    
    /**
     * The handler function that will be invoked when the action is fired.
     * @param context The turn context.
     * @param actionData The contextual data that associated with the action.
     */
    handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse>;
}

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

ワークフロー ボットは、独自のアダプターで初期化することも、初期化後にカスタマイズすることもできます。 既定の初期化は、 bot/src/internal/initialize.js(ts)にあります。

初期化ロジックは、次に更新できます。

  1. options.adapterを設定して、独自のBotFrameworkAdapterを使用します。
  2. options.command.commandsを設定して、複数のコマンド ハンドラーを含めます。
  3. options.cardAction.actionsを設定して、複数のアクション ハンドラーを含めます。
  4. 複数のConversationBot機能を有効にするには、options.{feature}.enabledを設定します。

初期化のカスタマイズの詳細については、「その他の初期化カスタマイズ」を参照してください。

カード アクションを追加する

JavaScript と TypeScript でカード アクションを追加するには、次の手順に従います。


1. アダプティブ カードにアクションを追加する

新しいアクション (ボタン) をアダプティブ カードに追加するには、JSON ファイルで定義します (src/adaptiveCards/helloworldCommandResponse.json ファイルに新しいDoSomethingアクションを追加するなど)。

次のコードは、アクションの種類 Action.Executeの例です。

{ 
  "type": "AdaptiveCard", 
  "body": [
    ...
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.Execute",
          "title": "DoSomething",
          "verb": "doSomething" 
        }
      ]
    },
    ...
  ]
}

Teams でアクションが呼び出されると、TeamsFx 会話 SDK が対応するアクション ハンドラーを呼び出すことができるように、verb プロパティが必要です。

注:

他のボットと競合する可能性がある一般的な文字列を使用している場合は、動詞プロパティにグローバル一意の文字列を指定してください。 これにより、予期しない動作を回避できます。


2. 新しいアダプティブ カードで対応する

呼び出されたアクションごとに新しいアダプティブ カードを返して、エンド ユーザーに応答を表示できます。 次の内容を含むdoSomethingアクションの応答としてbot/src/adaptiveCards/doSomethingResponse.json、新しいファイルを作成する必要があります。

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "size": "Medium",
      "weight": "Bolder",
      "text": "A sample response to DoSomething."
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4"
}

注:

ビジネス ニーズに応じてカード レイアウトを設計できます。 アダプティブ カード デザイナーに関するページを参照してください。


3. アクション ハンドラーを追加する

アダプティブ カードによって呼び出された新しいアクションは、TeamsFx SDK のクラス TeamsFxAdaptiveCardActionHandlerで処理できます。 この手順では、API の呼び出し、データの処理、ビジネスニーズに応じてその他のアクションをカスタマイズする必要があります。

新しいファイル bot/src/cardActions/doSomethingActionHandler.js作成できます。

    const { AdaptiveCards } = require("@microsoft/adaptivecards-tools");
    const { AdaptiveCardResponse, InvokeResponseFactory } = require("@microsoft/teamsfx");
    const responseCard = require("../adaptiveCards/doSomethingResponse.json");

    class DoSomethingActionHandler { 
    triggerVerb = "doStuff";

        async handleActionInvoked(context, message) { 
            const responseCardJson = AdaptiveCards.declare(responseCard).render(actionData);
            return InvokeResponseFactory.adaptiveCard(responseCardJson);
        }
    }

     module.exports = {

       DoSomethingActionHandler,
    }

注:

  • triggerVerb は、アクションの verb プロパティです。
  • actionData はアクションに関連付けられたデータであり、動的ユーザー入力や、アクションの data プロパティで提供されるコンテキスト データが含まれる場合があります。
  • アダプティブ カードが返された場合、既存のカードは既定でそれに置き換えられます。

4. アクション ハンドラーを登録する

ワークフロー ボット テンプレートの会話フローを有効にする、 conversationBot で各新しいカード アクションを構成する必要があります。 bot/src/internal/initialize.js(ts) ファイルに移動し、cardAction プロパティのactions配列を更新できます。

次の手順は、アクション ハンドラーを登録するのに役立ちます。

  1. ファイル bot/src/internal/initialize.js(ts)を開くことができます。

  2. cardAction機能を有効にするには、conversationBotの初期化を更新する必要があります。 次のコードを使用して、ハンドラー actions 配列に追加します。

          const conversationBot = new ConversationBot({ 
         ... 
         cardAction: { 
           enabled: true, 
           actions: [ 
             new DoStuffActionHandler(),
             new DoSomethingActionHandler() 
           ], 
         } 
       });
    

    注:

    ワークフロー ボット テンプレートの拡張の詳細については、「Teams でのカード アクションへの応答」を参照してください。


アクション応答をカスタマイズする

ハンドラーの adaptiveCardResponse プロパティを使用して、ボットがアダプティブ カードをユーザーに送信する方法をカスタマイズできます。 カスタマイズする 3 つのオプションを次に示します。

  • 応答カードは、アクションをトリガーする対話機能に対してボタンが定義されている現在のカードに置き換えられます。 会話内のユーザーは、既定で元のアクション カード AdaptiveCardResponse.ReplaceForInteractor を引き続き表示できます。

    ボットがアダプティブ カードを送信する方法をカスタマイズする方法を示すスクリーンショット。

  • 応答カードは、チャット内のすべてのユーザーのアクション カードに置き換えられ、応答カードの AdaptiveCardResponse.ReplaceForAllを表示できます。

    チャット内のすべてのユーザーのアクション カードが [確認] ボタンで置き換えられた状態を示すスクリーンショット。

    [確認] ボタンのないチャット内のすべてのユーザーに対して置き換えられたアクション カードを示すスクリーンショット。

  • 応答カードは、アクション カードを置き換えることができない別のメッセージとして会話に送信されます。 チャット内のすべてのユーザーは、応答カードの AdaptiveCardResponse.NewForAllを表示できます。

    スクリーンショットは、チャット内のすべてのユーザーに対して送信された応答カードを別のメッセージとして示しています。

テキスト メッセージで応答する

また、次の InvokeResponseFactory.textMessageを使用して、カード アクションの応答にアダプティブ カードを使用する代わりにテキスト メッセージで応答することもできます。

async handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse> {
    return InvokeResponseFactory.textMessage("This is a sample card action response!");
}

Teams では、次の応答メッセージが表示されます。

サンプル カードの応答を示すスクリーンショット。

エラー メッセージで応答する

エラー応答メッセージをクライアントに返す場合は、 InvokeResponseFactory.errorResponse を適用して呼び出し応答を作成できます。 次の図は、アダプティブ カードのエラー メッセージを示しています。

エラー応答メッセージを示すスクリーンショット。

注:

呼び出し応答形式の詳細については、「 応答形式」を参照してください。

アダプティブ カードのコンテンツをカスタマイズする

ファイル src/adaptiveCards/helloworldCommand.json を編集して、好みに合わせてアダプティブ カードをカスタマイズできます。 ファイル src/cardModels.ts は、アダプティブ カードのデータを入力するために使用されるデータ構造を定義します。

モデルとアダプティブ カードの間のバインドは、アダプティブ カード内の${title}にマップCardData.titleなど、一致する名前によって行われます。 プロパティとそのバインドを追加、編集、または削除して、ニーズに合わせてアダプティブ カードをカスタマイズできます。

アプリケーションに必要な場合は、新しいカードを追加することもできます。 ColumnSetFactSetを使用して、リストまたは動的コンテンツのテーブルを使用してさまざまな種類のアダプティブ カードを構築するには、「TeamsFx-Samples」を参照してください。

ユーザー固有のビューへの自動更新

アダプティブ カードが Teams チャネルまたはグループ チャットで送信されると、すべてのユーザーが同じカード コンテンツを表示できます。 アダプティブ カードユニバーサル アクションの新しい更新モデルを使用すると、ユーザーはユーザー固有のビューを使用できます。 自動更新により、承認、投票作成者コントロール、チケット作成、インシデント管理、プロジェクト管理カードなどのシナリオも容易になります。 次の図は、 refresh モデルでユーザー固有のビューを提供する方法を示しています。

図は、ユーザー固有の自動更新モデルを示しています。

  1. ベース カード: ボットは、カードの基本バージョンを含むメッセージを送信します。 この基本カードは、ボット通知、コマンド応答、またはその他のカード アクション応答として送信できます。 会話のすべてのメンバーは、同じ応答を表示できます。 ベース カードは、ベース カードの refresh プロパティでユーザー定義のuserIdに自動的に更新されます。

  2. 更新動作: ユーザーがメッセージを表示すると、Teams クライアントは最後の更新応答の 1 分後に自動的に更新をトリガーします。 ユーザー固有のビュー ハンドラーが呼び出され、特定のユーザー UserAのカード ビュー Response Cardが返されます。 会話内の他のユーザーは引き続きベース カードを表示できます。

次の図は、Teams でのユーザー固有のビューの表示方法を示しています。

Teams のユーザー固有のビューを示すスクリーンショット。

ユーザー固有のビューを追加する

次の手順は、TeamsFx SDK を使用してユーザー固有のビューを追加するのに役立ちます。


1. 基本アダプティブ カードで更新を有効にする

ユーザー固有のビューの自動更新に示すように、応答カードがベース カードから更新されると、 ユーザー固有のビューはベース カードから更新されます。 ベース カードで自動更新を有効にするには、次のようにします。

  • 最初のオプションでは、SDK を使用してユーザー固有のビューの更新を有効にします。 基本カードは、コマンド応答またはカード アクション応答として送信できます。 ユーザー固有のビュー更新は、コマンド ハンドラーの handleCommandReceived 、または基本カードが返されるカード アクション ハンドラーの handleActionInvoked で有効にすることができます。 @microsoft/adaptivecards-tools ライブラリの refresh(refreshVerb, userIds, data) メソッドを使用して、ベース カードに更新セクションを挿入できます。 更新セクションを定義するには、次のプロパティを指定してください。

    1. userIds: 自動更新をトリガーできるユーザーの MRI のセット。 アダプティブ カードの更新セクション userIds リストに追加する方法の詳細については、「 名簿またはユーザー プロファイルをフェッチする」を参照してください。
    2. verb: 更新アクションを識別する文字列。
    3. data: 更新アクションに関連付ける省略可能なデータ。

    次の例では、基本カードがコマンド応答として返され、コマンド送信者など、特定のユーザーに対して自動更新できます。

             import baseCard from "../adaptiveCards/baseCard.json";
             import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
    
             export class MyCommandHandler1 implements TeamsFxBotCommandHandler {
             triggerPatterns: TriggerPatterns = "helloWorld";
    
             async handleCommandReceived(context: TurnContext, message: CommandMessage): 
             Promise<string | Partial<Activity> | void> {
             const refreshVerb = "userViewRefresh";        // verb to identify the refresh action
             const userIds = [ context.activity.from.id ]; // users who will be refreshed
             const data = { key: "value"};                 // optional data associated with the action
    
             const responseCard = AdaptiveCards
               .declare(baseCard)
               .refresh(refreshVerb, userIds, data)
               .render(cardData);
    
                 return MessageFactory.attachment(CardFactory.adaptiveCard(responseCard));
             }
           }
    
  • 2 番目のオプションを使用すると、ユーザー固有のビューでアダプティブ カードを更新できます。 これは、 baseCard.jsonで定義されているサンプル更新アクションです。

    {
      "type": "AdaptiveCard",
      "refresh": {
        "action": {
          "type": "Action.Execute",
          "title": "Refresh",
          "verb": "userViewRefresh" ,
          "data": {
            "key": "value"
          }
        },
        "userIds": [
          "${userID}"
        ]
      },
      "body": [
        ...
      ],
      ...
    }
    
    

    カードコンテンツをレンダリングしながら、 ${userID} をコード内のユーザーMRIに置き換える必要があります。


2. ユーザー固有のアダプティブ カードを追加する

更新動作の図に示されているuserAresponseCard.jsonなど、特定の応答カードを更新するには、ユーザー固有のアダプティブ カードを設計する必要があります。 開始するには、次のコンテンツを含む responseCard.json を作成し、 bot/src/adaptiveCards フォルダーに保存します。

-
{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "size": "Medium",
      "weight": "Bolder",
      "text": "This is a user-specific view"
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4"
}


3. カード アクション ハンドラーを追加してビューを更新する

Teams で自動的にトリガーされる更新呼び出しアクティビティを処理する TeamsFxAdaptiveCardActionHandler を実装するハンドラーを追加できます。

import responseCard from "../adaptiveCards/responseCard.json";

export class Handler1 implements TeamsFxBotCardActionHandler {
    triggerVerb: string = "userViewRefresh";

    async handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse> {
      /**
       * If you have multiple userIds defined in your refresh action, for example: userIds: [ "<UserA>", "<userB>" ] ,
       * and you can return different card response for those users respectively with the following code sample.
        
        const currentUserId = context.activity.from.id;
        switch (currentUserId) {
          case "<userA's id>":
            const card1 = AdaptiveCards.declare(card1).render(actionData);
            return InvokeResponseFactory.adaptiveCard(card1);
          case "<userB's id>":
            const card1 = AdaptiveCards.declare(card2).render(actionData);
            return InvokeResponseFactory.adaptiveCard(card2);
        }
     */
      const responseCardJson = AdaptiveCards.declare(responseCard).render(actionData);
      return InvokeResponseFactory.adaptiveCard(responseCardJson);
    } 
}

4. アクション ハンドラーを登録する

更新アクション ハンドラーを bot/src/internal/initialize.js(ts) に登録するには、次のコードを使用します。

export const commandBot = new ConversationBot({
  ...
  cardAction: {
    enabled: true,
    actions: [
      new Handler1()
    ],
  }
})


Microsoft Graph にアクセスする

既にサインインしている Teams ユーザーの Microsoft Graph データにアクセスする必要があるコマンドに応答する場合は、Teams ユーザー トークンを使用してシングル サインオン (SSO) することで応答できます。 Teams ツールキットを使用して Teams アプリにシングル サインオンを追加する方法について詳しくは、こちらをご覧ください。

既存の API に接続する

Teams に送信するデータを取得するには、多くの場合、既存の API に接続する必要があります。 Teams Toolkit を使用すると、既存の API の認証を簡単に構成および管理できます。 詳細については、 既存のサード パーティ API を統合する方法に関するページを参照してください。

FAQ


通知を使用してワークフロー ボットを拡張する方法

通知は、アプリで外部イベントに応答してアダプティブ カードを送信する機能を追加します。 たとえば、メッセージが Event Hub に投稿されると、アプリは必要に応じてアダプティブ カードで応答できます。 通知を使用してワークフロー ボットを拡張する方法については、「 通知のカスタマイズ」を参照してください。


コマンドと応答を使用してワークフロー ボットを拡張する方法

既定のワークフロー ボットには、コマンドと応答が付属しています。 コマンドと応答を使用してワークフロー ボットを拡張する方法の詳細については、「 コマンドと応答の追加」を参照してください。


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

Teams ワークフロー ボットを構築するには 、ステップバイステップ ガイドに従います。

関連項目