Messages dans les conversations des robots

Chaque message d’une conversation est un Activity objet de type messageType: message. Lorsqu’un utilisateur envoie un message, Microsoft Teams publie l’activité de message dans votre bot. Teams envoie un objet JSON au point de terminaison de messagerie de votre bot et Teams n’autorise qu’un seul point de terminaison pour la messagerie. Votre bot examine le message pour déterminer son type et répond en conséquence.

Les conversations de base sont gérées via le connecteur Bot Framework, une seule API REST. Cette API permet à votre bot de communiquer avec Teams et d’autres canaux. Le Kit de développement logiciel (SDK) Bot Builder fournit les fonctionnalités suivantes :

  • Accès facile au connecteur Bot Framework.
  • Fonctionnalité permettant de gérer l’état et le flux de conversation.
  • Moyens simples d’incorporer des services cognitifs, tels que le traitement du langage naturel (NLP).

Votre bot reçoit des messages de Teams à l’aide de la Text propriété et envoie un ou plusieurs messages aux utilisateurs.

Pour plus d’informations, consultez Attribution d’utilisateurs pour les messages de bot.

Le tableau suivant répertorie l’activité que votre bot peut recevoir et sur laquelle il peut agir :

Type Objet de charge utile Portée
Recevoir une activité de message Activité de message tous
Recevoir l’activité de modification de message Activité de modification de message tous
Recevoir l’activité d’annulation de la suppression des messages Activité d’annulation de suppression de message tous
Recevoir l’activité de message de suppression réversible Activité de suppression réversible de message tous

Recevoir une activité de message

Pour recevoir un sms, utilisez la Text propriété d’un Activity objet . Dans le gestionnaire d’activités du bot, utilisez l’Activity de l’objet de contexte de tour pour lire un seul message de demande.

Le code suivant montre un exemple de réception d’une activité de message :


protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
  // Sends an activity to the sender of the incoming activity.
  await turnContext.SendActivityAsync(MessageFactory.Text($"Echo: {turnContext.Activity.Text}"), cancellationToken);
}

Recevoir une confirmation de lecture

Le paramètre Confirmations de lecture dans Teams permet à l’expéditeur d’un message de conversation d’être averti lorsque son message a été lu par le destinataire dans des conversations en tête-à-tête et de groupe. Une fois que le destinataire a lu le message, l’élément Vu apparaît en regard du message. Vous avez également la possibilité de configurer votre bot pour recevoir des événements de confirmation de lecture via le paramètre Confirmations de lecture . L’événement de confirmation de lecture vous permet d’améliorer l’expérience utilisateur des manières suivantes :

  • Vous pouvez configurer votre bot pour envoyer un message de suivi si l’utilisateur de votre application n’a pas lu le message dans la conversation personnelle.

  • Vous pouvez créer une boucle de commentaires à l’aide de confirmations de lecture pour optimiser l’expérience de votre bot.

Remarque

  • Les confirmations de lecture sont prises en charge uniquement dans les scénarios de conversation entre utilisateurs et bots.
  • Les confirmations de lecture pour les bots ne prennent pas en charge les étendues de conversation d’équipe, de canal et de groupe.
  • Si un administrateur client ou un utilisateur désactive le paramètre Confirmations de lecture , le bot ne reçoit pas l’événement de confirmation de lecture.

Pour recevoir des événements de confirmation de lecture pour votre bot, vérifiez les points suivants :

    
"webApplicationInfo": {
    
     "id": "38f0ca43-1c38-4c39-8097e-47f62c686500",
     "resource": ""
},
"authorization": {
    "permissions": {
    "orgwide": [],
     "resourceSpecific": [
        {
        "name": "ChatMessageReadReceipt.Read.Chat",
        "type": "Application"
        }
        ]
     }
 }
    

