Controlar eventos de bots en Microsoft Teams

Importante

Este artículo se basa en el SDK de Bot Framework v3. Si está buscando la versión 4.6 de la documentación actual o posterior del SDK, consulte la sección de bots conversacionales .

Microsoft Teams envía notificaciones al bot sobre los cambios o eventos que se producen en los ámbitos en los que el bot está activo. En la lista siguiente se proporcionan eventos para desencadenar la lógica del servicio:

  • Desencadene un mensaje de bienvenida cuando el bot se agregue a un equipo.
  • Consulta y almacena en caché la información del grupo cuando el bot se agrega a un chat grupal.
  • Actualice la información almacenada en caché sobre la pertenencia al equipo o la información del canal.
  • Quitar la información almacenada en caché de un equipo si se quita el bot.
  • Cuando un usuario le gusta a un mensaje de bot.

Cada evento de bot se envía como un Activity objeto en el que messageType se define qué información hay en el objeto. Para los mensajes de tipo message, consulte Envío y recepción de mensajes.

Los eventos de grupo y equipos, desencadenados por el conversationUpdate tipo, tienen más información de eventos de Teams pasada como parte del objeto y, por lo tanto, el channelData controlador de eventos debe consultar la channelData carga útil de los metadatos de Teams eventType y más específicos del evento.

En la tabla siguiente se enumeran los eventos que el bot puede recibir y sobre los que puede tomar medidas.

Tipo Objeto de carga útil Teams eventType Descripción Ámbito
conversationUpdate membersAdded teamMemberAdded Miembro agregado al equipo todos
conversationUpdate membersRemoved teamMemberRemoved El miembro se quitó del equipo groupChat & team
conversationUpdate teamRenamed Se cambió el nombre del equipo team
conversationUpdate channelCreated Se creó un canal team
conversationUpdate channelRenamed Se cambió el nombre de un canal team
conversationUpdate channelDeleted Se eliminó un canal team
messageReaction reactionsAdded Reacción al mensaje del bot todos
messageReaction reactionsRemoved Reacción quitada del mensaje del bot todos

Adición de miembros del equipo o bot

El conversationUpdate evento se envía al bot cuando recibe información sobre las actualizaciones de suscripción de los equipos en los que se agrega. También recibe una actualización cuando se agrega por primera vez específicamente para conversaciones personales. La información de usuario (Id) es única para el bot y se puede almacenar en caché para uso futuro por parte del servicio, como enviar un mensaje a un usuario específico.

Bot o usuario agregado a un equipo

El conversationUpdate evento con el membersAdded objeto en la carga se envía cuando se agrega un bot a un equipo o se agrega un nuevo usuario a un equipo donde se agrega un bot. Teams también agrega eventType.teamMemberAdded el channelData objeto.

Dado que este evento se envía en ambos casos, debe analizar el membersAdded objeto para determinar si la adición fue un usuario o el propio bot. Para esto último, una práctica recomendada es enviar un mensaje de bienvenida al canal para que los usuarios puedan comprender las características que proporciona el bot.

Código de ejemplo: comprobar si el bot era el miembro agregado

.NET
    for (int i = 0; i < sourceMessage.MembersAdded.Count; i++)
    {
        if (sourceMessage.MembersAdded[i].Id == sourceMessage.Recipient.Id)
        {
            addedBot = true;
            break;
        }
    }
Node.js
const builder = require('botbuilder');

var c = new builder.ChatConnector({appId: BOT_APP_ID, appPassword: .BOT_SECRET});
var bot = new builder.UniversalBot(c);

bot.on('conversationUpdate', (msg) => {
    var members = msg.membersAdded;
    // Loop through all members that were just added to the team
    for (var i = 0; i < members.length; i++) {

        // See if the member added was our bot
        if (members[i].id.includes(BOT_APP_ID)) {
            var botmessage = new builder.Message()
                .address(msg.address)
                .text('Hello World!');

            bot.send(botmessage, function(err) {});
        }
    }
});

Ejemplo de esquema: bot agregado al equipo

{
   "membersAdded":[
      {
         "id":"28:f5d48856-5b42-41a0-8c3a-c5f944b679b0"
      }
   ],
   "type":"conversationUpdate",
   "timestamp":"2017-02-23T19:38:35.312Z",
   "localTimestamp":"2017-02-23T12:38:35.312-07:00",
   "id":"f:5f85c2ad",
   "channelId":"msteams",
   "serviceUrl":"https://smba.trafficmanager.net/amer-client-ss.msg/",
   "from":{
      "id":"29:1I9Is_Sx0OIy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
   },
   "conversation":{
      "isGroup":true,
      "conversationType":"channel",
      "id":"19:efa9296d959346209fea44151c742e73@thread.skype"
   },
   "recipient":{
      "id":"28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
      "name":"SongsuggesterBot"
   },
   "channelData":{
      "team":{
         "id":"19:efa9296d959346209fea44151c742e73@thread.skype"
      },
      "eventType":"teamMemberAdded",
      "tenant":{
         "id":"72f988bf-86f1-41af-91ab-2d7cd011db47"
      }
   }
}

