Partager via


Lancer des actions avec des extensions de messagerie

Importante

Les articles de cette section sont basés sur le Kit de développement logiciel (SDK) Bot Framework v3. 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 message .

Les extensions de message basées sur des actions permettent à vos utilisateurs de déclencher des actions dans des services externes dans Teams.

La capture d’écran est un exemple qui montre la carte d’extension de message.

Ajouter une extension de message à votre application

Une extension de message 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 Framework Activity . Nos extensions .NET et Node.js pour le Kit de développement logiciel (SDK) Bot Builder peuvent vous aider à ajouter des fonctionnalités d’extension de message à votre application.

Capture d’écran montrant l’extension de message basée sur l’action dans Teams.

S’inscrire dans Bot Framework

Vous devez d’abord inscrire un bot auprès de Microsoft Bot Framework. L’ID d’application Microsoft et les points de terminaison de rappel de votre bot, tels qu’ils sont définis ici, sont utilisés dans votre extension de message pour recevoir et répondre aux demandes des utilisateurs. N’oubliez pas d’activer le canal Microsoft Teams pour votre bot.

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

Mettre à jour le manifeste de l’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 message. Ces propriétés régissent la façon dont votre extension de message apparaît et se comporte dans le client Microsoft Teams. Les extensions de message sont prises en charge à partir du manifeste v1.0.

Déclarer votre extension de message

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

Remarque

Le manifeste fait référence aux extensions de message en tant que composeExtensions. Il s’agit de maintenir la compatibilité descendante.

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. Cela 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 aux personal étendues ou team (ou aux deux). Oui
canUpdateConfiguration Active l’élément de menu Paramètres. Non
commands Tableau de commandes que cette extension de message prend en charge. Vous êtes limité à 10 commandes. Oui

Remarque

Si vous définissez la canUpdateConfiguration propriété true sur dans le manifeste de l’application, vous pouvez afficher l’élément de menu Paramètres de votre extension de message. Pour activer les paramètres, vous devez également gérer onQuerySettingsUrl et onSettingsUpdate.

Définir des commandes

Votre extension de message 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.

La capture d’écran est un exemple montrant une liste d’extensions de message 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 l’action de 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. S’il n’est pas présent, 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 la valeur true pour extraire la carte adaptative ou l’URL web à afficher dans le module de tâche. Il est utilisé lorsque l’entrée de la action commande est dynamique, par opposition à un ensemble statique de paramètres. Notez que si la valeur est true, la liste de 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. Il est envoyé à votre service dans la demande de l’utilisateur. Oui 1.0
parameter.description Décrit les objectifs de ce paramètre et l’exemple de la valeur qui doit être fournie. Cette valeur apparaît dans l’interface utilisateur. Oui 1.0
parameter.title Titre ou étiquette court du paramètre convivial. Oui 1.0
parameter.inputType Définissez sur le type d’entrée requis. Les valeurs possibles incluent text, 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 sont message, composeou 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 message, définissez le paramètre sur typeaction. Une seule extension de message peut avoir jusqu’à 10 commandes différentes et inclure plusieurs commandes basées sur la recherche et l’action.

Exemple de manifeste d’application complet

Le code suivant est un exemple de manifeste avec une commande de recherche et de création :

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

Lancer des actions à partir de messages

Vous pouvez lancer des actions à partir de la zone de rédaction du message et également à partir d’un message à l’aide de votre extension de message, ce qui vous permet d’envoyer le contenu du message à votre bot pour traitement. Vous pouvez éventuellement répondre à ce message à l’aide de la méthode décrite dans Réponse à l’envoi. La réponse est incluse en tant que réponse au message, que les utilisateurs peuvent modifier avant de l’envoyer.

Les utilisateurs peuvent accéder à l’extension de message à partir de l’option Action du menu de dépassement ... , comme illustré dans l’image suivante :

Capture d’écran montrant comment lancer une action à partir d’un message.

Pour permettre à votre extension de message de fonctionner à partir d’un message, ajoutez le paramètre à l’objet context de votre extension de message dans le manifeste de commands votre application, comme dans l’exemple suivant. Les chaînes valides pour le context tableau sont "message", "commandBox"et "compose". La valeur par défaut est ["compose", "commandBox"]. Pour plus d’informations sur le paramètre, consultez la context section Définir des commandes :

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

Le code suivant est un exemple de l’objet value contenant les détails du message qui est envoyé dans le cadre de la composeExtensions 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
          }
        }
      ]
    }
  ...

Tester via le chargement

Vous pouvez tester votre extension de message en chargeant votre application. Pour plus d’informations, consultez Chargement de votre application dans une équipe.

