Lo que cuesta mantener una integración después de entregarla
El presupuesto de una integración se hace con la primera llamada y el coste está en los dos años siguientes. Lo que se paga después, con casos concretos.
Una integración no se entrega: se mantiene. El presupuesto se hace con la primera llamada, la que se ve en la demostración, y el coste real está en los dos años siguientes, cuando el proveedor cambia algo que no dependía de ti.
Esto es lo que aparece después, con casos que hemos pagado manteniendo a la vez las integraciones de todas las redes sociales grandes en PlanVortex.
Ninguna alta se parece a otra, y eso no se ve en el presupuesto
Lo primero que descubre cualquiera que integre más de un proveedor es que «conectar la cuenta del usuario» no es una cosa, son cuatro, y solo la primera es la que sale en los tutoriales:
- El diálogo de OAuth de toda la vida. El usuario sale a la web del proveedor, autoriza y vuelve con un código que se canjea. Es el caso fácil y es el que casi nadie discute.
- Una ventana emergente que no devuelve nada por la URL. El alta de WhatsApp Business es un asistente de Meta que abre el navegador con su propio SDK de JavaScript y devuelve los identificadores por
postMessage. No hay parámetro de vuelta que leer: si tu diseño da por hecho que toda alta termina en una URL con un código, esta no encaja en ningún sitio. - Un bot al que se le habla por chat. En Telegram no hay diálogo de autorización, no hay código y no hay token de cuenta. El enlace abre una conversación con un bot, el usuario mete ese bot en su canal y la cuenta nace minutos después, desde un aviso entrante, cuando ya no queda ninguna petición viva a la que contestar.
- Credenciales del propio cliente. En Discord la aplicación es del cliente, no nuestra, porque el permiso que deja leer el texto de los mensajes se revisa por aplicación a partir de cierto tamaño de comunidad. Con una aplicación compartida, el primer cliente grande mete a todos los demás en un ciclo de revisión anual.
Ninguna de estas cuatro es un caso raro. Son cuatro proveedores grandes, y la diferencia no está en la API sino en el momento del alta, que es justo el que se presupuesta como «pantalla de conectar cuenta».
El proveedor no siempre falla con un error
La suposición que más caro sale es que un fallo llega como fallo. Tres ejemplos reales, los tres con código 200 o con un mensaje que dice lo contrario de lo que pasa:
Slack contesta 200 con {"ok": false}. Para un token revocado, para un canal que no existe, para un bot que no está dentro del canal y para un fichero demasiado grande. La librería de HTTP no lanza ninguna excepción, así que un código que solo mira el estado de la respuesta da la publicación por enviada. El resultado es una publicación marcada como publicada que no existe en ningún canal.
Discord contesta 200 con el texto vacío. Si a la aplicación le falta el permiso de leer contenido de mensajes, la API no devuelve un 403: devuelve la lista de mensajes con el campo de texto en blanco. Si eso se guarda, el problema deja de ser un error y pasa a ser una base de datos llena de comentarios vacíos que parecen ciertos.
Telegram contesta 400 para dos cosas opuestas. «message to delete not found» significa que el mensaje ya no está, que es exactamente donde queríamos llegar. «message can't be deleted» significa que sigue publicado y que el usuario tiene que enterarse. La única diferencia entre el éxito y el fallo es la frase.
De aquí sale una regla que no es de estilo: todo el tráfico hacia un proveedor pasa por un único punto, y es ahí donde se decide qué es un error. Una llamada suelta en cualquier rincón del código salta esa puerta, y con ella toda la interpretación.
El límite de tasa no es tuyo, es de todos
Los proveedores no cuentan peticiones por cliente tuyo: cuentan por aplicación o por dirección IP. Eso convierte un fallo de un cliente en una caída de todos.
El caso que mejor lo enseña es Discord. Cuenta aparte las peticiones inválidas (401, 403, 429) y su proveedor de red bloquea por IP a las 10.000 en diez minutos. No es el bloqueo de la aplicación: es el de tu servidor entero, con todos tus clientes dentro, y no lo arregla que cada cliente tenga su propia aplicación, porque la IP es la misma.
Contra eso, una estrategia estadística (reintentos espaciados, algo de aleatoriedad) no basta, porque promete un comportamiento medio y el bloqueo lo provoca el peor rato del mes. Lo que vale es una garantía aritmética: un cubo de fichas compartido por todo el proceso, con un techo de peticiones por segundo por encima del cual el código no puede pasar. Con un techo de diez por segundo, un fallo que fallara el 100% de las veces llegaría a 6.000 peticiones inválidas en diez minutos, por debajo del bloqueo. Esa frase se puede escribir en un contrato; «reintentamos con espera creciente» no.
Y hay un caso peor, el del recurso compartido de verdad: cuando el bot es uno para toda la plataforma (Telegram), el límite del proveedor es el de todos los clientes a la vez. Un cliente ruidoso no se penaliza a sí mismo, penaliza a los demás. La cola tiene que ser por conversación y el techo, global.
Las pruebas simuladas se quedan en verde para siempre
Una prueba que compara tu petición contra una respuesta escrita por ti comprueba lo que tu código hace, no lo que la API acepta. Es útil (es lo que te avisa de que has roto el parseo), pero tiene un punto ciego enorme: pasa igual el día que el proveedor retira una versión, exige un campo nuevo o deja de devolver un dato.
El caso más caro que hemos tenido no fue ni siquiera un rechazo. Al subir una imagen a Slack, el paso que crea el mensaje no devuelve el identificador del mensaje creado, aunque parezca lo natural. Nuestra prueba simulada llevaba meses devolviéndolo, en verde, porque quien la escribió supuso lo razonable. En producción, cada publicación con imagen terminaba marcada con error. La API no rechazó nada: simplemente contestó menos de lo que el simulacro daba por hecho.
Por eso las integraciones que mantenemos llevan tres capas y no dos:
| Capa | Qué comprueba | Qué no ve |
|---|---|---|
| Lógica propia | La máquina de estados, los reintentos, el aislamiento entre cuentas | Todo lo que pase del otro lado |
| Contrato simulado | Qué petición se construye y cómo se interpreta la respuesta | Que esa petición ya no se acepte |
| API real | Que el proveedor siga comportándose como creemos | Nada: es la única que puede decirlo |
La tercera cuesta dinero y tiempo (hay APIs que cobran por llamada) y por eso se ejecuta aparte y sin escribir nada por defecto. Pero es la única que encuentra lo que importa.
El calendario que no lo decides tú
Casi todas las integraciones grandes tienen un trámite de revisión antes de producción: Meta, Google y TikTok revisan la aplicación y cada permiso que pide. Se mide en semanas y no se puede comprimir metiendo más gente.
Lo que sí se puede es no perder la primera vuelta, y eso se prepara desde la propuesta: la aplicación funcionando de verdad para poder grabar el vídeo que piden, la política de privacidad publicada en un dominio verificado, y cada permiso justificado con la pantalla del producto donde se usa. Un permiso pedido «por si acaso» es el motivo de rechazo más común que nos hemos encontrado.
Va en el calendario como una dependencia externa, igual que el plazo de un proveedor de hardware. Si aparece la semana antes de salir, la fecha de salida ya no existe.
Lo que hay debajo: una interfaz honesta
Con varios proveedores a la vez, la tentación es esconderlos detrás de una interfaz común que promete lo mismo para todos. Funciona hasta que se mira de cerca: hay proveedores que no publican (una ficha local recibe reseñas, no publicaciones), otros que no dejan borrar el comentario de un tercero, otros que no tienen mensajes privados y otros que no avisan de nada y hay que preguntarles.
La forma que nos ha aguantado es la contraria: una interfaz común para lo que sí es común, y capacidades declaradas para lo demás. Cada proveedor dice lo que puede hacer, y el producto (el panel, la API pública, el cliente que la integra) lo lee y se comporta en consecuencia, en vez de intentarlo y fallar. Enseñar un botón que el proveedor no soporta es un fallo que solo ve el usuario final.
Qué preguntar antes de firmar una integración
Cuatro preguntas que cambian el presupuesto, y ninguna va sobre la primera llamada:
- ¿Quién mira los fallos y cada cuánto? Una integración sin alguien mirando es una integración que se descubre rota por un cliente.
- ¿Hay pruebas que hablen con la API real? Si no, el primer aviso del cambio será una incidencia.
- ¿Cuál es el techo de peticiones y quién lo comparte? Es la diferencia entre un cliente afectado y todos.
- ¿Qué pasa el día que el permiso caduca? Que es un problema tan grande que tiene artículo propio.
Nosotros presupuestamos las integraciones con esto dentro, no como extra: está en lo que incluye el servicio de integraciones y APIs. Si lo que necesitas es que alguien lo mantenga después de entregarlo, esa es justo la parte que hay que escribir en el contrato.
Preguntas frecuentes
- ¿Cuánto cuesta mantener una integración al año?
- Depende de cuánto cambie el proveedor, y eso no lo decides tú. Lo que sí se puede presupuestar es la capacidad: quién mira los fallos, cada cuánto se ejecutan las pruebas contra la API real y qué pasa cuando el proveedor retira un endpoint con tres meses de aviso. Una integración entregada sin ese acuerdo funciona hasta el primer cambio del otro lado, y a partir de ahí el coste aparece igualmente, solo que de urgencia.
- ¿Por qué no basta con las pruebas automáticas de siempre?
- Porque las pruebas con respuestas simuladas comprueban lo que tu código hace, no lo que la API acepta. Se quedan en verde el día que el proveedor exige un campo nuevo, retira una versión o deja de devolver un dato que tu código daba por hecho. Hace falta además una tanda que hable con la API de verdad, aunque sea semanal y aunque solo lea.
- ¿Qué es lo que más retrasa una integración?
- La revisión del proveedor. Meta, Google y TikTok revisan la aplicación y cada permiso que pide antes de dejarla salir a producción, y eso se mide en semanas, no en días. Se prepara desde la propuesta (vídeo de la aplicación funcionando, política de privacidad publicada, dominio verificado) porque perder la primera vuelta cuesta más que hacerlo bien.
- ¿Se puede integrar sin depender de un proveedor concreto?
- En parte. La capa de dentro (colas, reintentos, renovación de permisos, control de tasa) es tuya y vale para todos. Lo que no se puede abstraer son las diferencias reales: hay proveedores que no publican, otros que no dejan borrar el comentario de un tercero y otros que no tienen mensajes privados. Eso se declara y se enseña, no se esconde detrás de una interfaz que promete lo mismo para todos.