Vous pouvez également ajouter des autorisations RSC via API Graph. Pour plus d’informations, reportez-vous à l’article consentedPermissionSet.

  • Remplacez la méthode OnTeamsReadReceiptAsync par IsMessageRead le gestionnaire.

    La IsMessageRead méthode d’assistance est utile pour déterminer si le message est lu par les destinataires. Si est compareMessageId inférieur ou égal à , LastReadMessageIdle message a été lu. Remplacez la OnTeamsReadReceiptAsync méthode pour recevoir des confirmations de lecture avec IsMessageRead la méthode d’assistance :

    
    protected override async Task OnTeamsReadReceiptAsync(ReadReceiptInfo readReceiptInfo, ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken) 
    {
        var lastReadMessageId = readReceiptInfo.LastReadMessageId;
       if (IsMessageRead("{id of the message that you care}", LastReadMessageId))
       {
            await turnContext.SendActivityAsync(MessageFactory.Text("User read the bot's message"), cancellationToken);    
        }
    }
    

    Voici un exemple de demande d’événement de confirmation de lecture qu’un bot reçoit :

    {
        "name": "application/vnd.microsoft.readReceipt",
        "type": "event",
        "timestamp": "2023-08-16T17:23:11.1366686Z",
        "id": "f:b4783e72-9d7b-2ed9-ccef-ab446c873007",
        "channelId": "msteams",
        "serviceUrl": "https://smba.trafficmanager.net/amer/",
        "from": {
            "id": "29:1-8Iuh70W9pRqV8tQK8o2nVjxz33RRGDKLf4Bh7gKnrzN8s7e4vCyrFwjkPbTCX_Co8c4aXwWvq3RBLr-WkkVMw",
            "aadObjectId": "5b649834-7412-4cce-9e69-176e95a394f5"
        },
        "conversation": {
            "conversationType": "personal",
            "tenantId": "6babcaad-604b-40ac-a9d7-9fd97c0b779f",
            "id": "a:1xlimp68NSUxEqK0ap2rXuwC9ITauHgV2M4RaDPkeRhV8qMaFn-RyilMZ62YiVdqs8pp43yQaRKvv_U2S2gOS5nM-y_pOxVe4BW1qMGPtqD0Bv3pw-nJXF0zhDlZHMZ1Z"
        },
        "recipient": {
            "id": "28:9901a8b6-4fef-428b-80b1-ddb59361adeb",
            "name": "Test Bot"
        },
        "channelData": {
            "tenant": {
                "id": "6babcaad-604b-40ac-a9d7-9fd97c0b779f"
            }
        },
        "value": {
            "lastReadMessageId": "1692206589131"
        }
    }
    
    
  • Le paramètre d’administrateur de confirmation de lecture ou le paramètre utilisateur est activé pour que le locataire du bot reçoive les événements de confirmation de lecture. L’administrateur client ou l’utilisateur doit activer ou désactiver le paramètre de confirmation de lecture.

Une fois que le bot est activé dans un scénario de conversation entre utilisateurs et bots, le bot reçoit rapidement un événement de confirmation de lecture lorsque l’utilisateur lit le message du bot. Vous pouvez suivre l’engagement de l’utilisateur en comptant le nombre d’événements et vous pouvez également envoyer un message contextuel.

Envoyer un message

Pour envoyer un sms, spécifiez la chaîne que vous souhaitez envoyer en tant qu’activité. Dans le gestionnaire d’activités du bot, utilisez la méthode de SendActivityAsync l’objet de contexte de tour pour envoyer une réponse de message unique. Utilisez la méthode de l’objet SendActivitiesAsync pour envoyer plusieurs réponses.

Le code suivant montre un exemple d’envoi d’un message lorsqu’un utilisateur est ajouté à une conversation :


protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
  // Sends an activity to the sender of the incoming activity.
  await turnContext.SendActivityAsync(MessageFactory.Text($"Hello and welcome!"), cancellationToken);
}

Remarque

  • Le fractionnement des messages se produit lorsqu’un sms et une pièce jointe sont envoyés dans la même charge utile d’activité. Teams divise cette activité en deux activités distinctes, l’une avec un SMS et l’autre avec une pièce jointe. Comme l’activité est fractionnée, vous ne recevez pas l’ID de message en réponse, qui est utilisé pour mettre à jour ou supprimer le message de manière proactive. Il est recommandé d’envoyer des activités distinctes au lieu de dépendre du fractionnement des messages.
  • Les messages envoyés peuvent être localisés pour fournir une personnalisation. Pour plus d’informations, consultez Localiser votre application.

