メッセージ拡張機能を使用してアクションを開始する

重要

このセクションの記事は、v3 Bot Framework SDK に基づいています。 最新のドキュメント (SDK のバージョン 4.6 以降のバージョン) をお探しの場合は、「 メッセージ拡張機能を使用したタスク指向の対話 」セクションを参照してください。

アクションベースのメッセージ拡張機能を使用すると、ユーザーは Teams の使用中に外部サービスのアクションをトリガーできます。

スクリーンショットは、メッセージ拡張機能カードを示す例です。

メッセージ拡張機能をアプリに追加する

メッセージ拡張機能は、ユーザーの要求をリッスンし、カードなどの構造化されたデータで応答するクラウドでホストされるサービスです。 Bot Framework Activity オブジェクトを使用して、サービスと Microsoft Teams を統合します。 Bot Builder SDK 用の .NET および Node.js 拡張機能は、メッセージ拡張機能機能をアプリに追加するのに役立ちます。

Teams のアクションベースのメッセージ拡張機能を示すスクリーンショット。

Bot Framework に登録する

最初にボットを Microsoft Bot Framework に登録する必要があります。 ここで定義されているボットの Microsoft アプリ ID とコールバック エンドポイントは、メッセージ拡張機能でユーザー要求を受信して応答するために使用されます。 ボットの Microsoft Teams チャネルを有効にすることを忘れないでください。

ボット アプリ ID とアプリ パスワードをメモしておきます。アプリ ID をアプリ マニフェストで指定する必要があります。

アプリ マニフェストを更新する

ボットやタブと同様に、メッセージ拡張機能のプロパティを含めるようにアプリの マニフェスト を更新します。 これらのプロパティは、Microsoft Teams クライアントでのメッセージ拡張機能の表示方法と動作方法を制御します。 メッセージ拡張機能は、マニフェスト v1.0 以降でサポートされています。

メッセージ拡張機能を宣言する

メッセージ拡張機能を追加するには、 composeExtensions プロパティを使用して新しいトップレベルの JSON 構造をマニフェストに含めます。 アプリ用に作成できるメッセージ表示オプションは 1 つに制限されます。

マニフェストは、メッセージ拡張機能を composeExtensions と呼んでいます。 これは、下位互換性を維持するためです。

拡張機能定義は、次の構造を持つオブジェクトです。

プロパティ名 用途 必須
botId Bot Framework に登録されているボットの一意の Microsoft アプリ ID。 これは通常、Teams アプリ全体の ID と同じである必要があります。 はい
scopes この拡張機能を personal スコープまたは team スコープ (またはその両方) に追加できるかどうかを宣言する配列。
canUpdateConfiguration 設定メニュー項目を有効にします。 ×
commands このメッセージ拡張機能がサポートするコマンドの配列。 コマンド数は 10 個までです。

アプリ マニフェストで canUpdateConfiguration プロパティを true に設定すると、メッセージ拡張機能の [ 設定 ] メニュー項目を表示することができます。 設定を有効にするには、onQuerySettingsUrlonSettingsUpdateも処理する必要があります。

コマンドを定義する

メッセージ拡張機能では、ユーザーが作成ボックスの [ その他のオプション ()] ボタンからアプリを選択すると表示される 1 つのコマンドを宣言する必要があります。

スクリーンショットは、Teams のメッセージ拡張機能の一覧を示す例です。

アプリ マニフェストでは、コマンド アイテムは次の構造を持つオブジェクトです。

