Bots y mensajes interactivos
Una cuenta de bot es un usuario creado para un programa. Tiene su propio nombre, imagen y tokens, y muestra una etiqueta BOT junto a su nombre. Esta página también cubre los agentes de IA que ejecutas tú mismo, y las partes interactivas de los mensajes: botones, menús y diálogos, que cualquier integración puede utilizar.
Por qué usar una cuenta de bot
- Sus mensajes provienen de una identidad clara, con una etiqueta BOT, en lugar de de la cuenta de un compañero.
- Sus tokens siguen funcionando cuando la persona que los configuró cambia de rol o se va (a menos que el servidor desactive los bots de propietarios desactivados, ver abajo).
- Los bots no pueden iniciar sesión con una contraseña y nunca ven la aplicación web.
Las aplicaciones crean sus propios bots, como los bots de Por hacer o Playbooks, a través de la API de complementos (EnsureBotUser). Los agentes de IA también son cuentas de bot, de un tipo propio, mostrados con una etiqueta AGENTE: consulta Agentes.
Activar las cuentas de bot
Un administrador de sistema activa Permitir la Creación de Cuentas Bot en Consola de sistema › Integraciones › Cuentas de bot (ServiceSettings.EnableBotAccountCreation, AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION). Está desactivado por defecto. Solo los administradores de sistema pueden crear bots, a menos que otorguen ese permiso a otros roles en la configuración de permisos.
En la misma página, Desactivar cuentas bot cuando el dueño es desactivado (ServiceSettings.DisableBotsWhenOwnerIsDeactivated, activado por defecto) desactiva un bot cuando la cuenta de su dueño se desactiva.
Crear un bot
- Abre el menú del equipo, luego Configuración del equipo, haz clic en Integraciones al final de sus pestañas, luego en Cuentas de bot y Agregar Cuenta Bot.
- Introduce un Nombre de usuario (letras minúsculas, números, puntos, guiones y guiones bajos), y opcionalmente un Icono Bot, un Nombre a mostrar y una Descripción.
- Elige el Rol: Miembro, o Administrador de sistema para un bot que gestione el servidor. Otorga al bot solo lo que necesite.
- Marca mensajes:canales para permitirle publicar en todos los canales públicos, o mensajes:todos para todos los canales, incluidos los privados y los mensajes directos, sin necesidad de ser miembro.
- Configura cuándo expira su token predeterminado y luego elige Crear Cuenta Bot.
- Copia el token de acceso mostrado. No se mostrará de nuevo.
Más tarde, Crear nuevo token en la fila del bot añade un token, y cada token puede desactivarse o eliminarse. Los tokens de bot funcionan incluso cuando los tokens de acceso personal están desactivados para las personas.
Un bot puede llevar atributos del servidor (los establecidos en Consola de sistema › Atributos del sistema), definidos en el formulario de Agregar/Editar bot o desde Editar atributos… en el menú ⋯ del bot. Los establece quien administre el bot: su propietario, con el permiso de gestión de bots, o cualquier persona con el permiso de gestión de bots de otros; un atributo gestionado por un administrador del sistema aún requiere un administrador del sistema. El bot de un agente de IA no pertenece a nadie, por lo que solo alguien con el permiso de gestión de bots de otros o un administrador del sistema puede establecer sus atributos.
Con la API:
# create the bot (you become its owner)
curl -X POST https://chat.example.com/api/v4/bots \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"username": "deploy-bot", "display_name": "Deploy", "description": "Posts deployments"}'
# give it a token
curl -X POST https://chat.example.com/api/v4/users/$BOT_USER_ID/tokens \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"description": "deploy pipeline"}'
Desde la línea de comandos, iniciando sesión como administrador (no en modo local): amctl bot create deploy-bot --display-name Deploy --with-token --expires-in 90d. Otros puntos finales: GET /api/v4/bots, PUT /api/v4/bots/{bot_user_id}, POST /api/v4/bots/{bot_user_id}/disable y /enable, POST /api/v4/bots/{bot_user_id}/assign/{user_id} para cambiar su propietario.
Añadir el bot a comunidades y canales
Un bot nuevo no pertenece a ninguna comunidad. Añádelo como a una persona, desde la gestión de miembros de la comunidad o mediante la API:
curl -X POST https://chat.example.com/api/v4/teams/$TEAM_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"team_id": "'$TEAM_ID'", "user_id": "'$BOT_USER_ID'"}'
curl -X POST https://chat.example.com/api/v4/channels/$CHANNEL_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"user_id": "'$BOT_USER_ID'"}'
Un bot con mensajes:canales o mensajes:todos puede publicar sin ser miembro, pero solo recibe eventos de WebSocket para los canales en los que está.
Publicar como el bot
Usa el token del bot con cualquier llamada a la API; POST /api/v4/posts es la más común (consulta Recursos principales). Para escribir directamente a alguien, abre primero el canal de mensaje directo:
# returns the channel; use its "id" as channel_id
curl -X POST https://chat.example.com/api/v4/channels/direct \
-H "Authorization: Bearer $BOT_TOKEN" -H 'Content-Type: application/json' \
-d '["'$BOT_USER_ID'", "'$USER_ID'"]'
Para reaccionar a lo que dicen las personas, sigue el WebSocket con el token del bot y responde a los eventos posted que te interesen. Ignora los mensajes propios del bot para evitar bucles.
Un mensaje que solo una persona puede ver (un mensaje efímero) se envía con POST /api/v4/posts/ephemeral y {"user_id", "post": {"channel_id", "message"}}. Requiere el permiso create_post_ephemeral, que por defecto solo tienen los administradores de sistema. Las integraciones suelen enviar mensajes efímeros como respuesta a comandos con barra diagonal y botones.
Agentes
Un agente es una cuenta de bot del tipo agent: los usuarios tienen "is_agent": true, los bots "kind": "agent", y la interfaz muestra una etiqueta AGENTE en lugar de BOT. Los agentes solo los crean los administradores del sistema (agentes de todo el servidor), en Consola de sistema › IA › Conexiones de modelos, y los administradores del equipo (los de su equipo), en la pestaña IA de la configuración del equipo, o con /api/v4/ai/agents (consulta la API). Un bot creado con POST /bots o por una aplicación siempre es un bot normal.
Un agente integrado es respondido por el servidor, con una conexión de modelo. Un agente externo es de tu responsabilidad ejecutarlo: un programa en otro lugar (un agente de codificación en un proyecto, por ejemplo) que inicia sesión como el agente y responde como lo haría una persona. Antimatter no responde por él.
El estado de un agente integrado lo establece el servidor: En línea mientras su conexión de modelo responde, Ausente mientras no lo hace (caída, tiempo de espera agotado, clave rechazada), Desconectado cuando está apagado o no tiene una conexión o modelo utilizable. Se comprueba cuando el agente o su conexión cambian, cuando se prueba una conexión, en cada llamada al modelo del agente y cada 10 minutos. Nadie puede establecer el estado de un agente integrado: PUT /users/{id}/status y los puntos de acceso de estado personalizado responden 403 (api.status.agent.app_error), también para los administradores del sistema, y la API del complemento UpdateUserStatus, SetUserStatusTimedDND, UpdateUserCustomStatus y RemoveUserCustomStatus lo rechazan de la misma manera. El estado de un agente externo sigue su propia conexión en su lugar, y solo su propio token puede cambiarlo.
Ejecutar un agente externo
- Un administrador añade el agente en Consola de sistema › IA › Conexiones de modelos (o en la pestaña IA de una comunidad), con el tipo Agente externo, y elige quién puede hablar con él. La página muestra entonces cómo conectarlo.
- Proporcionarle un token: un administrador del sistema abre Integraciones › Cuentas de bot, encuentra la cuenta del agente y elige Crear nuevo token, o llama a la API de tokens con el ID de usuario del agente:
curl -X POST https://chat.example.com/api/v4/users/$AGENT_USER_ID/tokens \ -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \ -d '{"description": "agent"}' - El programa llama a la API y abre el WebSocket con
Authorization: Bearer <token>, lee sus menciones y mensajes directos de los eventosposted, y responde conPOST /posts, en el hilo del mensaje. - Muestra a las personas lo que está haciendo estableciendo su actividad:
curl -X PUT https://chat.example.com/api/v4/ai/agents/$AGENT_USER_ID/activity \ -H "Authorization: Bearer $AGENT_TOKEN" -H 'Content-Type: application/json' \ -d '{"state": "working", "text": "Running the tests", "thread_post_id": "'$ROOT_ID'"}'
El ID del agente en estas rutas es su ID de usuario. Mantén el token en secreto: cualquiera que lo tenga puede publicar como el agente.
Actividad
state:idle,thinking,working,waiting(para alguien),blockedooffline. Los estados ocupados (thinking, working, waiting, blocked) vuelven aidledespués deexpires_in_seconds: 10 minutos por defecto, 24 horas como máximo.text: unas pocas palabras sobre la tarea, una línea de 200 caracteres como máximo. La interfaz lo muestra en la lista de miembros y en la tarjeta de perfil.thread_post_id: el hilo en el que trabaja, que el programa debe poder leer. Solo se proporciona a quienes pueden leerlo.
Quién puede ver que el agente puede leer su actividad (GET /ai/agents/{agent_id}/activity, o POST /ai/agents/activity/ids con una lista de IDs) y recibe el evento WebSocket agent_activity_changed, sin el hilo. Los agentes integrados establecen su propia actividad.
Mientras un agente integrado escribe su respuesta, el servidor envía el texto en crecimiento en eventos agent_post_stream al canal: post_id, channel_id, root_id, user_id, message (el texto hasta el momento) y control (start, text, end, error o cancel). Un evento post_edited trae el mensaje final. Los clientes que ignoran la transmisión ven la respuesta una vez que se guarda.
Mensajes interactivos: botones y menús
Cualquier mensaje con adjuntos puede incluir acciones: botones y menús para seleccionar opciones. Funcionan en mensajes publicados mediante la API, webhooks y respuestas a comandos con barra diagonal. Cuando alguien usa una, Antimatter llama a la URL de tu integración.
{
"channel_id": "…",
"message": "Deploy **api 2.4.0** to production?",
"props": {
"attachments": [{
"actions": [
{
"id": "approve",
"type": "button",
"name": "Approve",
"style": "primary",
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "approve"}}
},
{
"id": "env",
"type": "select",
"name": "Pick an environment",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}],
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "env"}}
}
]
}]
}
}
type:buttonoselect.id: letras, números, guiones y guiones bajos, distintos para cada acción del mensaje. Se genera si se omite.style(botones):default,primary,success,good,warning,danger, o un color en hexadecimal.options(menús), odata_source:usersochannelspara seleccionar una persona o un canal.default_optionpreselecciona un valor.integration.url: destino de la solicitud. Una app (plugin) puede usar su propia ruta, como/plugins/com.example.deploy/actions.integration.contextes de tu propiedad: se devuelve con la solicitud y los clientes nunca lo ven.
La solicitud que recibe tu integración
{
"user_id": "…",
"user_name": "priya",
"channel_id": "…",
"channel_name": "releases",
"team_id": "…",
"team_domain": "lumen-labs",
"post_id": "…",
"trigger_id": "…",
"type": "button",
"context": {"release": "2.4.0", "action": "approve"}
}
En el caso de un menú, type es select y context.selected_option contiene el valor seleccionado.
Tu respuesta
{
"update": {"message": "Deploy of **api 2.4.0** approved by @priya", "props": {}},
"ephemeral_text": "Done. The deploy starts in a minute."
}
update: reemplaza el texto y las propiedades del mensaje, por ejemplo para eliminar los botones una vez usados (conpropsvacío).ephemeral_text: un mensaje que solo ve la persona que hizo clic.goto_location: una URL para abrir.- Un cuerpo vacío no cambia nada.
El servidor espera el tiempo que permita el Tiempo de espera de solicitud de integración (30 segundos por defecto). Las URL de integración en direcciones de red privada deben ser permitidas por un administrador de sistema, al igual que los webhooks.
Diálogos
Un diálogo es un formulario que se abre sobre el chat. Solo puedes abrirlo en respuesta a algo que la persona acaba de hacer, como un comando con barra diagonal o un botón, porque necesita el trigger_id de esa solicitud. El trigger_id es válido durante el tiempo que dure el Integration request timeout.
curl -X POST https://chat.example.com/api/v4/actions/dialogs/open \
-H 'Content-Type: application/json' \
-d '{
"trigger_id": "'$TRIGGER_ID'",
"url": "https://deploy.example.com/dialog",
"dialog": {
"callback_id": "new-release",
"title": "New release",
"introduction_text": "Fill in the release details.",
"submit_label": "Create",
"notify_on_cancel": false,
"state": "anything you want back",
"elements": [
{"display_name": "Version", "name": "version", "type": "text", "placeholder": "2.4.0"},
{"display_name": "Notes", "name": "notes", "type": "textarea", "optional": true},
{"display_name": "Environment", "name": "env", "type": "select",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}]},
{"display_name": "Owner", "name": "owner", "type": "select", "data_source": "users"},
{"display_name": "Notify the channel", "name": "notify", "type": "bool", "default": "true"}
]
}
}'
| Tipo de elemento | Lo que muestra |
|---|---|
text | Un campo de una línea. subtype: text, email, number, password, tel o url. min_length y max_length lo limitan. |
textarea | Un campo de varias líneas. |
select | Una lista: options, o data_source users, channels, o dynamic con una data_source_url. multiselect permite varios valores. |
bool | Una casilla de verificación. |
radio | Una elección entre options. |
date, datetime | Una fecha, o una fecha y hora. |
action_button | Un botón que llama a action_button_url por sí solo, de forma independiente al envío del diálogo. Su help_text se muestra debajo. |
collapsible | Un grupo plegable de elementos. Con sub_type: "grid", sus contenedores hijos se disponen como una tabla en lugar de apilarse: cada uno es una fila, y sus propios elementos son las celdas de esa fila. |
Cada elemento acepta display_name, name, help_text, placeholder, default y optional.
submit_buttons en el diálogo nombra un elemento select estático: sus opciones se convierten en los botones de envío del diálogo, uno por opción, en lugar de un único Enviar, y ese select no se muestra. size ("small", "medium" o "large"; "small" si se omite) solicita un diálogo más ancho. refresh_on_return (requiere source_url) vuelve a obtener el diálogo desde source_url cuando se cierra un diálogo abierto encima de él, para que pueda mostrar los cambios. Un size o sub_type no reconocido no impide que se abra el diálogo: recurre al valor predeterminado y el servidor solo lo registra en el registro.
Cuando la persona envía el formulario, Antimatter envía una solicitud POST a la url del diálogo:
{
"type": "dialog_submission",
"callback_id": "new-release",
"state": "anything you want back",
"user_id": "…",
"channel_id": "…",
"team_id": "…",
"submission": {"version": "2.4.0", "notes": "", "env": "staging", "owner": "…", "notify": true},
"cancelled": false
}
Responde con un cuerpo vacío para cerrar el diálogo, o déjalo abierto y muestra qué está mal:
{"errors": {"version": "This version already exists."}}
{"error": "…"} muestra un mensaje para todo el formulario. Con notify_on_cancel, al cerrar el diálogo se envía "cancelled": true. Los diálogos funcionan de la misma manera en las apps: la API del plugin OpenInteractiveDialog acepta la misma solicitud.