Automatizar el envío de mensajes personalizados a muchos usuarios dentro de Microsoft Teams permite ahorrar horas de trabajo manual y, al mismo tiempo, mantener la conversación en el mismo lugar donde el destinatario suele colaborar. A continuación encontrarás un recorrido completo —tanto técnico como estratégico— para que tu campaña de avisos o recordatorios llegue a cada chat individual de forma fiable y con la trazabilidad que exige un entorno corporativo.
Escenario y requisitos
Contamos con un archivo Excel que incluye tres columnas básicas: Nombre, Correo electrónico y Mensaje. La meta es que cada fila se convierta en un mensaje 1:1 dentro de Teams, de modo que el remitente pueda revisar el hilo, recibir respuestas y, si fuese necesario, continuar la conversación sin abandonar la plataforma.
Estructura del Excel
- Una hoja titulada Mensajes.
- Encabezados exactos:
Nombre
,Email
,Mensaje
. - No debe haber filas ni columnas vacías intercaladas.
- Para adjuntar archivos dinámicamente, basta con añadir una columna con la URL o el
fileId
del documento en OneDrive.
Por qué Power Automate puro o Copilot Studio no bastan
El conector estándar de Teams en Power Automate solo publica mensajes en canales, no en chats privados. Copilot Studio sí puede enviar mensajes proactivos, pero requiere un bot registrado, mayor coste operativo y no simplifica la vista de todas las conversaciones dentro de la bandeja de chat del usuario emisor.
Comparativa de alternativas
Opción | Descripción | Ventajas | Desventajas / Requisitos |
---|---|---|---|
Microsoft Graph API | Script (PowerShell, Python o C#) que lee Excel, crea / encuentra el chat 1:1 mediante GET /chats o POST /chats , y envía el mensaje con POST /chats/{id}/messages . | Mensajes visibles como chat individual. Control absoluto de registros, errores y respuestas. Puede programarse o ejecutarse por lotes. | Requiere permisos ChatMessage.Send o Chat.ReadWrite.All en Entra ID.Necesita manejar OAuth 2.0 y refresh tokens. Límites de Graph: ~4 cps por app / chat; back‑off en 429. |
Power Automate + Graph | Flujo programado: Excel Online “Obtener filas” → Acción HTTP a Graph o Post message in a chat (conector preview). | Interfaz low‑code; sin compilación. Historial de ejecuciones, reintento manual. Fácil de compartir con analistas de negocio. | El conector estándar no cubre chats; obliga a usar la acción HTTP. Historial del flujo no muestra el hilo completo. Posible coste de ejecuciones periódicas. |
Copilot Studio / Bot proactivo | Bot que, al iniciarse, lee el Excel y dispara mensajes proactivos a cada usuario. | Conversación continua y enriquecida (respuestas, tarjetas adaptativas). Puede ampliarse con IA generativa o flujos de diálogo complejos. | Mayor esfuerzo de configuración y licenciamiento. Sobreingeniería si solo se necesita un envío puntual. |
Mail Merge en Outlook | Combinar correspondencia para enviar correos en lugar de chats. | Sin desarrollo; utiliza el mismo Excel. Compatible con firmas y seguimiento de lectura por correo. | El mensaje llega por correo, no por Teams. No ofrece conversación en tiempo real. |
Implementación con Microsoft Graph API
Esta es la ruta más directa para obtener un chat 1:1 por cada fila del Excel y dejar la conversación anclada en Teams. El proceso puede resumirse en cuatro fases.
Registro de la aplicación en Entra ID
- Crea una App registration en el portal de Entra ID.
- En API permissions, agrega los permisos delegados
Chat.ReadWrite
yUser.Read
. Si el script será ejecutado por un servicio, usa la variante application, por ejemploChatMessage.Send
oChat.ReadWrite.All
. - Concede Admin consent para el tenant.
- Genera un client secret de larga duración o utiliza certificados si el entorno lo exige.
Script ejemplo en PowerShell
# Requiere módulo Microsoft.Graph (v2.8+)
Import-Module Microsoft.Graph
$clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientSecret = (Get-Secret -Name "GraphClientSecret") # Recomendado usar SecretManagement
Connect-MgGraph -ClientId $clientId `
-TenantId $tenantId `
-ClientSecret $clientSecret `
-Scopes "Chat.ReadWrite", "User.Read"
Carga del Excel
$tabla = Import-Excel -Path ".\Mensajes.xlsx" -WorksheetName "Mensajes"
foreach ($fila in $tabla) {
$usuario = Get-MgUser -Filter "mail eq '$($fila.Email)'" -ConsistencyLevel eventual
# Obtiene o crea el chat 1:1
$chat = Get-MgChat -Filter "chatType eq 'oneOnOne'" `
-Search $usuario.Id -ConsistencyLevel eventual
if (-not $chat) {
$chat = New-MgChat -ChatType oneOnOne -Members @(
@{ '@odata.type' = '#microsoft.graph.aadUserConversationMember'
roles = @("owner")
user@odata.bind = "https://graph.microsoft.com/v1.0/users/$($usuario.Id)" }
)
}
# Envía el mensaje
New-MgChatMessage -ChatId $chat.Id -Body @{ content = $fila.Mensaje }
Start-Sleep -Milliseconds 300 # Respetar 4 cps máx.; Delay recomendado
}
Disconnect-MgGraph
Puntos clave:
Import-Excel
proviene del módulo ImportExcel (Install-Module ImportExcel
).- Si la tabla contiene cientos de filas, ajusta la pausa (
Start-Sleep
) o implementa lógica de reintento con exponencial back‑off al recibir HTTP 429. - Para mostrar tarjetas adaptativas, reemplaza
Body
porattachments
con un Adaptive Card en formato JSON.
Manejo de errores y cuotas
Graph impone límites de concurrencia distintos según el tipo de recurso. Para chats 1:1, la práctica más segura es no superar las 4 llamadas por segundo y hacer chunking de usuarios en bloques de 50‑100. Implementa captura de códigos 429 y reintenta tras el valor de Retry-After
. Registra también los eventuales 403 (falta de consentimiento) y 404 (cuenta no encontrada).
Implementación low‑code con Power Automate
Configuración del conector Excel Online
- Crea un flujo programado que se dispare manualmente o cada cierto tiempo.
- Añade la acción Obtener todas las filas apuntando al archivo Excel en OneDrive o SharePoint.
- Habilita la opción Usar ámbito de tabla si el Excel ya tiene la tabla “Mensajes”.
Llamada HTTP a Graph desde el flujo
A falta de un conector nativo para chats, se recurre a la acción HTTP:
- Método: POST
- URL:
https://graph.microsoft.com/v1.0/chats/{{ChatId}}/messages
- Headers:
Content-Type: application/json
- Cuerpo (ejemplo):
{
"body": {
"content": "@{items('Applytoeach')?['Mensaje']}"
}
}
Conviene encapsular la llamada en una acción “Scope” y, tras ella, un “Configure Run After” para capturar fallos y registrar el usuario que no recibió su mensaje.
Seguimiento y reinicio de flujos
El historial de ejecuciones permite verificar cuántas filas se procesaron y en qué mensaje falló la llamada HTTP. Como los chats sí quedan en Teams, puedes abrir la conversación desde allí y continuar diálogo. Para reenviar a los fallidos, basta con reiniciar el flujo y filtrar por estado en Excel o, mejor, añadir una columna Enviado actualizada vía acción “Actualizar fila”.
Otras vías y escenarios complementarios
Bots proactivos con Copilot Studio
Si prevés interacciones bidireccionales ricas (por ejemplo, que el usuario conteste con datos que se registren en Dataverse), la creación de un bot ofrece:
- Mensajes proactivos disparados por un evento (hora, webhook, llegada de archivo, etc.).
- Lógica de estado para validar que el usuario haya leído o respondido.
- Posibilidad de integrar IA generativa para comprender respuestas libres.
Ten presente que un bot requiere un Azure Bot Service, licencias de Copilot Studio y, para producción, un pipeline de ALM.
Uso de Mail Merge como plan B
Cuando el factor crítico es la entrega y no la conversación en vivo, el clásico Combinar correspondencia de Outlook sigue siendo imbatible: admite plantillas con campos dinámicos, incrusta imágenes y puede usarse junto a la función Retrasar entrega para escalonar envíos. El archivo Excel es idéntico al exigido por los métodos anteriores.
Buenas prácticas antes del despliegue
Pruebas controladas y piloto
- Empieza con un grupo de 5‑10 usuarios y valida que cada mensaje llegue sin advertencias.
- Mide la latencia promedio; si supera los 5 segundos por mensaje, revisa throttling y divide la ejecución en lotes.
- Evalúa la reacción de los destinatarios: ¿responden por el mismo chat? ¿Confirman lectura?
Seguridad y gobierno
- Guarda secretos en Azure Key Vault o en un almacén de credenciales (PowerShell SecretManagement, Connection References en Power Automate).
- Activa Conditional Access para la app si solo debe ejecutarse desde la red corporativa.
- Revisa los informes de consentimiento para asegurarte de que los permisos “Chat.*” no queden concedidos a apps fantasma.
Gestión de respuestas y analítica
Graph permite leer mensajes y obtener recibos de lectura con GET /chats/{id}/messages
y /lastMessagePreview
. Con esto puedes generar un informe en Power BI que muestre:
- Usuarios que contestaron.
- Timestamps de lectura (si read receipts está activado en el tenant).
- Análisis de sentimiento usando Cognitive Services.
Conclusión
Para lograr una campaña de mensajería personalizada, en escala y totalmente integrada con la experiencia de Teams, la ruta más ágil es la combinación Excel → Graph API. Power Automate es ideal cuando se prefiere un enfoque low‑code o se quiere delegar la operación en usuarios de negocio. Los bots de Copilot Studio cobran sentido cuando la conversación posterior desempeña un papel central. En entornos donde basta con notificar —sin interacción inmediata—, el tradicional Mail Merge sigue siendo una carta válida. Analiza la complejidad de tu escenario, la pericia técnica del equipo y los requisitos de cumplimiento para elegir tu opción. Con la preparación correcta y un piloto bien medido, podrás transformar un archivo Excel en cientos —o miles— de conversaciones perfectamente cuidadas dentro de Microsoft Teams.