diff --git a/docs/alta-cliente.md b/docs/alta-cliente.md index 6e3820f..253d851 100644 --- a/docs/alta-cliente.md +++ b/docs/alta-cliente.md @@ -8,8 +8,33 @@ Cada cliente necesita **su propia** cuenta de Meta, su propia app y su propio n Nada se comparte entre clientes: ni el token, ni el App Secret, ni el número. `Taller Beldor` es nuestro ambiente de pruebas y no sirve como cuenta productiva de nadie. -Tiempo realista: **una tarde** si el cliente tiene todo a mano, **varios días** si hay que -esperar la aprobación del Display Name o liberar el número de WhatsApp. +Tiempo realista: **varios días**. La configuración activa lleva una tarde, pero Meta mete +esperas que no se pueden apurar: la revisión de la cuenta, la aprobación del Display Name y +la liberación del número de WhatsApp. Planificar el alta con margen, nunca para el mismo día. + +> **Lo que más caro sale es equivocarse en el orden.** Varios pasos dependen de otros de +> forma no evidente, y reintentarlos deja basura que después bloquea. Las secciones están en +> el orden en que hay que hacerlas. + +--- + +## 0. Antes de tocar nada: los cuatro preparativos + +Estos cuatro se resuelven **antes** de abrir el panel de Meta. Saltearlos es lo que nos costó +una jornada entera en el alta de Taller Beldor. + +1. **El teléfono del titular tiene que estar confirmado en el Centro de cuentas.** + No alcanza con tenerlo a mano: Meta exige que ya esté confirmado antes de dejar verificar + la cuenta de desarrollador, y el mensaje de error no lo dice así. +2. **El nombre del negocio y el del sitio web tienen que coincidir.** + Meta compara el nombre declarado contra el `` del sitio que se declara como + respaldo. Si no coinciden, rechaza el alta con el error de política `#2494070`, que no + explica la causa. +3. **El sitio tiene que servir contenido público.** Una raíz que redirige al login no sirve: + el verificador de Meta ve una pantalla vacía. Hace falta al menos una home con el nombre + del taller y qué hace. +4. **Una política de privacidad en una URL pública.** Es requisito para publicar la app, y + sin publicar la app Meta no entrega datos de producción al webhook. --- @@ -41,6 +66,8 @@ Son actos que quedan a nombre del cliente: aceptan condiciones legales y crean c Register (acepta condiciones) → Verify account (el SMS) → Contact info → About you. 4. **Crear la app**: tipo Business, caso de uso **"Conectarte con los clientes a través de WhatsApp"**, vinculada al portfolio del paso 2. + El **nombre de la app no puede contener "WhatsApp", "Facebook" ni "Insta"**: Meta los + rechaza. Es un nombre interno, no el que ven los clientes. > **El SMS es el punto donde más veces se traba el alta.** Si no llega: verificar que el > número ya esté confirmado en el Centro de cuentas (es un SMS distinto del de la cuenta de @@ -48,6 +75,23 @@ Son actos que quedan a nombre del cliente: aceptan condiciones legales y crean c > seguidas** — Meta deja de entregar los códigos por un rato sin avisar. Si pasó eso, > esperar unas horas y pedir uno solo. +### Reintentar tiene costo: cada intento fallido deja una WABA huérfana + +El asistente de alta **crea la cuenta de WhatsApp Business antes de validar el formulario**. +Si el alta falla después de ese punto, la cuenta queda igual, vacía y contando para el cupo. +Un portfolio sin verificar admite pocas, así que a los pocos reintentos aparece el error +`#2494067` ("Se alcanzó el límite de cuentas de WhatsApp Business"). + +En el alta de Taller Beldor quedaron **seis cuentas, cinco de ellas basura**, y hubo que +borrarlas a mano para poder seguir. Conclusión práctica: **no reintentar a ciegas**. Si el +alta falla, averiguar la causa antes del siguiente intento, y revisar después en +Business Suite → Cuentas de WhatsApp si quedaron cuentas vacías para borrar. + +### El campo "Sitio web" es obligatorio + +Figura como opcional en algunas pantallas pero el formulario no deja avanzar sin él. Y el +sitio que se declare es el que Meta va a comparar contra el nombre del negocio (ver punto 0). + ## 3. Credenciales — las saca el cliente, nosotros no las tocamos Las cuatro variables del `.env`. **Nunca pasan por chat, mail ni WhatsApp**: el cliente las @@ -97,22 +141,70 @@ Errores que ya nos pasaron y conviene chequear: curl "https://graph.facebook.com/v21.0/<PHONE_NUMBER_ID>?fields=display_phone_number,verified_name" \ -H "Authorization: Bearer <TOKEN>" ``` -5. Dar de alta el webhook en Meta: **WhatsApp → Configuration → Webhook**, con la Callback - URL del cliente, el mismo verify token, y **suscribir el campo `messages`**. - Sin esa suscripción no llega ningún mensaje. -6. Cargar los datos del taller: jefes mecánicos, tipos de servicio y horarios. -7. Probar punta a punta con el número de prueba gratis de Meta, mirando - `docker logs -f taller_app`. +5. Dar de alta el webhook en Meta: **Paso 2 → Configurar webhooks**, con la Callback URL del + cliente y el mismo verify token. Meta suscribe **`messages`** solo al guardar; verificar + que el aviso aparezca, porque sin esa suscripción no llega ningún mensaje. +6. **Suscribir la app a la WABA.** Es una segunda suscripción, distinta de la anterior y + fácil de pasar por alto: el campo `messages` se suscribe a nivel app, pero además la app + tiene que estar asociada a esa cuenta de WhatsApp. Si falta, Meta recibe los mensajes y + los entrega a su propia app de pruebas, no al webhook del cliente. + + ```bash + curl -X POST "https://graph.facebook.com/v21.0/<WABA_ID>/subscribed_apps" \ + -H "Authorization: Bearer <TOKEN>" + ``` + + Verificar que el nombre de la app aparezca al consultar ese mismo endpoint con GET. + **Ojo:** si se crea una WABA nueva, hay que rehacer esta suscripción — es por WABA. +7. Cargar los datos del taller: jefes mecánicos, tipos de servicio y horarios. +8. Probar punta a punta, mirando `docker logs -f taller_app`. + El endpoint **solo escribe en el log cuando algo falla**, así que un mensaje que entra + bien es silencioso: la confirmación real es que aparezcan filas en + `MensajeWhatsappProcesado` y `ConversacionWhatsapp`. + +> **Los números de prueba de Meta no sirven para probar el bot.** El que regala el panel +> queda en `status: PENDING`, no se le puede escribir, no envía (`133010 Account not +> registered`) y no acepta `/register`. Sirve para los ejemplos de curl de la documentación, +> nada más. La prueba punta a punta necesita el número real ya conectado. ## 5. Migrar el número real del taller -El último paso, y el que más fricción genera con el cliente. +El último paso, el que más fricción genera con el cliente y donde está la espera más larga. - El número **no puede estar activo en la app de WhatsApp normal o Business**. Hay que **borrar esa cuenta** antes de migrarlo a Cloud API. Se pierde el historial de chats. - Avisarle al cliente con tiempo: si el taller venía atendiendo por ese número, va a querer elegir el momento. -- El **Display Name** necesita aprobación de Meta. Suele salir rápido, pero puede demorar. +- Después de liberarlo, Meta tarda **hasta 3 minutos** en actualizar el estado. Si al + cargarlo dice que sigue registrado, esperar y reintentar: no falló el borrado. + +### Verificar el número NO es lo mismo que conectarlo + +Son dos cosas distintas y el número tiene un campo para cada una: + +| Campo | Qué significa | Cómo se consigue | +|---|---|---| +| `code_verification_status: VERIFIED` | El cliente probó que la línea es suya | Código por SMS o llamada | +| `status: CONNECTED` | El número está operativo sobre Cloud API | Lo aprovisiona Meta | + +**Un número en `PENDING` no envía ni recibe, y ni siquiera existe en WhatsApp**: si se +intenta escribirle desde otro teléfono, WhatsApp solo ofrece "Invitar". Entre que se borra la +cuenta común y que Meta lo conecta, el número queda en tierra de nadie. Es el estado normal +durante la espera, no un error de configuración. + +### La revisión de la cuenta bloquea todo, y no se puede apurar + +Mientras la cuenta de WhatsApp Business figure **`Pending review`**, Meta deshabilita el +botón "Registrar" del Paso 2 con este mensaje: + +> "Number registration and webhook subscription are unavailable for this account now." + +No hay nada que configurar mientras tanto. Es el cuello de botella real del alta: **planificar +el alta de cada cliente contando con esta espera**, y no prometerle una fecha hasta que la +cuenta salga de revisión. + +- El **Display Name** necesita aprobación, pero suele salir sin revisión + (`name_status: AVAILABLE_WITHOUT_REVIEW`) si coincide con el nombre del negocio. - La **Business Verification** se saltea mientras el cliente esté abajo de 1000 usuarios únicos cada 24hs. Para un taller eso es muchísimo, así que en la práctica no aplica. @@ -123,3 +215,23 @@ El último paso, y el que más fricción genera con el cliente. - Si en algún momento se quisiera que el taller **inicie** la conversación (recordatorios de turno, por ejemplo), eso **sí** requiere plantillas aprobadas y **sí** tiene costo. Hoy el bot no lo hace. + +## 7. Manejo de credenciales + +Vale para todos los clientes y no es negociable: + +- **Las credenciales no viajan por chat, mail ni WhatsApp.** Van de la pantalla de Meta al + `.env` del servidor, directo. Un token pegado en una conversación queda registrado ahí para + siempre y hay que revocarlo y regenerarlo. +- **El token de System User se muestra una sola vez.** Tener el `.env` abierto antes. +- Para verificar sin exponer valores, chequear **largo y prefijo** en vez de imprimirlos: + + ```bash + docker exec <contenedor> sh -c 'v=$(printenv WHATSAPP_TOKEN); echo "${#v} chars"' + ``` + +- **Cuidado con los mensajes de error de la Graph API**: cuando un token es inválido, la + respuesta lo devuelve completo en el campo `message`. No volcar esas respuestas crudas en + un log compartido ni en una conversación. +- El PIN de verificación en dos pasos del número lo elige el cliente y conviene que lo anote: + Meta lo pide si alguna vez hay que re-registrar el número.