Usuario agregado a una reunión

El conversationUpdate evento con el membersAdded objeto en la carga se envía cuando se agrega un usuario a una reunión privada programada. Los detalles del evento se envían incluso cuando los usuarios anónimos se unen a la reunión.

Nota

  • Cuando se agrega un usuario anónimo a una reunión, el objeto de carga membersAdded no tiene aadObjectId campo.
  • Cuando se agrega un usuario anónimo a una reunión, from el objeto de la carga siempre tiene el identificador del organizador de la reunión, incluso si otro moderador agregó el usuario anónimo.

Ejemplo de esquema: usuario agregado a la reunión

{
   "membersAdded":[
      {
         "id":"229:1Z_XHWBMhDuehhDBYoPQD6Y1DSFsTtqOZx-SA5Jh9Y4zHKm4VbFGRn7-rK7SWiW1JECwxkMdrWpHoBut2sSyQPA"
      }
   ],
   "type":"conversationUpdate",
   "timestamp":"2017-02-23T19:38:35.312Z",
   "localTimestamp":"2020-09-29T21:11:38.6542339Z",
   "id":"f:a8cd1b51-9ddb-bd35-624b-7f7474165df8",
   "channelId":"msteams",
   "serviceUrl":"https://canary.botapi.skype.com/amer/",
   "from":{
      "id":"29:1siKxZhSoTapsXvI0gyf7Gywm_HM-4kEQW4BJnWuFYVIVu87xCNP99nidgQRCcwD3L3p_schiMShzx8IDRzf8mw",
      "aadObjectId":"f30ba569-abef-4e97-8762-35f85cbae706"
   },
   "conversation":{
      "isGroup":true,
      "tenantId":"e15762ef-a8d8-416b-871c-25516354f1fe",
      "id":"19:meeting_MWJlNGViOTgtMGExYi00NDA3LWExODgtOTZhMWNlYjM4ZTRj@thread.v2"
   },
   "recipient":{
      "id":"28:3af3604a-d4fc-486b-911e-86fab41aa91c",
      "name":"EchoBot1_Rename"
   },
   "channelData":{
      "tenant":{
         "id":"e15762ef-a8d8-416b-871c-25516354f1fe"
      },
      "source":null,
      "meeting":{
         "id":"MCMxOTptZWV0aW5nX01XSmxOR1ZpT1RndE1HRXhZaTAwTkRBM0xXRXhPRGd0T1RaaE1XTmxZak00WlRSakB0aHJlYWQudjIjMA=="
      }
   }
}

Bot agregado solo para contexto personal

El bot recibe un conversationUpdate mensaje cuando membersAdded un usuario lo agrega directamente para el chat personal. En este caso, la carga que recibe el bot no contiene el channelData.team objeto. Debe usarlo como filtro en caso de que desee que su bot ofrezca un mensaje de bienvenida diferente según el ámbito.

Nota

En el caso de los bots de ámbito personal, el bot recibe el conversationUpdate evento varias veces, incluso si el bot se quita y se vuelve a agregar. Para el desarrollo y las pruebas, puede resultarle útil agregar una función auxiliar que le permita restablecer el bot por completo. Para obtener más información, consulte Node.js ejemplo oejemplo de C# para obtener más detalles sobre la implementación.

Ejemplo de esquema: bot agregado a un contexto personal

{
  "membersAdded": [{
      "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0"
    },
    {
      "id": "29:<userID>",
      "aadObjectId": "***"
    }
  ],
  "type": "conversationUpdate",
  "timestamp": "2019-04-23T10:17:44.349Z",
  "id": "f:5f85c2ad",
  "channelId": "msteams",
  "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
  "from": {
    "id": "29:<USERID>",
    "aadObjectId": "***"
  },
  "conversation": {
    "conversationType": "personal",
    "id": "***"
  },
  "recipient": {
    "id": "28:<BOT ID>",
    "name": "<BOT NAME>"
  },
  "channelData": {
    "tenant": {
      "id": "<TENANT ID>"
    }
  }
}

Miembro del equipo o bot quitado

