Un contacto es una persona con la que habla tu organización: un paciente, o un familiar que llama por uno. Raíz guarda un registro por persona, con sus nombres, los números de teléfono, los números de WhatsApp y los correos que usa, sus documentos de identidad, un resumen y lo que tus agentes aprendieron sobre ella. Cada conversación con ella, en cualquier canal, se vincula a ese registro, así que tu equipo y tus sistemas ven un solo historial por paciente. La app de Raíz llama a los contactos Personas.
Qué contiene un contacto
| Campo | Qué es |
|---|---|
givenName, familyName |
Sus nombres y apellidos. fullName los une. |
points |
Hasta 20 formas de comunicarse con la persona. Cada una tiene un kind (phone, email, whatsapp, telegram, slack o web), una address (E.164 para un teléfono), una label opcional y preferred; cuando ningún punto de un tipo es el preferido, lo es el primero. |
identifiers |
Hasta 5 documentos de identidad: un código de type como CC, CE, PA o TI, un number de letras mayúsculas y dígitos, y el countryCode que lo emitió (CO por defecto). |
postalAddresses |
Hasta 5, cada una con un use opcional: home o work. |
summary |
Un resumen de la persona. |
metadata |
Tus propias claves y valores, que Raíz nunca interpreta. |
facts |
El valor actual de cada definición sobre la persona. |
profileName |
El nombre que muestra en WhatsApp, tal como lo envió WhatsApp. Solo lectura. |
phone, email |
Su teléfono y su correo preferidos. |
lastConversation, conversationCount, lastContactedAt |
Su última conversación, y cuánto contacto has tenido con ella. |
Crear, actualizar y buscar
raiz.contacts.create agrega una persona. No es idempotente, y cuando otro contacto ya tiene una de las direcciones o de los documentos de identidad, responde 409 ADDRESS_IN_USE o 409 IDENTIFIER_IN_USE y no crea nada, así que busca primero. En este ejemplo, Ana Ejemplo es una persona inventada:
curl https://api.getarbol.com/v1/raiz/contacts \
--request POST \
--header "Authorization: Bearer $ARBOL_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"givenName": "Ana",
"familyName": "Ejemplo",
"points": [
{ "kind": "whatsapp", "address": "+12025550143" },
{ "kind": "email", "address": "ana.ejemplo@example.com" }
]
}'raiz.contacts.update cambia un contacto. Los campos que omites se quedan y null borra uno, pero points e identifiers son conjuntos completos: los elementos listados conservan su id y su verificación, y los que faltan se eliminan. Lee primero el contacto y envía su version como expectedVersion. Los nombres y los resúmenes que escribes de esta forma nunca los sobrescribe la IA.
raiz.contacts.list busca personas por q: nombres, nombres de perfil, nombres de usuario, teléfonos (incluso parciales o sin el prefijo del país), correos, documentos o el id del contacto, sin distinguir tildes, mayúsculas ni el formato de los números. También filtra por channelType, agentId (personas que hablaron con ese agente), handling y lastContactedAfter, y ordena por created, name o last_contacted. raiz.contacts.count cuenta las mismas coincidencias, hasta 10.000.
Importar desde un CSV
raiz.contacts.import agrega o actualiza muchas personas a la vez desde un CSV en UTF-8 con una fila de encabezado, separado por comas, puntos y comas o tabulaciones. Envíalo como texto en csv o codificado en base64 en file.data, no ambos, de hasta 12 MB (unas 100.000 filas).
given_name,family_name,whatsapp,email,preferred_site
Ana,Ejemplo,+12025550143,ana.ejemplo@example.com,north
Luis,Prueba,+12025550178,luis.prueba@example.com,southLas columnas given_name, family_name, phone, whatsapp, email, document_type, document_number y summary llenan el contacto. Una columna cuyo encabezado es la key de una definición de contacto activa se importa como un hecho, como lo haría preferred_site para una definición con esa clave; cualquier otra columna se guarda como metadata. countryCode (por defecto CO) es el país de los números de teléfono escritos sin +. Una fila cuyo teléfono, número de WhatsApp, correo o documento coincide con un contacto existente actualiza ese contacto; las demás crean contactos nuevos.
La importación responde de inmediato con una tarea. raiz.tasks.get muestra su progreso, processedRows de totalRows, y al final cuántos contactos se crearon, se actualizaron y se rechazaron, con los primeros 100 errores por fila. raiz.tasks.cancel detiene la importación después de su lote actual, y una importación fallida se reanuda con raiz.tasks.retry dentro de 7 días.
Duplicados e historial
Cuando un contacto duplicado se fusiona con otro, el que sobrevive lo absorbe, y el id del duplicado sigue funcionando: raiz.contacts.get devuelve el que sobrevive, raiz.conversations.list con ese contactId lista las conversaciones del que sobrevive, y los hechos registrados con él van al que sobrevive.
expand=timeline en raiz.contacts.get agrega lo que le pasó a la persona, de lo más reciente a lo más antiguo: conversaciones, hechos, cambios y fusiones, incluidos los de los duplicados que absorbió. Recórrelo por páginas con timelineCursor.
Contactos y conversaciones
Cada conversación tiene un contactId, la persona del otro lado, y puede tener un subjectContactId, la persona sobre la que trata cuando es otra. raiz.conversations.list con contactId encuentra ambas. Para mover una conversación a otro contacto, actualiza su contactId con raiz.conversations.update; los hechos ya registrados se quedan con el contacto anterior. El contacto de un destinatario de campaña es el que este nombra o, si no, el contacto dueño de su número, que se crea cuando no hay ninguno.
Perfiles de contacto
Un perfil de contacto es una forma guardada y con nombre de comunicarse con las personas, que otros sistemas usan por su id para iniciar conversaciones. Un perfil voice llama con un agente de voz, opcionalmente con su propio firstMessage y sus propias instructions. Un perfil whatsapp abre una conversación con una plantilla aprobada, cuyos parameters pueden usar variables como {{patient_name}}, y su agente de texto atiende lo que respondan. Ambos pueden limitar cuándo empieza el contacto con contactHours en una timeZone.
Administra los perfiles con raiz.profiles.create, raiz.profiles.get, raiz.profiles.list y raiz.profiles.update. El channelType de un perfil nunca cambia, y las conversaciones iniciadas desde uno llevan su profileId.
Reglas de no contactar
Una supresión (suppression) prohíbe contactar a alguien. Las llamadas, los mensajes de WhatsApp y el widget web revisan estas reglas antes de contactar a nadie, y un intento que prohíben falla con CONTACT_SUPPRESSED. raiz.suppressions.create agrega una regla de uno de cuatro tipos, cada una con un reason que las personas entiendan más adelante:
kind |
Prohíbe |
|---|---|
phone |
Un número, en phone, en E.164. |
phone_prefix |
Todos los números que empiezan por phonePrefix: un código de país como +57, o un rango como +57300. |
ip_network |
Los visitantes del chat web desde ipNetwork, una dirección o red CIDR IPv4 o IPv6. |
country |
Un país, en countryCode, que se compara con el país de un número de teléfono o con la ubicación de un visitante web. |
La misma regla dos veces responde 409 SUPPRESSION_EXISTS. raiz.suppressions.list lista las reglas, filtradas por kind, por q o por phone para las reglas que prohíben ese número.