Pour ouvrir votre extension de message, accédez à l’une de vos conversations ou canaux. Sélectionnez le bouton Plus d’options () dans la zone de composition et choisissez votre extension de message.

Collecte des entrées des utilisateurs

Il existe trois façons de collecter des informations auprès d’un utilisateur dans Teams.

Liste de paramètres statiques

Dans cette méthode, il vous suffit de définir une liste statique de paramètres dans le manifeste, comme indiqué dans la commande « Create To Do ». Pour utiliser cette méthode, vérifiez fetchTask que est défini sur false et que vous définissez vos 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. Lorsque vous appuyez sur Envoyer, un composeExtensions/submitAction est envoyé au bot. Pour plus d’informations sur l’ensemble de réponses attendu, consultez Réponse à l’envoi.

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 le fetchTask paramètre true sur dans le manifeste. Si vous définissez fetchTask sur true, tous les paramètres statiques définis pour la commande sont ignorés.

Dans cette méthode, votre service reçoit un composeExtensions/fetchTask événement et répond avec une réponse de module de tâche basée sur une carte 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 s’authentifier ou configurer l’extension avant d’obtenir l’entrée utilisateur.

Entrée dynamique à l’aide d’une vue web

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

Tout comme dans le flux de carte adaptative, votre service envoie un fetchTask événement et répond avec une réponse de module de tâche basée sur 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 robot conversationnel

Si votre application contient un bot de conversation, vérifiez qu’il est installé dans la conversation avant de charger votre module de tâche pour obtenir plus de contexte pour votre module de tâche. Par exemple, vous devrez peut-être extraire la liste pour remplir un contrôle sélecteur de personnes ou la liste des canaux d’une équipe.

Pour faciliter ce flux, lorsque votre extension de message reçoit l’appel pour la composeExtensions/fetchTask première fois, vérifiez si votre bot est installé dans le contexte actuel. Vous pouvez l’obtenir en essayant d’obtenir l’appel de la liste. Par exemple, si votre bot n’est pas installé, vous retournez une carte adaptative avec une action qui demande à l’utilisateur d’installer votre bot. L’utilisateur doit avoir l’autorisation d’installer des applications à cet emplacement. S’il ne peut pas être installé, le message 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 avec name = composeExtensions/submitAction 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 de tâche que celle avec laquelle vous avez répondu, si le bot a été installé.

Réponse à l’envoi

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

Il s’agit des différentes réponses attendues à un submitAction.

Réponse du module de tâche

La réponse du module de tâche est utilisée lorsque votre extension doit chaîner des dialogues pour obtenir plus d’informations. La réponse est la même que fetchTask celle mentionnée précédemment.

Réponse d’authentification/configuration des extensions de composition

La réponse d’authentification/configuration des extensions Compose est utilisée lorsque votre extension doit s’authentifier ou configurer pour continuer. Pour plus d’informations, consultez la section sur l’authentification dans la section de recherche.

Réponse du résultat des extensions compose

La réponse du résultat des extensions compose est utilisée 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": "https://placekitten.com/200/200"
            },
            {
              "title": "Details",
              "facts": [
                {
                  "name": "Assigned to:",
                  "value": "[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’envoi 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 ou 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 message pour déclencher le module de tâche.
  2. L’utilisateur utilise le module de tâche pour configurer le sondage.
  3. Une fois que vous avez envoyé 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 tant que botMessagePreview réponse au client.
  4. L’utilisateur peut ensuite afficher un aperçu du message de carte adaptative avant que le bot ne l’insère dans le canal. Si le bot n’est pas déjà membre du canal, le fait de Send cliquer sur ajoute le bot.
  5. L’interaction avec la carte adaptative modifie le message avant de l’envoyer.
  6. Une fois que l’utilisateur a Sendsélectionné , le bot publie le message sur le canal.

Remarque

  • Le activityPreview doit contenir une activité message avec exactement une pièce jointe de carte adaptative.
  • Outlook ne prend pas en charge la réponse avec un message de carte adaptative envoyé à partir d’un bot.

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

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

Votre extension de message doit répondre à deux nouveaux types d’interactions, value.botMessagePreviewAction = "send" et value.botMessagePreviewAction = "edit". Le code suivant est un exemple de l’objet value que vous devez 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 edit demande, vous devez répondre avec une task réponse avec les valeurs remplies avec les informations que l’utilisateur a envoyées. Lorsque vous répondez à la send demande, vous devez envoyer un message au canal 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);
        }
    });

Voir aussi

Exemples Bot Framework