プロパティ名 用途 必須 最小マニフェスト バージョン
id このコマンドに割り当てる一意の ID。 ユーザー要求にはこの ID が含まれます。 はい 1.0
title コマンド名。 この値は UI に表示されます。 はい 1.0
description このコマンドの動作を示すヘルプ テキスト。 この値は UI に表示されます。 1.0
type コマンドの種類を設定します。 指定できる値は、 queryaction です。 存在しない場合は、既定値は query に設定されます。 × 1.4
initialRun query コマンドで使用される省略可能なパラメーター。 true に設定すると、ユーザーが UI でこのコマンドを選択するとすぐにこのコマンドが実行されることを示します。 × 1.0
fetchTask action コマンドで使用される省略可能なパラメーター。 タスク モジュール内に表示するアダプティブ カードまたは Web URL をフェッチする場合は、true に設定します。 これは、 action コマンドへの入力が静的なパラメーター セットではなく動的である場合に使用されます。 true に設定すると、コマンドの静的パラメーター リストは無視されることに注意してください。 × 1.4
parameters コマンドのパラメーターの静的リスト。 はい 1.0
parameter.name パラメーターの名前。 これは、ユーザー要求でサービスに送信されます。 はい 1.0
parameter.description このパラメーターの目的と、指定する必要がある値の例について説明します。 この値は UI に表示されます。 1.0
parameter.title 短くユーザー フレンドリーなパラメーターのタイトルまたはラベル。 1.0
parameter.inputType 必要な入力の種類に設定します。 使用可能な値は、 texttextareanumberdatetimetoggle です。 既定値は text に設定されています。 × 1.4
context メッセージ アクションを使用できるコンテキストを定義する値の配列 (オプション)。 指定可能な値は、 messagecompose、または commandBox です。 既定値は ["compose", "commandBox"] です。 × 1.5

アクション タイプ メッセージ表示オプション

メッセージ拡張機能からアクションを開始するには、 type パラメーターを action に設定します。 1 つのメッセージ拡張機能に、最大 10 個の異なるコマンドを含めることができ、検索ベースとアクションベースの複数のコマンドを含めることができます。

完全なアプリ マニフェストの例

次のコードは、検索コマンドと作成コマンドを含むマニフェストの例です。