El conversationUpdate evento con el objeto en la carga se envía cuando se quita el membersRemoved bot de un equipo o se quita un usuario de un equipo donde se agrega un bot. Teams también agrega eventType.teamMemberRemoved el channelData objeto. Al igual que con el membersAdded objeto, debe analizar el membersRemoved objeto del id. de aplicación del bot para determinar quién se quitó.

Nota

Si se agrega un bot a un equipo y, posteriormente, el administrador de espacios empresariales lo bloquea para el propietario del equipo, no recibirá conversationUpdate el evento cuando el propietario quite a un usuario del equipo.

Ejemplo de esquema: Miembro del equipo quitado

{
    "membersRemoved": [
        {
            "id": "29:1_LCi5Up14pAy65yZuaJzG1uIT7ujYhjjSTsUNqjORsZHjLHKiQIBJa4cX2XsAsRoaY7va2w6ZymA9-1VtSY_g"
        }
    ],
    "type": "conversationUpdate",
    "timestamp": "2017-02-23T19:37:06.96Z",
    "localTimestamp": "2017-02-23T12:37:06.96-07:00",
    "id": "f:d8a6a4aa",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
    "from": {
        "id": "29:1I9Is_Sx0OIy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
    },
    "conversation": {
        "isGroup": true,
        "conversationType": "channel",
        "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
    },
    "recipient":
    {
        "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
        "name": "SongsuggesterBot"
    },
    "channelData": {
        "team": {
            "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
        },
        "eventType": "teamMemberRemoved",
        "tenant": {
            "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
        }
    }
}

Usuario quitado de una reunión

El conversationUpdate evento con el membersRemoved objeto en la carga se envía cuando se elimina a un usuario de una reunión privada programada. Los detalles del evento se envían incluso cuando los usuarios anónimos se unen a la reunión.

Nota

  • Cuando se elimina un usuario anónimo de una reunión, el objeto de carga membersRemoved no tiene aadObjectId campo.
  • Cuando se quita un usuario anónimo de una reunión, from los objetos de la carga siempre tendrán el id. del organizador de la reunión, incluso si el usuario anónimo fue eliminado por otro moderador.

Ejemplo de esquema: usuario quitado de la reunión

{   
      "membersRemoved": 
        {  
          "id": "29:1Z_XHWBMhDuehhDBYoPQD6Y1DSFsTtqOZx-SA5Jh9Y4zHKm4VbFGRn7-rK7SWiW1JECwxkMdrWpHoBut2sSyQPA"   
        }   
      ],   
      "type": "conversationUpdate",   
      "timestamp": "2020-09-29T21:15:08.6391139Z",   
      "id": "f:ee8dfdf3-54ac-51de-05da-9d49514974bb",   
      "channelId": "msteams",   
      "serviceUrl": "https://canary.botapi.skype.com/amer/",   
      "from": {   
        "id": "29:1siKxZhSoTapsXvI0gyf7Gywm_HM-4kEQW4BJnWuFYVIVu87xCNP99nidgQRCcwD3L3p_schiMShzx8IDRzf8mw",   
        "aadObjectId": "f30ba569-abef-4e97-8762-35f85cbae706"   
      },   
      "conversation": {    
        "isGroup": true,   
        "tenantId": "e15762ef-a8d8-416b-871c-25516354f1fe",   
        "id": "19:meeting_MWJlNGViOTgtMGExYi00NDA3LWExODgtOTZhMWNlYjM4ZTRj@thread.v2"   
      },   
      "recipient": {   
        "id": "28:3af3604a-d4fc-486b-911e-86fab41aa91c",   
        "name": "EchoBot1_Rename"   
      },   
      "channelData": {   
        "tenant": {   
          "id": "e15762ef-a8d8-416b-871c-25516354f1fe"   
        },   
        "source": null,   
        "meeting": {   
          "id": "MCMxOTptZWV0aW5nX01XSmxOR1ZpT1RndE1HRXhZaTAwTkRBM0xXRXhPRGd0T1RaaE1XTmxZak00WlRSakB0aHJlYWQudjIjMA=="   
        }   
      }   
}

Actualizaciones de nombres de equipo

Nota

No existe ninguna funcionalidad para consultar todos los nombres de los equipos y el nombre del equipo no se devuelve en las cargas de otros eventos.

El bot recibe una notificación cuando se cambia el nombre del equipo en el que se encuentra. Recibe un conversationUpdate evento con eventType.teamRenamed en el channelData objeto. No hay notificaciones para la creación o eliminación de equipos, porque los bots existen solo como parte de los equipos y no tienen visibilidad fuera del ámbito en el que se han agregado.

