Lancer des actions avec des extensions de messagerie

Important

Les articles de cette section sont basés sur le SDK v3 Bot Framework. Si vous recherchez la documentation actuelle (version 4.6 ou ultérieure du SDK), consultez la section Interactions orientées tâches avec les extensions de messagerie.

Les extensions de messagerie basées sur l’action permettent à vos utilisateurs de déclencher des actions dans des services externes en Teams.

Exemple de carte d’extension de messagerie

Les sections suivantes décrivent comment faire :

Ajouter une extension de messagerie à votre application

Une extension de messagerie est un service hébergé dans le cloud qui écoute les demandes des utilisateurs et répond avec des données structurées, telles qu’une carte. Vous intégrez votre service à Microsoft Teams via des objets Bot Activity Framework. Nos extensions .NET et Node.js pour le SDK Bot Builder peuvent vous aider à ajouter des fonctionnalités d’extension de messagerie à votre application.

Diagramme du flux de messages pour les extensions de messagerie

S’inscrire dans Bot Framework

Si ce n’est pas déjà fait, vous devez d’abord inscrire un bot auprès du Microsoft Bot Framework. L’ID d’application Microsoft et les points de terminaison de rappel pour votre bot, tels que définis ici, seront utilisés dans votre extension de messagerie pour recevoir et répondre aux demandes des utilisateurs. N’oubliez pas d’activer Microsoft Teams canal de recherche pour votre bot.

Enregistrez votre ID d’application de bot et votre mot de passe d’application. Vous devez fournir l’ID de l’application dans le manifeste de votre application.

Mettre à jour le manifeste de votre application

Comme avec les bots et les onglets, vous mettez à jour le manifeste de votre application pour inclure les propriétés d’extension de messagerie. Ces propriétés régissent l’apparition et le comportement de votre extension de messagerie dans le client Microsoft Teams messagerie. Les extensions de messagerie sont pris en charge à partir de la v1.0 du manifeste.

Déclarer votre extension de messagerie

Pour ajouter une extension de messagerie, incluez une nouvelle structure JSON de niveau supérieur dans votre manifeste avec la composeExtensions propriété. Actuellement, vous êtes limité à la création d’une extension de messagerie unique pour votre application.

Notes

Le manifeste fait référence aux extensions de messagerie comme composeExtensions . Il s’agit de maintenir la compatibilité ascendante.

La définition d’extension est un objet qui a la structure suivante :

Nom de la propriété Objectif Obligatoire ?
botId ID d’application Microsoft unique pour le bot inscrit dans le Bot Framework. Il doit généralement être identique à l’ID de votre application Teams globale. Oui
scopes Tableau déclarant si cette extension peut être ajoutée à ou personal à des team étendues (ou les deux). Oui
canUpdateConfiguration Active Paramètres’élément de menu. Non
commands Tableau de commandes pris en charge par cette extension de messagerie. Vous êtes limité à 10 commandes. Oui

Définir des commandes

Votre extension de messagerie doit déclarer une commande, qui s’affiche lorsque l’utilisateur sélectionne votre application à partir du bouton Plus d’options () dans la zone de composition.

Capture d’écran de la liste des extensions de messagerie dans Teams

Dans le manifeste de l’application, votre élément de commande est un objet avec la structure suivante :

Nom de la propriété Objectif Obligatoire ? Version minimale du manifeste
id ID unique que vous affectez à cette commande. La demande de l’utilisateur inclut cet ID. Oui 1.0
title Nom de la commande. Cette valeur apparaît dans l’interface utilisateur. Oui 1.0
description Texte d’aide indiquant ce que fait cette commande. Cette valeur apparaît dans l’interface utilisateur. Oui 1.0
type Définissez le type de commande. Les valeurs possibles sont query et action. Si elle n’est pas présente, la valeur par défaut est définie sur query . Non 1.4
initialRun Paramètre facultatif, utilisé avec query les commandes. Si la valeur est true, indique que cette commande doit être exécutée dès que l’utilisateur choisit cette commande dans l’interface utilisateur. Non 1.0
fetchTask Paramètre facultatif, utilisé avec action les commandes. Définissez sur true pour récupérer la carte adaptative ou l’URL web à afficher dans le module de tâche. Cette valeur est utilisée lorsque les entrées de la commande sont dynamiques par opposition à un action ensemble statique de paramètres. Notez que si la valeur true est définie, la liste des paramètres statiques de la commande est ignorée. Non 1.4
parameters Liste statique des paramètres de la commande. Oui 1.0
parameter.name Le nom du paramètre. Cette information est envoyée à votre service dans la demande de l’utilisateur. Oui 1.0
parameter.description Décrit les objectifs de ce paramètre ou un exemple de la valeur à fournir. Cette valeur apparaît dans l’interface utilisateur. Oui 1.0
parameter.title Titre ou étiquette de paramètre court et convivial. Oui 1.0
parameter.inputType Définir sur le type d’entrée requis. Les valeurs text possibles sont , , , , textarea number date time toggle . La valeur par défaut est définie sur text . Non 1.4
context Tableau facultatif de valeurs qui définit le contexte dans lequel l’action de message est disponible. Les valeurs possibles message sont , compose ou commandBox . La valeur par défaut est ["compose", "commandBox"]. Non 1,5

