# Que el agente escriba primero

Un agente contesta cuando le escriben. Con un trigger, además **empieza la conversación**: tu sistema avisa que pasó algo y el agente le escribe a esa persona.

Base de la API de Lelemon: `https://api.lelemon.cl`

La idea de fondo es que tú mandas **el hecho**, no el texto. Tu sistema sabe qué pasó; qué se dice y si se dice vive del lado de Lelemon, en el trigger. Así el mensaje abre una conversación que el agente sigue solo, con la base de conocimiento de tu negocio.

## En tres pasos

1. Creas un trigger: ante qué hecho, con qué agente y qué texto.
2. Tu sistema reporta el hecho cuando ocurre.
3. El agente escribe, y te avisamos por webhook para que lo muestres.

## 1. Crear el trigger

Necesitas una credencial con el alcance `triggers:write`.

```
POST https://api.lelemon.cl/v1/external/triggers
Authorization: Bearer <tu credencial>
Content-Type: application/json

{
  "agentId": "el id de tu agente",
  "evento": "primera_empresa_conectada",
  "texto": "Hola, veo que conectaste tu primera empresa. Te acompaño con lo que sigue.",
  "abrirPanel": true
}
```

- **`evento`** es el nombre que uses en tu sistema. No lo elegimos nosotros: es texto libre y tiene que coincidir con el que vas a reportar.
- **`abrirPanel`** viaja tal cual hasta el aviso saliente. Es tu decisión de producto, no la deducimos del nombre del hecho.
- **`activo`** es opcional y por omisión es `true`. Manda `false` para dejarlo creado pero pausado, y prenderlo después con el `PATCH`.
- **El agente tiene que ser tuyo** y de los que la API administra. Si no, la respuesta es `404`.
- **El agente tiene que estar activo.** Si está en borrador o pausado, la respuesta es `422`: no lo creamos, porque no podría escribir y el trigger quedaría mudo sin que se note.

**Crear no es idempotente.** Dos veces el mismo `POST` dejan dos triggers escuchando el mismo hecho, y los dos escriben: a esa persona le llegan dos mensajes. Es a propósito que no lo prohibamos —dos triggers para el mismo hecho con agentes distintos es un caso real—, así que si tu sistema reintenta el `POST`, revisa antes con el `GET`.

Para ver los que tienes, `GET /v1/external/triggers` con `triggers:read`.

## 2. Reportar el hecho

Necesitas `events:write`. Puede ser la misma credencial o una distinta, y conviene que sea distinta: reportar hechos y decidir qué se dice son dos poderes.

```
POST https://api.lelemon.cl/v1/external/events
Authorization: Bearer <tu credencial>
Content-Type: application/json

{
  "evento": "primera_empresa_conectada",
  "externalId": "el id de ese usuario EN TU SISTEMA"
}
```

`externalId` es la misma palabra que usas para abrir una conversación, así que es la misma persona para las dos rutas.

**Los tres códigos son éxito** y conviene tratarlos así:

| Código | Qué pasó |
|---|---|
| `201` | El agente escribió. |
| `200` | A esa persona ese trigger ya le había llegado. No se escribió de nuevo. |
| `202` | No había nada que hacer. El cuerpo trae `motivo`. |

En el cuerpo van siempre `triggers` y `duplicado`. Lee esos dos en vez del código si quieres medir: el código es la convención, el cuerpo es el detalle.

**A cada persona, un trigger le llega una sola vez.** No hay ventana de tiempo: da lo mismo que reintentes en un segundo o en un mes, la respuesta es `200` con `duplicado: true` y no se escribe nada. Esto no sirve para un mensaje que deba repetirse.

La única forma de que vuelva a escribir es que **el mensaje deje de existir**: si se borra de la conversación, para nosotros esa persona ya no lo recibió, y el siguiente reporte del mismo hecho se lo manda de nuevo. Es a propósito —lo que se pregunta es si lo recibió, no si alguna vez se envió— pero conviene saberlo antes de borrar mensajes en masa.

**Si alguien de tu equipo tomó la conversación**, no se escribe y el trigger le sigue debiendo ese mensaje: cuando devuelvan el control, el siguiente reporte del mismo hecho lo entrega.

## 3. Enterarte de que el agente escribió

El mensaje queda en la conversación, pero tu aplicación no se entera sola. Para eso hay un aviso saliente.

Configura un destino para el evento `conversation.agent_message` en tu panel, en **Desarrolladores → Destinos de aviso**. El cuerpo que te llega:

```json
{
  "tipo": "agente",
  "abrirPanel": true,
  "conversation": { "dealId": "...", "pipelineId": "..." },
  "recipient": { "externalId": "el id de ese usuario en tu sistema" },
  "message": { "id": "..." },
  "trigger": { "id": "...", "evento": "primera_empresa_conectada" }
}
```

**No trae el texto**, a propósito: el aviso dice dónde está el mensaje, no qué decía. Un webhook viaja a tu sistema y queda en tus registros. El contenido lo lees con `GET /v1/external/conversations/{id}/messages`.

Tres cosas que conviene saber antes de configurarlo:

- **Cada destino tiene su propio secreto**, y lo genera Lelemon. Si ya tenías un destino para otro evento, éste va a nacer con otro secreto: tu verificador de firma tiene que aceptar los dos.
- **Si el destino no existe, no falla nada.** No se manda el aviso y la respuesta de la API sigue siendo la misma. Todo se ve bien y no llega nada.
- **Un aviso que se pierde no se recupera.** Reintentamos tres veces; si igual se pierde, reportar el hecho de nuevo no lo trae, porque el trigger ya lo considera entregado.

## Pausar un trigger

```
PATCH https://api.lelemon.cl/v1/external/triggers/{id}
{ "activo": false }
```

Un trigger pausado no dispara, y el reporte del hecho contesta `202` con `motivo: "sin trigger"`.

**No hay borrar.** Borrar un trigger se llevaría el registro de a quién ya se le escribió, y volver a crearlo les escribiría de nuevo a todos. Pausar hace lo que se quiere cuando se pide borrar, sin perder eso.

## Errores

| Código | Qué significa |
|---|---|
| `400` | Falta un campo o no es válido. El cuerpo trae `errors` con el campo que falló. |
| `401` | La credencial falta, está revocada o venció. |
| `403` | A la credencial le falta el alcance. |
| `404` | El agente o el trigger no existen en tu organización. |
| `422` | El agente existe y es tuyo, pero no está activo. |
| `429` | Pasaste el techo de peticiones por minuto. |