Les messages envoyés entre les utilisateurs et les bots incluent des données de canal interne dans le message. Ces données permettent au bot de communiquer correctement sur ce canal. Le Kit de développement logiciel (SDK) Bot Builder vous permet de modifier la structure des messages.

Obtenir l’activité de modification des messages

Lorsque vous modifiez un message, le bot reçoit une notification de l’activité de modification de message.

Pour obtenir une notification d’activité de modification de message dans un bot, vous pouvez remplacer OnTeamsMessageEditAsync le gestionnaire.

Voici un exemple de notification d’activité de modification de message utilisant OnTeamsMessageEditAsync lorsqu’un message envoyé est modifié :


protected override async Task OnTeamsMessageEditAsync(ITurnContext<IMessageUpdateActivity> turnContext, CancellationToken cancellationToken) 
{ 
var replyActivity = MessageFactory.Text("message is updated"); 
await turnContext.SendActivityAsync(replyActivity, cancellationToken); 
} 

Obtenir l’activité d’annulation de la suppression des messages

Lorsque vous annulez la suppression d’un message, le bot reçoit une notification de l’activité d’annulation de la suppression de message.

Pour obtenir une notification d’activité de message d’annulation de la suppression dans un bot, vous pouvez remplacer OnTeamsMessageUndeleteAsync le gestionnaire.

Voici un exemple de notification d’activité de message d’annulation de la suppression à l’aide OnTeamsMessageUndeleteAsync de quand un message supprimé est restauré :


protected override async Task OnTeamsMessageUndeleteAsync(ITurnContext<IMessageUpdateActivity> turnContext, CancellationToken cancellationToken)
{ 
var replyActivity = MessageFactory.Text("message is undeleted"); 
await turnContext.SendActivityAsync(replyActivity, cancellationToken); 
} 

Obtenir l’activité de message de suppression réversible

Lorsque vous supprimez de manière réversible un message, le bot reçoit une notification de l’activité de message de suppression réversible.

Pour obtenir une notification d’activité de message de suppression réversible dans un bot, vous pouvez remplacer OnTeamsMessageSoftDeleteAsync le gestionnaire.

Voici un exemple de notification d’activité de message de suppression réversible utilisant OnTeamsMessageSoftDeleteAsync lorsqu’un message est supprimé de manière réversible :


protected override async Task OnTeamsMessageSoftDeleteAsync(ITurnContext<IMessageDeleteActivity> turnContext, CancellationToken cancellationToken) 
{ 
var replyActivity = MessageFactory.Text("message is soft deleted"); 
await turnContext.SendActivityAsync(replyActivity, cancellationToken); 
} 

Envoyer des actions suggérées

Les actions suggérées permettent à votre bot de présenter des boutons que l’utilisateur peut sélectionner pour fournir une entrée. Les actions suggérées améliorent l’expérience utilisateur en permettant à l’utilisateur de répondre à une question ou de faire un choix en sélectionnant un bouton, plutôt que de taper une réponse avec un clavier. Lorsque l’utilisateur sélectionne un bouton, celui-ci reste visible et accessible dans les cartes enrichies, mais pas pour les actions suggérées. Cela empêche l’utilisateur de sélectionner des boutons obsolètes dans une conversation.

Pour ajouter des actions suggérées à un message, définissez la suggestedActions propriété d’un objet d’activité pour spécifier la liste des objets d’action carte qui représentent les boutons à présenter à l’utilisateur. Pour plus d’informations, reportez-vous à l’article sugestedActions.

Voici un exemple d’implémentation et d’expérience des actions suggérées :

"suggestedActions": {
    "actions": [
      {
        "type": "imBack",
        "title": "Action 1",
        "value": "Action 1"
      },
      {
        "type": "imBack",
        "title": "Action 2",
        "value": "Action 2"
      }
    ],
    "to": [<list of recepientIds>]
  }

Voici un exemple d’actions suggérées :

Actions suggérées par le bot

Remarque

  • SuggestedActions ne sont pris en charge que pour les bots de conversation en un avec des messages texte et des cartes adaptatives.
  • SuggestedActions ne sont pas pris en charge pour les bots de conversation avec des pièces jointes pour tout type de conversation.
  • imBack est le seul type d’action pris en charge et Teams affiche jusqu’à trois actions suggérées.

