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

重要

このセクションの記事は、v3 Bot Framework SDK に基づいています。 現在のドキュメント (バージョン 4.6 以降の SDK) を探している場合は、 メッセージ拡張機能に関するタスク指向の操作に関する セクションを参照してください。

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

メッセージ拡張カードの例

次のセクションでは、これを行う方法について説明します。

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

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

メッセージ拡張機能のメッセージ フローの図

Bot Framework に登録する

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

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

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

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

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

メッセージ拡張機能を追加するには、プロパティを使用してマニフェストに新しい最上位レベルの JSON 構造を composeExtensions 含めます。 現時点では、アプリ用に 1 つのメッセージ拡張機能を作成することに制限されています。

注意

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

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

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

コマンドを定義する

メッセージ拡張機能は 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 入力が動的な場合に使用されます。 if が true に設定されている場合、コマンドの静的パラメーター リストは無視されることに注意してください。 なし 1.4
parameters コマンドのパラメーターの静的リスト。 はい 1.0
parameter.name パラメーターの名前です。 これは、ユーザー要求でサービスに送信されます。 はい 1.0
parameter.description このパラメーターの目的または指定する必要がある値の例について説明します。 この値は UI に表示されます。 はい 1.0
parameter.title 短いわかりやすいパラメーターのタイトルまたはラベル。 はい 1.0
parameter.inputType 必要な入力の種類に設定します。 使用可能な値にはtext、, , textarea, number, date, time``toggle. 既定値は .text なし 1.4
context メッセージ アクションを使用できるコンテキストを定義する値の省略可能な配列。 指定できる値は message、、 compose、または commandBox. 既定値は ["compose", "commandBox"] です。 いいえ 1.5

アクションの種類のメッセージ拡張機能

メッセージ拡張機能からアクションを開始するには、パラメーターactiontype . 検索と作成コマンドを含むマニフェストの例を次に示します。 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",
  "packageName": "com.microsoft.teams.samples.Todo",
  "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"
  ]
}

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

メッセージ作成領域からアクションを開始するだけでなく、メッセージ拡張機能を使用してメッセージからアクションを開始することもできます。 これにより、処理のためにメッセージの内容をボットに送信し、必要に応じて、送信する応答に関するページで説明されているメソッドを使用して応答でそのメッセージ に返信できます。 応答は、送信する前にユーザーが編集できるメッセージへの応答として挿入されます。 ユーザーはオーバーフロー ... メニューからメッセージ拡張機能にアクセスし、次の図のように選択 Take action できます。

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

メッセージ拡張機能をメッセージから機能させるには、次の context 例のように、アプリ マニフェストでメッセージ拡張機能の commands オブジェクトにパラメーターを追加します。 配列の 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
    }]
    ...

ボットに value 送信される要求の一部として送信されるメッセージの詳細を含むオブジェクトの composeExtension 例を次に示します。

{
  "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 つの方法があります。

静的パラメーターの一覧

このメソッドでは、"To Doの作成" コマンドで上に示したように、マニフェスト内のパラメーターの静的な一覧を定義するだけです。 このメソッドを使用するには、マニフェストでパラメーターが設定falseされていることと、パラメーターを定義していることを確認fetchTaskします。

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

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

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

このメソッドでは、サービスがイベントを composeExtension/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"
    }
}

会話型ボットのインストールを要求する

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

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

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

{
  "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 = composeExtension/submitActionおよび value.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 とパラメーター値が設定されたイベントを受け取ります composeExtension/submitAction

これらは、次に示す異なる予想される応答です submitAction

タスク モジュールの応答

これは、拡張機能がダイアログを連結して詳細情報を取得する必要がある場合に使用されます。 応答は、前に説明したものとまったく同じです fetchTask

拡張機能の認証/構成応答を作成する

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

拡張機能の結果応答を作成する

これは、コマンドの結果として作成ボックスにカードを挿入するために使用されます。 検索コマンドで使用されるのと同じ応答ですが、配列内の 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&quot;: &quot;https://placekitten.com/200/200"
            },
            {
              "title": "Details",
              "facts": [
                {
                  "name": "Assigned to:",
                  "value&quot;: &quot;[Larry Brown](mailto:larryb@example.com)"
                },
                {
                  "name": "State:",
                  "value": "Active"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

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

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

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

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

注意

には activityPreviewmessage アダプティブ カードの添付ファイルが 1 つだけ含まれるアクティビティが含まれている必要があります。

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

これで、メッセージ拡張機能は 2 つの新しい種類の対話に応答する必要があります value.botMessagePreviewAction = "send" value.botMessagePreviewAction = "edit"。 処理する必要があるオブジェクトの 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);
        }
    });