{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
  "manifestVersion": "1.5",
  "version": "1.0",
  "id": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
  "developer": {
    "name": "John Developer",
    "websiteUrl": "http://todobotservice.azurewebsites.net/",
    "privacyUrl": "http://todobotservice.azurewebsites.net/privacy",
    "termsOfUseUrl": "http://todobotservice.azurewebsites.net/termsofuse"
  },
  "name": {
    "short": "To Do",
    "full": "To Do"
  },
  "description": {
    "short": "Find or create a new task in To Do",
    "full": "Find or create a new task in To Do"
  },
  "icons": {
    "outline": "todo-outline.jpg",
    "color": "todo-color.jpg"
  },
  "accentColor": "#ff6a00",
  "composeExtensions": [
    {
      "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
      "canUpdateConfiguration": true,
      "commands": [
        {
          "id": "searchCmd",
          "description": "Search you Todo's",
          "title": "Search",
          "initialRun": true,
          "context": ["commandBox", "compose"],
          "parameters": [
            {
              "name": "searchKeyword",
              "description": "Enter your search keywords",
              "title": "Keywords"
            }
          ]
        },
        {
          "id": "addTodo",
          "description": "Create a To Do item",
          "title": "Create To Do",
          "type": "action",
          "context": ["commandBox", "message", "compose"],
          "parameters": [
            {
              "name": "Name",
              "description": "To Do Title",
              "title": "Title",
              "inputType": "text"
            },
            {
              "name": "Description",
              "description": "Description of the task",
              "title": "Description",
              "inputType": "textarea"
            },
            {
              "name": "Date",
              "description": "Due date for the task",
              "title": "Date",
              "inputType": "date"
            }
          ]
        },
        {
          "id": "reassignTodo",
          "description": "Reassign a todo item",
          "title": "Reassign a todo item",
          "type": "action",
          "fetchTask": false,
          "parameters": [
            {
              "name": "Name",
              "title": "Title"
              "inputType": "text"
            }
          ]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "todobotservice.azurewebsites.net",
    "*.todobotservice.azurewebsites.net"
  ]
}

メッセージからアクションを開始する

メッセージ作成領域からアクションを開始できるほか、メッセージ拡張機能を使用してメッセージからアクションを開始することもできます。これにより、メッセージの内容をボットに送信して処理できます。 必要に応じて、「 送信に応答する」で説明されている方法を使用して、そのメッセージに応答できます。 応答はメッセージへの返信として含まれます。ユーザーは送信前に編集できます。

ユーザーは、次の図に示すように、オーバーフロー ... メニューの [アクションの実行] オプションからメッセージ拡張機能にアクセスできます。

スクリーンショットは、メッセージからアクションを開始する方法について説明しています。

メッセージ拡張機能がメッセージから動作できるようにするには、次の例のように、アプリ マニフェストのメッセージ拡張機能の commands オブジェクトに context パラメーターを追加します。 context 配列の有効な文字列は、"message""commandBox"、および "compose" です。 既定値は ["compose", "commandBox"] です。 context パラメーターの詳細については、「コマンドの定義」セクションを参照してください。

"composeExtensions": [
  {
    "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
    "canUpdateConfiguration": true,
    "commands": [
      {
        "id": "reassignTodo",
        "description": "Reassign a todo item",
        "title": "Create To Do",
        "type": "Action",
        "context": ["message"],
        "fetchTask": true
    }]
    ...

次のコードは、ボットへのcomposeExtensions要求の一部として送信されるメッセージの詳細を含む value オブジェクトの例です。

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
...
  "value": {
    "commandId": "setReminder",
    "commandContext": "message",
    "messagePayload": {
      "id": "1111111111",
      "replyToId": null,
      "createdDateTime": "2019-02-25T21:29:36.065Z",
      "lastModifiedDateTime": null,
      "deleted": false,
      "subject": "Message subject",
      "summary": null,
      "importance": "normal",
      "locale": "en-us",
      "body": {
        "contentType": "html",
        "content": "this is the message"
    },
      "from": {
        "device": null,
        "conversation": null,
        "user": {
          "userIdentityType": "aadUser",
          "id": "wxyz12ab8-ab12-cd34-ef56-098abc123876",
          "displayName": "Jamie Smythe"
        },
        "application": null
      },
      "reactions": [
        {
          "reactionType": "like",
          "createdDateTime": "2019-02-25T22:40:40.806Z",
          "user": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "qrst12346-ab12-cd34-ef56-098abc123876",
              "displayName": "Jim Brown"
            },
            "application": null
          }
        }
      ],
      "mentions": [
        {
          "id": 0,
          "mentionText": "Sarah",
          "mentioned": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "ab12345678-ab12-cd34-ef56-098abc123876",
              "displayName": "Sarah"
            },
            "application": null
          }
        }
      ]
    }
  ...

アップロードによるテスト

アプリをアップロードすることで、メッセージ拡張機能をテストできます。 詳細については、「 チームにアプリをアップロードする」を参照してください。

メッセージ拡張機能を開くには、チャットまたはチャネルのいずれかに移動します。 作成ボックスの [ その他のオプション ] () ボタンを選択し、メッセージ表示オプションを選択します。

ユーザーからの入力の収集

Teams でユーザーから情報を収集するには、3 つの方法があります。

静的パラメーター リスト

この方法では、"Create To Do" コマンドに示すように、マニフェストでパラメーターの静的リストを定義するだけです。 このメソッドを使用するには、 fetchTaskfalse に設定されていることと、マニフェストでパラメーターを定義していることを確認します。

ユーザーが静的パラメーターを含むコマンドを選択すると、Teams はマニフェストで定義されたパラメーターを含むフォームをタスク モジュールに生成します。 [送信] をクリックすると、 composeExtensions/submitAction がボットに送信されます。 予想される応答のセットの詳細については、「 送信への応答」を参照してください。

アダプティブ カードを使用した動的入力

この方法では、カスタム アダプティブ カードを定義してユーザー入力を収集できます。 この方法では、マニフェストで fetchTask パラメーターを true に設定します。 fetchTasktrue に設定すると、コマンドに定義されている静的パラメーターは無視されます。

この方法では、サービスは composeExtensions/fetchTask イベントを受信し、アダプティブ カード ベースの タスク モジュール応答で応答します。 アダプティブ カードを使用した応答の例を次に示します。

{
    "task": {
        "type": "continue",
        "value": {
            "card": {
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": {
                    "body": [
                        {
                            "type": "TextBlock",
                            "text": "Please enter the following information:"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Name"
                        },
                        {
                            "type": "Input.Text",
                            "spacing": "None",
                            "title": "New Input.Toggle",
                            "placeholder": "Placeholder text"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Date of birth"
                        },
                        {
                            "type": "Input.Date",
                            "spacing": "None",
                            "title": "New Input.Toggle"
                        }
                    ],
                    "type": "AdaptiveCard",
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "version": "1.0"
                }
            }
        }
    }
}

ユーザーがユーザー入力を取得する前に拡張機能を認証または構成する必要がある場合、ボットは認証/構成応答で応答することもできます。

Web ビューを使用した動的入力

この方法では、サービスで <iframe> ベースのウィジェットを表示してカスタム UI を表示し、ユーザー入力を収集できます。 この方法では、マニフェストで fetchTask パラメーターを true に設定します。

アダプティブ カード フローと同様に、サービスは fetchTask イベントを送信し、URL ベースの タスク モジュール応答で応答します。 アダプティブ カードを使用した応答の例を次に示します。

{
    "task": {
        "value": {
            "url": "http://mywebapp.com/input"
        },
        "type": "continue"
    }
}

会話型ボットのインストールをリクエストする

アプリに会話ボットが含まれている場合は、タスク モジュールを読み込む前に会話にインストールされていることを確認して、タスク モジュールのコンテキストを詳しく取得します。 たとえば、ユーザー ピッカー コントロールやチーム内のチャネルの一覧を設定するために名簿をフェッチする必要がある場合があります。

このフローを容易にするには、メッセージ拡張機能が最初に composeExtensions/fetchTask 呼び出しを受信したときに、ボットが現在のコンテキストにインストールされているかどうかをチェック確認します。 これは、get roster 呼び出しを試行することによって取得できます。 たとえば、ボットがインストールされていない場合は、ボットのインストールをユーザーに要求するアクションを含むアダプティブ カードを返します。 ユーザーには、その場所にアプリをインストールするためのアクセス許可が必要です。 インストールできない場合は、管理者に問い合わせるよう求めるメッセージが表示されます。

応答の例を次に示します。

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "text": "Looks like you haven't used Disco in this team/chat"
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Continue",
      "data": {
        "msteams": {
          "justInTimeInstall": true
        }
      }
    }
  ],
  "version": "1.0"
}