Données du canal Teams

L’objet channelData contient des informations spécifiques à Teams et constitue une source définitive pour les ID d’équipe et de canal. Si vous le souhaitez, vous pouvez mettre en cache et utiliser ces ID comme clés pour le stockage local. Dans TeamsActivityHandler le SDK, le extrait les informations importantes de l’objet pour le channelData rendre accessible. Toutefois, vous pouvez toujours accéder aux données d’origine à partir de l’objet turnContext .

L’objet channelData n’est pas inclus dans les messages dans les conversations personnelles, car celles-ci ont lieu en dehors d’un canal.

Un objet classique channelData d’une activité envoyée à votre bot contient les informations suivantes :

  • eventType: type d’événement Teams transmis uniquement en cas d’événements de modification de canal.
  • tenant.id: Microsoft Entra ID de locataire passé dans tous les contextes.
  • team: transmis uniquement dans les contextes de canal, et non dans la conversation personnelle.
  • channel: transmis uniquement dans les contextes de canal, lorsque le bot est mentionné ou pour les événements dans les canaux dans les équipes, où le bot est ajouté.
  • channelData.teamsTeamId:Déconseillée. Cette propriété est incluse uniquement pour la compatibilité descendante.
  • channelData.teamsChannelId:Déconseillée. Cette propriété est incluse uniquement pour la compatibilité descendante.

Exemple d’objet channelData

Le code suivant montre un exemple d’objet channelData (événement channelCreated) :

"channelData": {
    "eventType": "channelCreated",
    "tenant": {
        "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
    },
    "channel": {
        "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype",
        "name": "My New Channel"
    },
    "team": {
        "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype"
    }
}

Contenu du message

Les messages reçus ou envoyés à votre bot peuvent inclure différents types de contenu de message.

Format De l’utilisateur au bot Du bot à l’utilisateur Notes
Texte enrichi ✔️ ✔️ Votre bot peut envoyer du texte enrichi, des images et des cartes. Les utilisateurs peuvent envoyer du texte enrichi et des images à votre bot.
Images ✔️ ✔️ Maximum 1 024 × 1 024 pixels et 1 Mo au format PNG, JPEG ou GIF. Ne prend pas en charge le GIF animé.
Cartes ✔️ Consultez les informations de référence sur les carte Teams pour connaître les cartes prises en charge.
Emojis ✔️ ✔️ Teams prend actuellement en charge les emojis via UTF-16, tels que U+1F600 pour les visages à sourire.

Messages d’image

Pour améliorer votre message, vous pouvez inclure des images en tant que pièces jointes à ce message. Pour plus d’informations sur les pièces jointes, consultez Ajouter des pièces jointes multimédias aux messages.

Les images peuvent être au maximum 1024 × 1 024 pixels et 1 Mo au format PNG, JPEG ou GIF. Le GIF animé n’est pas pris en charge.

Spécifiez la hauteur et la largeur de chaque image à l’aide de XML. Dans Markdown, la taille d’image par défaut est 256×256. Par exemple :

  • Utilisez : <img src="http://aka.ms/Fo983c" alt="Duck on a rock" height="150" width="223"></img>.
  • N’utilisez pas : ![Duck on a rock](http://aka.ms/Fo983c).

Un bot conversationnel peut inclure des cartes adaptatives qui simplifient les workflows métier. Les cartes adaptatives offrent du texte, de la parole, des images, des boutons et des champs d’entrée personnalisables enrichis.

Cartes adaptatives

Les cartes adaptatives peuvent être créées dans un bot et affichées dans plusieurs applications telles que Teams, votre site web, etc. Pour plus d’informations, voir Cartes adaptatives.

Le code suivant montre un exemple d’envoi d’une carte adaptative simple :

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.5",
    "body": [
    {
        "items": [
        {
            "size": "large",
            "text": " Simple Adaptivecard Example with a Textbox",
            "type": "TextBlock",
            "weight": "bolder",
            "wrap": true
        },
        ],
        "spacing": "extraLarge",
        "type": "Container",
        "verticalContentAlignment": "center"
    }
    ]
}