Extensions de message de type d’action

Pour lancer des actions à partir d’une extension de messagerie, définissez type le paramètre sur action . Voici un exemple de manifeste avec une recherche et une commande de création. Une seule extension de messagerie peut avoir jusqu’à 10 commandes différentes. Cela peut inclure à la fois plusieurs commandes de recherche et plusieurs commandes basées sur l’action.

Exemple de manifeste d’application complet

{
  "$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"
  ]
}

Lancer des actions à partir de messages

En plus de lancer des actions à partir de la zone composer un message, vous pouvez également utiliser votre extension de messagerie pour lancer une action à partir d’un message. Cela vous permettra d’envoyer le contenu du message à votre bot pour traitement et éventuellement répondre à ce message avec une réponse à l’aide de la méthode, qui est décrite dans Répondre à l’envoi. La réponse est insérée en tant que réponse au message que vos utilisateurs peuvent modifier avant d’envoyer. Vos utilisateurs peuvent accéder à l’extension de messagerie à partir du menu de dépassement, puis en sélectionnant comme ... Take action dans l’image suivante :

Exemple de l’initiative d’une action à partir d’un message

Pour que votre extension de messagerie fonctionne à partir d’un message, ajoutez le paramètre à l’objet de votre extension de messagerie dans le manifeste de votre application, comme dans context commands l’exemple suivant. Les chaînes context valides pour le tableau "message" sont , et "commandBox" "compose" . La valeur par défaut est ["compose", "commandBox"]. Pour plus d’informations sur le paramètre, voir la section Définir des commandes 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
    }]
    ...

Voici un exemple de l’objet contenant les détails du message qui sera envoyé dans le cadre de la value composeExtension demande à votre bot.

{
  "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
          }
        }
      ]
    }
  ...

Test via le chargement

Vous pouvez tester votre extension de messagerie en chargeant votre application. Pour plus d’informations, voir Téléchargement de votre application dans une équipe.

Pour ouvrir votre extension de messagerie, accédez à vos conversations ou canaux. Choisissez le bouton Plus d’options () dans la zone de composition, puis choisissez votre extension de messagerie.

Collecte des entrées des utilisateurs

Il existe trois façons de collecter des informations d’un utilisateur final Teams.

Liste des paramètres statiques

Dans cette méthode, il vous suffit de définir une liste statique de paramètres dans le manifeste, comme indiqué ci-dessus dans la commande « Créer Tâches à faire ». Pour utiliser cette méthode, fetchTask assurez-vous que vous définissez vos false paramètres dans le manifeste.

Lorsqu’un utilisateur choisit une commande avec des paramètres statiques, Teams génère un formulaire dans un module de tâche avec les paramètres définis dans le manifeste. Lors de l’accès à Submit, un message composeExtension/submitAction est envoyé au bot. Pour plus d’informations sur l’ensemble attendu de réponses, voir Répondre pour envoyer.

Entrée dynamique à l’aide d’une carte adaptative

Dans cette méthode, votre service peut définir une carte adaptative personnalisée pour collecter l’entrée utilisateur. Pour cette approche, définissez fetchTask le paramètre sur dans le true manifeste. Si vous définissez, fetchTask true les paramètres statiques définis pour la commande seront ignorés.

Dans cette méthode, votre service reçoit un événement et répond avec une réponse de module de tâche basée sur une carte composeExtension/fetchTask adaptative. Voici un exemple de réponse avec une carte adaptative :

{
    "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"
                }
            }
        }
    }
}

Le bot peut également répondre avec une réponse d’authentification/configuration si l’utilisateur doit authentifier ou configurer l’extension avant d’obtenir l’entrée de l’utilisateur.

Entrée dynamique à l’aide d’un affichage web

Dans cette méthode, votre service peut afficher un widget basé pour afficher n’importe quelle interface utilisateur personnalisée <iframe> et collecter les entrées utilisateur. Pour cette approche, définissez fetchTask le paramètre sur dans le true manifeste.