Ejemplo de esquema: equipo cuyo nombre se ha cambiado

{ 
    "type": "conversationUpdate",
    "timestamp": "2017-02-23T19:35:56.825Z",
    "localTimestamp": "2017-02-23T12:35:56.825-07:00",
    "id": "f:1406033e",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/", 
    "from": { 
        "id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
    }, 
    "conversation": {
        "isGroup": true,
        "conversationType": "channel",
        "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
    },
    "recipient": { 
        "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
        "name": "SongsuggesterLocal"
    },
    "channelData": {
        "team": {
            "id": "19:efa9296d959346209fea44151c742e73@thread.skype",
            "name": "New Team Name"
        },
        "eventType": "teamRenamed",
        "tenant": { 
           "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
        }
    }
}

Actualizaciones del canal

El bot recibe una notificación cuando se crea, cambia el nombre o se elimina un canal en un equipo en el que se ha agregado. De nuevo, se recibe el conversationUpdate evento y se envía un identificador de evento específico de Teams como parte del objeto, donde los datos del channel.id canal son el GUID del canal y channel.name contiene el propio nombre del channelData.eventType canal.

Los eventos de canal son los siguientes:

  • channelCreated Un usuario agrega un nuevo canal al equipo.
  • channelRenamed Un usuario cambia el nombre de un canal existente.
  • channelDeleted Un usuario quita un canal.

Ejemplo de esquema completo: channelCreated

{
    "type": "conversationUpdate",
    "timestamp": "2017-02-23T19:34:07.478Z",
    "localTimestamp": "2017-02-23T12:34:07.478-07:00",
    "id": "f:dd6ec311",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
    "from": {
        "id": "29:1wR7IdIRIoerMIWbewMi75JA3scaMuxvFon9eRQW2Nix5loMDo0362st2IaRVRirPZBv1WdXT8TIFWWmlQCizZQ"
    },
    "conversation": {
        "isGroup": true,
        "conversationType": "channel",
        "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
    },
    "recipient": {
        "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
        "name": "SongsuggesterBot"
    },
    "channelData": {
        "channel": {
            "id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
            "name": "FunDiscussions"
        },
        "team": {
            "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
        },
        "eventType": "channelCreated",
        "tenant": {
            "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
        }
    }
}

Extracto de esquema: channelData para channelRenamed

⋮
"channelData": {
    "channel": {
        "id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
        "name": "PhotographyUpdates"
    },
    "team": {
        "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
    },
    "eventType": "channelRenamed",
    "tenant": {
        "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
    }
}
⋮

Extracto de esquema: channelData para channelDeleted

⋮
"channelData": {
    "channel": {
        "id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
        "name": "PhotographyUpdates"
    },
    "team": {
        "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
    },
    "eventType": "channelDeleted",
    "tenant": {
        "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
    }
}
⋮

Reacciones

El messageReaction evento se envía cuando un usuario agrega o quita su reacción a un mensaje, que fue enviado originalmente por el bot. replyToId Contiene el identificador del mensaje específico.

Ejemplo de esquema: a un usuario le gusta un mensaje

{
    "reactionsAdded": [
        {
            "type": "like"
        }
    ],
    "type": "messageReaction",
    "timestamp": "2017-10-16T18:45:41.943Z",
    "id": "f:9f78d1f3",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
    "from": {
        "id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA",
        "aadObjectId": "c33aafc4-646d-4543-9d4c-abd28e4d2110"
    },
    "conversation": {
        "isGroup": true,
        "conversationType": "channel",
        "id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
    },
    "recipient": {
        "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
        "name": "SongsuggesterLocal"
    },
    "channelData": {
        "channel": {
            "id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
        },
        "team": {
            "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
        },
        "tenant": {
            "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
        }
    },
    "replyToId": "1575667808184"
}

Ejemplo de esquema: a un usuario no le gusta un mensaje

{
    "reactionsRemoved": [
        {
            "type": "like"
        }
    ],
    "type": "messageReaction",
    "timestamp": "2017-10-16T18:45:41.943Z",
    "id": "f:9f78d1f3",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
    "from": {
        "id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA",
        "aadObjectId": "c33aafc4-646d-4543-9d4c-abd28e4d2110"
    },
    "conversation": {
        "isGroup": true,
        "conversationType": "channel",
        "id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
    },
    "recipient": {
        "id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
        "name": "SongsuggesterLocal"
    },
    "channelData": {
        "channel": {
            "id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
        },
        "team": {
            "id": "19:efa9296d959346209fea44151c742e73@thread.skype"
        },
        "tenant": {
            "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
        }
    },
    "replyToId": "1575667808184"
}