ユーザーがインストールを完了すると、ボットは name = composeExtensions/submitActionvalue.data.msteams.justInTimeInstall = true を含む別の呼び出しメッセージを受け取ります。

呼び出しの例を次に示します。

{
  "value": {
    "commandId": "giveKudos",
    "commandContext": "compose",
    "context": {
      "theme": "default"
    },
    "data": {
      "msteams": {
        "justInTimeInstall": true
      }
    }
  },
  "conversation": {
    "id": "19:7705841b240044b297123ad7f9c99217@thread.skype"
  },
  "name": "composeExtension/submitAction",
  "imdisplayname": "Bob Smith"
}

ボットがインストールされている場合は、応答したのと同じタスク応答を使用して呼び出しに応答します。

送信に応答する

ユーザーが入力の入力を完了すると、ボットはコマンド ID とパラメーター値が設定された composeExtensions/submitAction イベントを受け取ります。

これらは、 submitActionに対して期待されるさまざまな応答です。

タスク モジュールの応答

タスク モジュールの応答は、拡張機能がダイアログをチェーンして、より多くの情報を取得する必要がある場合に使用されます。 応答は前述の fetchTask と同じです。

拡張機能の認証/構成応答のCompose

拡張機能の認証/構成応答の Compose は、拡張機能を認証するか、続行するために構成する必要がある場合に使用されます。 詳細については、検索セクションの 認証セクション を参照してください。

Compose 拡張機能の結果応答

Compose 拡張機能の結果応答は、コマンドの結果として作成ボックスにカードを挿入するために使用されます。 これは検索コマンドで使用される応答と同じですが、配列内の 1 つのカードまたは 1 つの結果に制限されます。