Tout comme dans le flux de carte adaptative, votre service envoie un événement et répond avec une réponse de module de tâche basée sur fetchTask une URL. Voici un exemple de réponse avec une carte adaptative :

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

Demande d’installation de votre bot de conversation

Si votre application contient un bot de conversation, assurez-vous qu’il est installé dans la conversation avant de charger votre module de tâche. Cela peut être utile dans les situations où vous devez obtenir un contexte supplémentaire pour votre module de tâche. Par exemple, vous devrez peut-être extraire la liste de membres pour remplir un contrôle de s picker de personnes ou la liste des canaux d’une équipe.

Pour faciliter ce flux, lorsque votre extension de messagerie reçoit pour la première fois la vérification d’appel pour voir si votre bot est installé composeExtension/fetchTask dans le contexte actuel. Vous pouvez obtenir cette liste en essayant d’obtenir l’appel de la liste. Par exemple, si votre bot n’est pas installé, vous renvoyez une carte adaptative avec une action qui demande à l’utilisateur d’installer votre bot. L’utilisateur doit être autorisé à installer des applications à cet emplacement. S’ils ne peuvent pas être installés, le message vous invite à contacter l’administrateur.

Voici un exemple de réponse :

{
  "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"
}

Une fois que l’utilisateur a terminé l’installation, votre bot reçoit un autre message d’appel name = composeExtension/submitAction avec , et value.data.msteams.justInTimeInstall = true .

Voici un exemple d’appel :

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

Répondez à l’appel avec la même réponse à la tâche avec qui vous ariez répondu si le bot était déjà installé.

Réponse à l’soumission

Une fois qu’un utilisateur a entré son entrée, le bot reçoit un événement avec l’ID de commande et les valeurs composeExtension/submitAction de paramètre définies.

Voici les différentes réponses attendues à un submitAction .

Réponse du module de tâche

Cette valeur est utilisée lorsque votre extension doit chaîner des boîtes de dialogue pour obtenir plus d’informations. La réponse est identique à ce qui a fetchTask été mentionné précédemment.

Réponse d’th/config d’extension de composition

Il est utilisé lorsque votre extension doit s’authentifier ou configurer pour continuer. Pour plus d’informations, voir la section sur l’authentification dans la section de recherche.

Réponse aux résultats de l’extension de composition

Il est utilisé pour insérer une carte dans la zone de composition à la suite de la commande. Il s’agit de la même réponse que celle utilisée dans la commande de recherche, mais elle est limitée à une carte ou à un résultat dans le tableau.

{
  "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"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Répondre avec un message de carte adaptative envoyé à partir d’un bot

Répondez à l’action d’soumission en insérant un message avec une carte adaptative dans le canal avec un bot. Votre utilisateur peut afficher un aperçu du message avant de l’envoyer et éventuellement le modifier/interagir avec celui-ci. Cela peut être utile dans les scénarios où vous devez collecter des informations auprès de vos utilisateurs avant de créer une réponse de carte adaptative. Le scénario suivant montre comment utiliser ce flux pour configurer un sondage sans inclure les étapes de configuration dans le message de canal.

  1. L’utilisateur sélectionne l’extension de messagerie pour déclencher le module de tâche.
  2. L’utilisateur utilise le module de tâche pour configurer le sondage.
  3. Après avoir soumis le module de tâche de configuration, l’application utilise les informations fournies dans le module de tâche pour créer une carte adaptative et l’envoie en réponse botMessagePreview au client.
  4. L’utilisateur peut alors afficher un aperçu du message de carte adaptative avant que le bot l’insère dans le canal. Si le bot n’est pas déjà membre du canal, un clic Send ajoute le bot.
  5. L’interaction avec la carte adaptative modifie le message avant de l’envoyer.
  6. Une fois que l’utilisateur Send a sélectionné le bot, il publie le message sur le canal.

Pour activer ce flux, votre module de tâche doit répondre comme dans l’exemple ci-dessous, qui présente le message d’aperçu à l’utilisateur.

Notes

Le activityPreview doit contenir une activité avec exactement 1 pièce jointe message de carte adaptative.

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

Votre extension de message devra désormais répondre à deux nouveaux types d’interactions, value.botMessagePreviewAction = "send" et value.botMessagePreviewAction = "edit" . Voici un exemple de value l’objet que vous devrez traiter :

{
  "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" }
      }
    ],
  }
}

Lorsque vous répondez à la demande, vous devez répondre par une réponse avec les valeurs remplies avec les informations que edit l’utilisateur a task déjà envoyées. Lorsque vous répondez à la demande, vous devez envoyer un message au canal send contenant la carte adaptative finalisée.

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);
        }
    });