Ajouter des notifications à votre message

Il existe deux façons d’envoyer une notification à partir de votre application :

  • En définissant la propriété sur le Notification.Alert message du bot.
  • En envoyant une notification de flux d’activité à l’aide du API Graph.

Vous pouvez ajouter des notifications à votre message à l’aide de la Notification.Alert propriété . Les notifications alertent les utilisateurs d’un événement dans votre application, tel que de nouvelles tâches, mentions ou commentaires. Ces alertes sont liées à ce sur quoi les utilisateurs travaillent ou à ce qu’ils doivent examiner en insérant un avis dans leur flux d’activité. Pour que les notifications se déclenchent à partir de votre message de bot, définissez la TeamsChannelData propriété objects Notification.Alert sur true. Si une notification est déclenchée dépend des paramètres Teams de l’utilisateur individuel, et vous ne pouvez pas remplacer ces paramètres.

Si vous souhaitez générer une notification arbitraire sans envoyer de message à l’utilisateur, vous pouvez utiliser la API Graph. Pour plus d’informations, consultez comment envoyer des notifications de flux d’activité à l’aide de API Graph ainsi que les meilleures pratiques.

Remarque

Le champ Résumé affiche n’importe quel texte de l’utilisateur sous forme de message de notification dans le flux.

Le code suivant montre un exemple d’ajout de notifications à votre message :

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
  // Returns a simple text message.
  var message = MessageFactory.Text("You'll get a notification, if you've turned them on.");
  message.TeamsNotifyUser();

  // Sends an activity to the sender of the incoming activity.
  await turnContext.SendActivityAsync(message);
}

Codes d’état des API conversationnelles de bot

Veillez à gérer ces erreurs de manière appropriée dans votre application Teams. Le tableau suivant répertorie les codes d’erreur et les descriptions sous lesquels les erreurs sont générées :