{
  "composeExtension": {
    "type": "result",
    "attachmentLayout": "list",
    "preview": {
          "contentType": "application/vnd.microsoft.card.thumbnail",
          "content": {
            "title": "85069: Create a cool app",
            "images": [
              {
                "url": "https://placekitten.com/200/200"
              }
            ]
          }
        },
    "attachments": [
      {  
        "contentType": "application/vnd.microsoft.teams.card.o365connector",
        "content": {
          "sections": [
            {
              "activityTitle": "[85069]: Create a cool app",
              "activityImage": "https://placekitten.com/200/200"
            },
            {
              "title": "Details",
              "facts": [
                {
                  "name": "Assigned to:",
                  "value": "[Larry Brown](mailto:larryb@example.com)"
                },
                {
                  "name": "State:",
                  "value": "Active"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

ボットから送信されたアダプティブ カード メッセージで応答する

ボットを使用してチャネルにアダプティブ カードを含むメッセージを挿入して、送信アクションに応答します。 ユーザーは、メッセージを送信する前にプレビューすることができます。また、メッセージを編集したり操作したりすることもできます。 これは、アダプティブ カード応答を作成する前にユーザーから情報を収集する必要があるシナリオに役立ちます。 次のシナリオでは、チャネル メッセージに構成手順を含めずに、このフローを使用して投票を構成する方法を示しています。

  1. ユーザーがメッセージ拡張機能を選択して、タスク モジュールをトリガーします。
  2. ユーザーは、タスク モジュールを使用して投票を構成します。
  3. 構成タスク モジュールを送信すると、アプリはタスク モジュールで提供された情報を使用してアダプティブ カードを作成し、 botMessagePreview 応答としてクライアントに送信します。
  4. これにより、ボットがチャネルに挿入する前に、ユーザーはアダプティブ カード メッセージをプレビューできます。 ボットがまだチャネルのメンバーではない場合は、[ Send ] をクリックするとボットが追加されます。
  5. アダプティブ カードを操作すると、送信前にメッセージが変更されます。
  6. ユーザーが Send を選択すると、ボットはメッセージをチャネルに投稿します。

  • activityPreviewには、アダプティブ カードが添付されたmessageアクティビティが 1 つだけ含まれている必要があります。
  • Outlook では、ボットから送信されたアダプティブ カード メッセージでの応答はサポートされていません。

このフローを有効にするには、タスク モジュールが次の例のように応答する必要があります。これにより、プレビュー メッセージがユーザーに表示されます。

{
  "composeExtension": {
    "type": "botMessagePreview",
    "activityPreview": {
      "type": "message",
      "attachments":  [
        {
          "contentType": "application/vnd.microsoft.card.adaptive",
          "content": << Card Payload >>
        }
      ]
    }
  }
}

メッセージ拡張機能は、 value.botMessagePreviewAction = "send"value.botMessagePreviewAction = "edit" という 2 つの新しいタイプの対話に応答する必要があります。 次のコードは、処理する必要がある value オブジェクトの例です。

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
  "conversation": { "id": "19:c366b75791784100b6e8b515fd55b063@thread.skype" },
  "imdisplayname": "Pranav Smith",
  ...
  "value": {
    "botMessagePreviewAction": "send" | "edit",
    "botActivityPreview": [
      {
        "type": "message/card",
        "attachments": [
          {
            "content":
              {
                "type": "AdaptiveCard",
                "body": [{<<card payload>>}]
              },
            "contentType" : "application/vnd.microsoft.card.adaptive"
          }
        ],
        "context": { "theme": "default" }
      }
    ],
  }
}

edit要求に応答するときは、ユーザーが送信した情報が入力された値を使用してtask応答する必要があります。 send要求に応答するときは、完成したアダプティブ カードを含むチャネルにメッセージを送信する必要があります。

teamChatConnector.onComposeExtensionSubmitAction((
    event: builder.IEvent,
    request: teamBuilder.IComposeExtensionActionCommandRequest,
    callback: (err: Error, result: any, statusCode: number) => void) => {
        let invokeValue = (<any> event).value;

        if (invokeValue.botMessagePreviewAction ) {
            let attachment = invokeValue.botActivityPreview[0].attachments[0];

            if (invokeValue.botMessagePreviewAction === 'send') {
                let msg = new builder.Message()
                    .address(event.address)
                    .addAttachment(attachment);
                teamChatConnector.send([msg.toMessage()],
                    (error) => {
                        if(error){
                            // TODO: Handle error and callback.
                        }
                        else {
                            callback(null, null, 200);
                        }
                    }
                );
            }

            else if (invokeValue.botMessagePreviewAction === 'edit') {
              // Create the card and populate with user-inputted information.
              let card = { ... }

              let taskResponse = {
                task: {
                  type: "continue",
                  value: {
                    title: "Card Preview",
                    card: {
                      contentType: 'application/vnd.microsoft.card.adaptive',
                      content: card
                    }
                  }
                }
              }
              callback(null, taskResponse, 200);
            }

        else {
            let attachment = {
                  // Create Adaptive Card.
                };
            let activity = new builder.Message().addAttachment(attachment).toMessage();
            let response = teamBuilder.ComposeExtensionResponse.messagePreview()
                .preview(activity)
                .toResponse();
            callback(null, response, 200);
        }
    });

関連項目

Bot Framework サンプル