# Alta de un cliente nuevo Qué hay que pedirle a cada taller y qué hacemos nosotros, para poner en marcha el bot de reservas por WhatsApp. El detalle técnico de las piezas está en [whatsapp.md](whatsapp.md); acá está el orden operativo y quién hace cada cosa. Cada cliente necesita **su propia** cuenta de Meta, su propia app y su propio número. 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: **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. --- ## 1. Lo que le pedimos al cliente antes de empezar Conviene mandarle esta lista completa de entrada, porque casi todo depende de él. | Qué | Para qué | Cuidado | |---|---|---| | Quién va a ser **titular** de la cuenta de Meta | Todo cuelga de esa cuenta | Si es el dueño, mejor; si es un empleado y se va, se complica | | **Cuenta de Facebook** de esa persona, con sesión iniciada | Es la puerta de entrada a todo | — | | **Celular con SMS** para verificar esa cuenta | Meta exige verificar la cuenta de desarrollador | **El número tiene que estar confirmado en el Centro de cuentas ANTES de empezar** | | **Nombre público exacto** del taller | Nombre del portfolio comercial y base del Display Name | Sin caracteres especiales | | **Email del negocio** | Contacto del portfolio y de la app | Tiene que poder recibir el mail de verificación | | **Número de WhatsApp** que va a atender | Es el número del bot | **No puede estar activo en WhatsApp normal ni Business** (ver punto 5) | | **Jefes mecánicos** con nombre | El bot los ofrece como botones | Más de 3 → los primeros 3 son botón, el resto se elige por número | | **Tipos de servicio** y duración | El bot los ofrece después del mecánico | Pueden ser globales o propios de cada jefe | | **Horarios de atención** | Cálculo de los turnos disponibles | — | ## 2. Cuentas de Meta — lo hace el cliente, nosotros guiamos Son actos que quedan a nombre del cliente: aceptan condiciones legales y crean cuentas. **Nosotros no los hacemos por él**, aunque estemos compartiendo pantalla. 1. **Confirmar el teléfono** en el Centro de cuentas → Perfiles y datos personales → Información de contacto → Agregar número → **Confirmar número** con el código del SMS. 2. **Portfolio comercial** en `business.facebook.com`: nombre del negocio, su nombre, email. 3. **Cuenta de desarrollador** en `developers.facebook.com` → "Empezar". Cuatro pasos: 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 > desarrollador), revisar la bandeja de spam del teléfono, y **no reintentar muchas veces > 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 copia de la pantalla de Meta y las pega directo en el `.env` del servidor, o nos da acceso al servidor y las carga él ahí. | Variable | De dónde sale | Forma esperada | |---|---|---| | `WHATSAPP_PHONE_NUMBER_ID` | Caso de uso WhatsApp → Paso 1 "Pruébalo" | Numérico, ~16 dígitos. **No es el teléfono** | | `WHATSAPP_TOKEN` | Business Settings → Usuarios del sistema → Generar token | **Empieza con `EAA`**, ~200 chars | | `WHATSAPP_VERIFY_TOKEN` | Lo inventamos nosotros | Alfanumérico, sin símbolos ni espacios | | `WHATSAPP_APP_SECRET` | App → Configuración → Básica → "Mostrar" | **32 caracteres hexadecimales** | **System user** (de donde sale el token): - Crear uno por cliente, por ejemplo `taller-bot`, rol Employee. - Asignarle **dos activos**: la app (permiso *Desarrollar app*) y la cuenta de WhatsApp (permisos *Mensajes* y *Números de teléfono — ver y administrar*). - Generar token con caducidad **Nunca** y los permisos `whatsapp_business_messaging` y `whatsapp_business_management`. - **El token se muestra una sola vez.** Tener el `.env` abierto antes de apretar el botón. Errores que ya nos pasaron y conviene chequear: - Token **cortado al copiar**: si no empieza con `EAA`, está incompleto. - Placeholders sin reemplazar: que no queden `<...>` en el `.env`. - `APP_SECRET` que no tiene 32 hex: quedó truncado. - Sin `APP_SECRET` correcto, **el webhook rechaza todo con 403** y no entra ningún mensaje. ## 4. Lo que hacemos nosotros 1. Desplegar la app para ese cliente con su dominio propio y certificado válido. Meta **exige HTTPS** para el webhook. 2. Cargar las 4 variables en el `.env` de ese despliegue y `docker compose up -d`. El `.env` no está en el repo: un `git push` no lo toca. 3. Verificar el webhook **antes** de darlo de alta en Meta: ```bash curl "https://<dominio-del-cliente>/api/whatsapp/webhook?hub.mode=subscribe&hub.verify_token=<VERIFY_TOKEN>&hub.challenge=12345" ``` Tiene que devolver exactamente `12345` en texto plano. Si devuelve 403, la variable no llegó al contenedor. 4. Verificar que el token funciona contra la Graph API: ```bash 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: **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, 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. - 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. ## 6. Costos a aclarar antes de vender - El flujo del bot ocurre **dentro de la ventana de 24hs que abre el cliente final**, así que **no usa plantillas aprobadas y no tiene costo por conversación**. - 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.