Code d'état Code d’erreur et valeurs de message Description Demande de nouvelle tentative Action du développeur
400 Code : Bad Argument
Message : *spécifique au scénario
Charge utile de requête non valide fournie par le bot. Pour plus d’informations, consultez le message d’erreur. Non Réévaluez la charge utile de la demande pour les erreurs. Consultez le message d’erreur retourné pour plus d’informations.
401 Code : BotNotRegistered
Message : Aucune inscription n’a été trouvée pour ce bot.
L’inscription de ce bot est introuvable. Non Vérifiez l’ID et le mot de passe du bot. Vérifiez que l’ID de bot (ID Microsoft Entra) est inscrit dans le portail des développeurs Teams ou via l’inscription du canal de bot Azure dans Azure avec le canal « Teams » activé.
403 Code : BotDisabledByAdmin
Message : L’administrateur du locataire a désactivé ce bot
L’administrateur de locataire a bloqué les interactions entre l’utilisateur et l’application bot. L’administrateur de locataire doit autoriser l’application pour l’utilisateur à l’intérieur des stratégies d’application. Pour plus d’informations, consultez Stratégies d’application. Non Arrêtez la publication dans la conversation jusqu’à ce que l’interaction avec le bot soit explicitement initiée par un utilisateur dans la conversation indiquant que le bot n’est plus bloqué.
403 Code : BotNotInConversationRoster
Message : Le bot ne fait pas partie de la liste de conversation.
Le bot ne fait pas partie de la conversation. L’application doit être réinstallée dans la conversation. Non Avant de tenter d’envoyer une autre demande de conversation, attendez un installationUpdate événement, ce qui indique que le bot est ajouté à nouveau.
403 Code : ConversationBlockedByUser
Message : L’utilisateur a bloqué la conversation avec le bot.
L’utilisateur a bloqué le bot dans une conversation personnelle ou un canal via les paramètres de modération. Non Supprimez la conversation du cache. Arrêtez la tentative de publication dans les conversations jusqu’à ce que l’interaction avec le bot soit explicitement initiée par un utilisateur dans la conversation, ce qui indique que le bot n’est plus bloqué.
403 Code : ForbiddenOperationException
Message : Le bot n’est pas installé dans l’étendue personnelle de l’utilisateur
Un message proactif est envoyé par un bot, qui n’est pas installé dans une étendue personnelle. Non Avant de tenter d’envoyer une autre demande de conversation, installez l’application dans l’étendue personnelle.
403 Code : InvalidBotApiHost
Message : Hôte d’API de bot non valide. Pour les locataires GCC, appelez https://smba.infra.gcc.teams.microsoft.com.
Le bot a appelé le point de terminaison d’API public pour une conversation qui appartient à un locataire GCC. Non Mettez à jour l’URL du service pour la conversation https://smba.infra.gcc.teams.microsoft.com et réessayez la demande.
403 Code : NotEnoughPermissions
Message : *spécifique au scénario
Le bot ne dispose pas des autorisations requises pour effectuer l’action demandée. Non Déterminez l’action requise à partir du message d’erreur.
404 Code : ActivityNotFoundInConversation
Message : Conversation introuvable.
L’ID de message fourni est introuvable dans la conversation. Le message n’existe pas ou il est supprimé. Non Vérifiez si l’ID de message envoyé est une valeur attendue. Supprimez l’ID s’il a été mis en cache.
404 Code : ConversationNotFound
Message : Conversation introuvable.
La conversation n’a pas été trouvée, car elle n’existe pas ou est supprimée. Non Vérifiez si l’ID de conversation envoyé est une valeur attendue. Supprimez l’ID s’il a été mis en cache.
412 Code : PreconditionFailed
Message : Échec de la condition préalable. Réessayez.
Une condition préalable a échoué sur l’une de nos dépendances en raison de plusieurs opérations simultanées sur la même conversation. Oui Réessayez avec un backoff exponentiel.
413 Code : MessageSizeTooBig
Message : taille du message trop grande.
La taille de la requête entrante était trop grande. Pour plus d’informations, consultez Mettre en forme vos messages de bot. Non Réduisez la taille de la charge utile.
429 Code : Throttled
Message : Trop de demandes. Retourne également quand réessayer après.
Trop de requêtes envoyées par le bot. Pour plus d’informations, consultez Limite de débit. Oui Réessayez à l’aide de Retry-After l’en-tête pour déterminer le temps d’interruption.
500 Code : ServiceError
Message : *divers
Erreur interne au serveur. Non Signalez le problème dans la communauté des développeurs.
502 Code : ServiceError
Message : *divers
Problème de dépendance de service. Oui Réessayez avec un backoff exponentiel. Si le problème persiste, signalez le problème dans la communauté des développeurs.
503 Le service n’est pas disponible. Oui Réessayez avec un backoff exponentiel. Si le problème persiste, signalez le problème dans la communauté des développeurs.
504 Délai d’expiration de la passerelle. Oui Réessayez avec un backoff exponentiel. Si le problème persiste, signalez le problème dans la communauté des développeurs.

Conseils pour les nouvelles tentatives de codes d’état

Les instructions générales relatives aux nouvelles tentatives pour chaque code status sont répertoriées dans le tableau suivant. Le bot doit éviter de réessayer status codes qui ne sont pas spécifiés :

Code d'état Stratégie de nouvelle tentative
403 Réessayez en appelant l’API https://smba.infra.gcc.teams.microsoft.com GCC pour InvalidBotApiHost.
412 Réessayez à l’aide d’un backoff exponentiel.
429 Réessayez à l’aide Retry-After de l’en-tête pour déterminer le temps d’attente en secondes et entre les requêtes, si disponible. Sinon, réessayez à l’aide d’une interruption exponentielle avec l’ID de thread, si possible.
502 Réessayez à l’aide d’un backoff exponentiel.
503 Réessayez à l’aide d’un backoff exponentiel.
504 Réessayez à l’aide d’un backoff exponentiel.

Exemple de code

Exemple de nom Description Node.js . NETCore Python .NET Manifeste
Bot de conversation Teams Cet exemple d’application montre comment utiliser différents événements de conversation de bot disponibles dans Bot Framework v4. View View View N/A View
Localisation des applications Teams Cet exemple montre la localisation d’applications Teams à l’aide d’un bot et d’un onglet. View N/A N/A View N/A

Étape suivante

Voir aussi