Auditoría de OpenReply: 2.544 estrellas, cero versiones publicadas y la verificación de empresa de Meta que termina con la vía gratuita

OpenReply libera bajo licencia MIT el flujo de Instagram de comentario-a-DM que ManyChat cobra por suscripción, y su documentación es inusualmente honesta sobre el costo real. Cloné el repositorio (247 archivos, 191 commits, 44 archivos de pruebas) y verifiqué los números: 2.544 estrellas pero solo 12 watchers, 1.037 forks pero cero releases y cero tags, 28 colaboradores de los cuales 26 tienen ocho commits o menos. El hallazgo interesante no es el código sino el límite: autoalojarlo para tu propia cuenta es genuinamente gratis, y atender a un cliente que paga choca con la verificación de empresa de Meta, que exige una entidad legal registrada, por lo que la ruta práctica documentada es pagarle al propio patrocinador del proyecto. Zernio es un proveedor de conexión de pago y el patrocinador del proyecto, y su frase de marketing — «We've done the platform reviews, so you don't have to» — nombra exactamente el muro donde se detiene la capa gratuita. Además: el stack gratuito de referencia es Vercel más una base Neon de 0,5 GB más un Redis de 30 MB más una VM micro de Oracle siempre gratuita, lo que da del orden de 250.000 filas de registro de DM y unos 10.000 trabajos en cola antes de tocar techo, y tres fallos documentados cuestan una tarde cada uno porque los mensajes de error apuntan lejos de la causa.

Alguien comenta LINK en tu reel. OpenReply encola un mensaje directo con tu enlace, a través de la API oficial de respuestas privadas de Meta, y opcionalmente publica una respuesta pública bajo el comentario. Eso es todo el producto, y es la única función que todas las herramientas de redes sociales venden como suscripción mensual.

OpenReply tiene licencia MIT y es autoalojado. No hay plan alojado al que subir de nivel: la demo pública en openreply.diwen.dev es una demostración del panel y nunca enviará un DM por ti. Despliegas tu propia copia, ejecutas tu propio worker y conectas tu propia cuenta de Instagram.

Lo cloné y revisé los números, la documentación y la capa gratuita que recomienda. La ingeniería está por encima de la media de los lanzamientos de «alternativa open source». La documentación es más honesta que la de la mayoría de los proveedores comerciales. Y lo más interesante del proyecto es un límite que está documentado en una cláusula subordinada y que determina si todo esto es gratis o no.

Qué es OpenReply exactamente

Dos procesos de Node y dos almacenes de datos, y la división no es decorativa:

  • Aplicación web y API — Next.js 16 con React 19, App Router. Sirve el panel, el callback de OAuth y el webhook entrante. Se despliega en Vercel.
  • Worker — un proceso de Node de larga duración (npm run worker, ejecutado con tsx). Consume la cola de envío, envía los DM, ejecuta el reconciliador de sondeo para comentarios perdidos y realiza las comprobaciones de la barrera de seguimiento con is_user_follow_business.

La existencia del worker se deriva de una sola frase de la documentación: «It cannot run on Vercel, because serverless functions are short-lived and a queue consumer has to stay up.» Un envío de DM tiene que sobrevivir a los límites de velocidad y a los reintentos de Meta, así que necesita un proceso siempre encendido. Vercel solo ejecuta la mitad delantera.

El resto es PostgreSQL con Prisma 7, Redis con BullMQ 5 para la cola de envío y el limitador por cuenta, Auth.js con enlaces mágicos por correo vía Resend, Tailwind para la interfaz y la API oficial de Instagram con Instagram Login. Catorce dependencias en tiempo de ejecución en package.json, algo austero para todo lo que hace.

El repositorio en main:

  • 247 archivos, 191 commits, TypeScript 97,4 %
  • 44 archivos de pruebas en __tests__/
  • 18 modelos de Prisma y 7 enums en un schema.prisma de 421 líneas
  • La CI ejecuta typecheck, lint, vitest run y una compilación de producción en cada push y cada pull request

La lista de funciones es más amplia que el eslogan de una línea: coincidencia de palabras clave en modo palabra completa o parcial, enlaces con seguimiento y CTR por campaña, hasta dos botones en el DM cada uno con sus propias estadísticas de clics, una barrera de seguimiento que vuelve a pedir la acción hasta confirmarla y que falla en abierto cuando Meta no devuelve el estado de seguimiento, limitación de velocidad por cuenta que encola el excedente en lugar de descartarlo, espacios de trabajo con roles de propietario/administrador/miembro y enlaces de invitación, plantillas de campaña, una bandeja de entrada para leer y responder dentro de la ventana de 24 horas de Meta, y registros de DM que anotan cada envío, omisión y fallo con su motivo.

También hay un selector de idioma de interfaz con inglés, chino tradicional y portugués de Brasil. El soporte de pt-BR llegó como pull request de la comunidad el último día del árbol de trabajo que cloné, lo que es señal de que el proyecto sigue vivo y no archivado y olvidado.

La vía gratuita es real, y termina en tu propia cuenta

Aquí está la parte que el titular no lleva. El comentario-a-DM de Instagram es una función privilegiada que Meta controla, y el control no es un límite de velocidad. Es quién tiene permitido usar el permiso siquiera.

OpenReply documenta dos formas de conectar Instagram. La primera es tu propia app de Meta. La segunda es Zernio, un proveedor de conexión de pago, que además es el patrocinador del proyecto.

Si tomas la primera vía para tus propias cuentas, funciona y no cuesta nada. Añade tu usuario de Instagram como tester de la app, acepta la invitación del lado de Instagram, y Standard Access te cubre. Sin revisión de app. La documentación lo dice sin rodeos: «Everything above is enough to run OpenReply for your own accounts, or a handful of accounts you add as testers. No App Review needed.»

Si quieres la cuenta de otra persona — la de un cliente, la de un usuario, la de cualquiera que no sea tester de tu app — el camino cambia por completo. META_APP_REVIEW.md enumera lo que hace falta: un screencast de todo el flujo grabado en una sola toma con cuentas reales, una justificación escrita para cada uno de los tres permisos, y luego esto:

«Meta usually requires business verification before granting Advanced Access. It asks for a document proving a legal entity: a business registration or license, articles of incorporation, a business tax document, or a business bank statement. If you do not have a registered business, you cannot complete this step, and the practical path is to run OpenReply for your own accounts instead, which never needs review.»

Vuelve a leerlo como operador y no como lector. El software es gratis, la API es gratis, el alojamiento puede ser gratis, y lo único que se interpone entre tú y atender a un cliente que paga es un documento emitido por un gobierno. Un freelance, alguien que trabaja solo, alguien que prueba una idea de agencia antes de constituir la empresa: todos quedan fuera de la vía gratuita, no por decisión del proyecto, sino por la estructura de la plataforma que hay debajo.

La documentación añade una segunda advertencia que importa para planificar: «Meta scrutinizes automated-DM apps and often rejects the first submission, so budget for a resubmit.»

El modelo de negocio del patrocinador es el muro que encuentras

Zernio aparece descrito en el README como «an optional paid Instagram connection provider that lets you avoid creating and reviewing your own Meta app». También es el patrocinador del proyecto, y cada enlace de la documentación que apunta a él lleva utm_source=openreply&utm_medium=sponsorship&utm_campaign=openreply-integration.

Zernio es en sí una empresa mucho más grande de lo que sugiere el patrocinio. Se presenta como «marketing infrastructure for agents» — una sola API para redes sociales, blogs, anuncios, números de teléfono, SMS, WhatsApp e iMessage, con servidor MCP e integraciones anunciadas para Claude Code, Cursor, Codex y herramientas similares. Su portada afirma «200,000+ builders» y, el día que la consulté, «32,613 accounts connected this week».

Su precio es por cuenta conectada, sin planes ni asientos: 1–2 cuentas gratis, 3–10 a 6 $ por cuenta al mes, 11–100 a 3 $, y más de 101 a 1 $, con el promedio anunciado en 4,80 $ por cuenta. Los primeros 10.000 mensajes enviados cada mes están incluidos.

Y su texto de marketing nombra el muro con precisión:

«Skip months of platform approvals and go live today.» «We’ve done the platform reviews, so you don’t have to.» «Platform changes, token rotations, and rate limits are ours to absorb.»

Nada de esto está oculto, y el proyecto no pretende lo contrario. docs/setup.md etiqueta a Zernio como «recommended for simpler connection setup» y declara en la misma fila de la tabla que es un proveedor de pago y que patrocina OpenReply. El prompt de configuración para asistentes de IA que se distribuye con el repositorio también lo explicita, instruyendo al asistente a «clearly disclose that it is an optional PAID service and OpenReply sponsor» antes de recomendarlo.

Eso es más transparencia de la que se molestan en ofrecer la mayoría de los proyectos open source patrocinados, y merece reconocerse. Pero la transparencia no cambia la forma de la cosa: la capa gratuita de este software gratuito se detiene exactamente donde empieza el producto de pago del patrocinador. Lo leas como un modelo de financiación sostenible para un mantenedor individual o como un embudo con licencia MIT delante, la consecuencia práctica para ti es idéntica. O tienes una entidad registrada, o pagas por cuenta.

Prefiero que un proyecto se financie así a que quede abandonado, y la alternativa —sin patrocinador y sin compatibilidad mantenida con lo que Meta cambie el próximo trimestre— no es obviamente mejor. Simplemente vale la pena ver el límite antes de planificar un negocio encima.

Qué medí en el repositorio

Los números de crecimiento son inusuales de una forma que conviene anotar, porque no encajan con la forma de un lanzamiento viral típico.

  • 2.544 estrellas, pero 12 watchers. Los watchers son quienes eligieron recibir notificaciones: la señal de intención más fuerte disponible. Doce frente a 2.544 estrellas es 0,47 %. En repositorios que alcanzan este nivel de atención, los watchers suelen ser un orden de magnitud más.
  • 1.037 forks frente a 2.544 estrellas. Una proporción de forks a estrellas del 40,8 %. Para una aplicación autoalojada el fork es la vía de despliegue, así que una proporción elevada es esperable, pero 40,8 % está muy por encima de la banda habitual, y dice que la mayoría de esas estrellas no vienen de gente que lee el código.
  • Cero releases y cero tags. No «ninguna versión reciente»: ninguna en absoluto. package.json dice 0.1.0 y no hay ninguna etiqueta apuntando a nada. No hay versión que fijar, ni changelog que comparar, ni artefacto que descargar. Todo el que despliega esto clona main en el commit que le tocó, lo que además significa que la pregunta «¿debo actualizar?» no tiene respuesta limpia.
  • 28 colaboradores, y 26 de ellos tienen ocho commits o menos. El mantenedor, Diwen Huang, tiene 108 de los 191 commits muestreados. El autor original del proyecto del que se bifurcó tiene 28. El resto es una cola larga de contribuciones de uno a ocho commits, normal en un repositorio con plantilla good_first_issue y guía de contribución, y también significa que el factor autobús es uno para cualquier cosa estructural.
  • Ninguna discusión en Hacker News. Lo busqué. OpenReply no aparece. La categoría a la que pertenece sí: encontré al menos otros dos posts de Show HN del mismo período anunciando alternativas a ManyChat de código abierto y autoalojables, ambas con puntuaciones de un dígito. Es un carril concurrido, y las estrellas aquí no vienen de los canales de lanzamiento habituales.
  • La cronología de commits tiene un pico y una cola. El repositorio se creó en julio de 2026, pero los commits se remontan a abril porque el fork conservó el historial anterior. Julio acumula 100 de los 191; agosto 24, septiembre 35, octubre 4 en el momento del clonado. El patrón —un empujón grande cuando el proyecto se reestableció como producto open source, y luego mantenimiento constante— encaja con un mantenedor único construyendo en su tiempo libre.

El historial de bifurcación también explica un archivo que de otro modo resulta extraño: el directorio de migraciones contiene una migración remove_billing fechada en mayo de 2026, y las cinco primeras migraciones construyen una «B2B SaaS foundation». Esto no se escribió como proyecto open source y luego se licenció bajo MIT. Era un SaaS comercial que se convirtió en uno.

El techo de la capa gratuita, en números

docs/stack.md publica el stack de costo cero exacto que ejecuta el mantenedor, lo cual es un nivel de concreción bienvenido, y hace que los techos sean calculables en lugar de vagos:

PiezaServicioAsignación gratuita
Aplicación webVercel (Hobby)Gratis
PostgreSQLNeon~0,5 GB
RedisRedis Cloud (Essentials)30 MB, requiere TCP
Worker (24/7)VM «Always Free» de Oracle Cloud (VM.Standard.E2.1.Micro, Ubuntu 22.04, pm2)Gratis para siempre
Correo de accesoResend3.000 correos/mes
API de InstagramApp de Meta con Instagram LoginGratis

La documentación ya señala una restricción que sorprende: «Vercel’s free plan allows each cron to run at most once per day. The repo’s crons are set to daily for that reason.» El cron de renovación de tokens es, por tanto, un trabajo diario, lo cual está bien, pero significa que cualquier cosa que quisieras en una cadencia más fina no puede vivir ahí.

Los dos números que nadie ha calculado son la base de datos y la cola, así que los calculé, y las respuestas son menos cómodas que el resto del stack.

PostgreSQL con 0,5 GB. Esta aplicación registra de forma agresiva por diseño: DmLog anota cada envío, omisión y fallo con su motivo, WebhookEvent guarda las entregas entrantes, OperationalEvent guarda caídas del worker y barridos del reconciliador, y los enlaces con seguimiento añaden eventos de clic encima. Una sola fila de registro de DM con su carga útil almacenada ronda 1–3 KB. A 2 KB por fila, 0,5 GB está en el orden de 250.000 filas antes de tocar techo, y ese techo cuenta todo, no solo la tabla de registros, y no tiene en cuenta la sobrecarga propia de Postgres, los índices ni la fragmentación de tablas. Una cuenta que envíe 500 DM al día lo alcanza en aproximadamente año y medio. Una que envíe 5.000 al día lo alcanza en unas siete semanas.

Redis con 30 MB. BullMQ guarda las cargas útiles de los trabajos más el estado que conserva para los completados y fallidos. Un trabajo en cola que lleve contexto de campaña y destinatario es realista que ocupe 2–5 KB. A 3 KB por trabajo, 30 MB está en el orden de 10.000 trabajos en vuelo. Suena generoso hasta que lo comparas con el límite de la plataforma que la aplicación respeta: 750 respuestas privadas por hora y por cuenta. Una acumulación por límite de velocidad que llegue siquiera a unas pocas horas de tráfico empieza a presionar el Redis gratuito, y el Redis gratuito es el componente con menos margen de todo el stack.

Ninguno de los dos límites es un defecto de diseño. Son la consecuencia natural de elegir la capa gratuita de todo, que es una decisión razonable para el público al que apunta la documentación. Pero «gratis para siempre» y «gratis en el volumen donde esto se convierte en un negocio» son afirmaciones distintas, y solo la primera está sobre la mesa.

Tres fallos que cuestan una tarde cada uno

La documentación dedica espacio a tres modos de fallo que comparten una propiedad: el mensaje de error apunta a otro sitio que la causa. Los enumero porque son el mejor argumento de que esta documentación se escribió desde la operación real y no desde una plantilla.

1. Publicar tu app no amplía quién puede conectarse. Una app de Meta publicada sigue teniendo Standard Access sobre instagram_business_basic, instagram_business_manage_comments e instagram_business_manage_messages. Publicar pone la app en producción; no cambia a qué cuentas cubren los permisos. Así que tu primera cuenta se conecta perfectamente y tu segunda cuenta —la de un cliente— falla. El síntoma, citado de la guía: aparece la pantalla de consentimiento, el inicio de sesión funciona, el intercambio de código devuelve un token IGAA… válido con todos los permisos solicitados, y entonces todas las llamadas contra graph.instagram.com son rechazadas con:

Unsupported request - method type: get  [code=100, type=IGApiException]

Nada en ese mensaje sugiere un rol ausente, y el token no es el problema.

2. Una herramienta anterior puede seguir siendo dueña de la conversación. Si la cuenta de Instagram estuvo conectada alguna vez a ManyChat u otra herramienta de comentario-a-DM —aunque la suscripción se cancelara— esa herramienta puede seguir siendo la propietaria de la conversación del lado de Meta. El resultado es un fallo parcial que parece un error de código: los comentarios funcionan, la respuesta pública se publica, el primer DM llega, y luego cada pulsación de botón dentro del DM falla en silencio con The action is invalid since it's not the thread owner. [code=100 sub=2534037]. La solución no está en OpenReply en absoluto; está en Meta Business Suite, en Configuración → Integraciones → Enrutamiento de conversaciones → Aplicaciones asociadas, donde eliminas la herramienta antigua y concedes a tu app tanto «Access all conversations» como «Take control of conversations». Instagram deja deliberadamente que cualquier app conectada envíe esa primera respuesta privada, que es exactamente por lo que el fallo solo aparece en la segunda interacción.

3. La clave de cifrado es un punto único de fallo sin ruta de recuperación. ENCRYPTION_KEY tiene que ser idéntica byte a byte en la aplicación web y en el worker, porque la aplicación web escribe el token de Instagram cifrado y el worker lo descifra para enviar. Una discrepancia significa que cada envío falla al descifrar. Perderla después significa lo mismo de forma permanente, para cada cuenta conectada, sin ruta de migración: la documentación dice «Losing or changing it means every connected account has to reconnect.» En un stack gratuito distribuido —Vercel más un host de worker aparte más un Postgres gestionado— esa clave es la única pieza de estado que tiene que estar bien en tres sitios y que no tiene más copia de seguridad que la que hagas tú.

Hay una cuarta, estructural, que merece nombrarse. El worker tiene que estar siempre encendido y las opciones gratuitas no son equivalentes. La instancia micro siempre gratuita de Oracle son 1 GB de RAM en una tenencia compartida con un historial bien documentado de recuperaciones no anunciadas, mantenida viva con pm2. Ejecutará esta aplicación. También es el componente con más probabilidad de desaparecer sin aviso, y cuando lo hace el modo de fallo es «llegan los webhooks, no se envía nada»: visible en /api/health como worker.healthy: false, e invisible para quien comentó y no recibió respuesta.

Para quién sirve realmente esto

Sirve de verdad para un creador individual o una marca única que gestiona su propia cuenta. Este es el caso para el que se diseñó la vía gratuita. Conectas una o dos cuentas profesionales, añades tu propio usuario como tester de la app, te saltas la revisión por completo y ejecutas todo en el stack gratuito documentado. El flujo que automatiza es uno por el que ManyChat y sus competidores cobran mensualmente, y obtienes una implementación autoalojada e inspeccionable por el costo de tu tiempo. La barrera de seguimiento, los botones de enlace con seguimiento y los registros de DM son funciones reales, no casillas marcadas.

Sirve de verdad para una agencia técnica que ya tiene una entidad legal registrada. La verificación de empresa es la barrera dura, y si la superas, la revisión de app desbloquea Advanced Access y el número de cuentas deja de ser una línea de facturación. En ese punto lo sensato es dejar de usar el stack gratuito distribuido y autoalojar worker, Postgres y Redis en un solo VPS, porque los límites de 30 MB de Redis y 0,5 GB de Neon nunca se dimensionaron para volumen de clientes.

Es un mal negocio para un freelance o alguien que trabaja solo y sin empresa. No porque el software sea malo, sino porque la vía gratuita te está cerrada por un requisito que no puedes cumplir, y la vía de pago es un precio por cuenta que escala con tu número de clientes. De tres a diez cuentas, el patrocinador cuesta 6 $ por cuenta al mes; súmale una mejora de alojamiento para el worker y una base de datos que aguante tráfico real, y estás cerca de la suscripción de la que intentabas escapar, mientras además asumes la operación. Las palabras que hay que buscar son las que usa docs/setup.md: «If you do not have a registered business, most self-hosters skip this entirely by running their own instance for their own account.» Esa frase soporta mucho peso.

Es un mal negocio para un responsable de marketing sin perfil técnico. Los tres fallos de arriba no son casos límite; son la experiencia normal de la primera semana conectando Instagram a través de Meta. Diagnosticar el fallo de propiedad de la conversación exige leer un error code=100 sub=2534037 y saber que hay que mirar en Business Suite. Migrar desde otra herramienta tiene un orden documentado y nada obvio. Si tu tiempo vale más que una suscripción, la suscripción es el producto más barato.

Preguntas frecuentes

¿OpenReply es realmente gratis? El software tiene licencia MIT y es gratuito, y la propia API de Instagram lo es. El alojamiento es gratis si usas el stack gratuito documentado. Lo que no es gratis es atender las cuentas de Instagram de otras personas: eso requiere la revisión de app de Meta con verificación de empresa, que exige una entidad legal registrada. Si la tienes, el costo marginal sigue cerca de cero. Si no, tus opciones son solo tus propias cuentas, o un proveedor de conexión de pago.

¿Puedo usarlo ya para mis clientes? Solo si pasas la verificación de empresa de Meta, o si pagas a un proveedor de conexión como Zernio. La ruta gratuita cubre las cuentas que tienen un rol de administrador, desarrollador o tester en tu app, y esa lista significa en la práctica tú y las personas que invites personalmente.

¿Necesito un VPS? Sí, salvo que pagues por un plan siempre activo en otro sitio. El worker es un proceso de larga duración y la documentación afirma que no puede ejecutarse en Vercel porque las funciones serverless son efímeras. Railway, Render, Fly o cualquier máquina siempre encendida sirven; el despliegue gratuito de referencia usa una VM micro siempre gratuita de Oracle.

¿Por qué falla la pulsación del botón del DM si el primer DM funcionó? Casi con certeza es la propiedad de la conversación. Instagram deja que cualquier app conectada envíe la única respuesta privada que dispara un comentario, pero cada mensaje posterior tiene que venir de la app dueña de la conversación. Si la cuenta estuvo alguna vez conectada a otra herramienta de comentario-a-DM, elimínala y toma el control en Meta Business Suite → Configuración → Integraciones → Enrutamiento de conversaciones → Aplicaciones asociadas.

¿Hace algo con TikTok u otras plataformas? No en main en el commit que cloné. Hay un pull request abierto que propone respuestas automáticas a comentarios de TikTok mediante la TikTok API for Business, y otro que propone una API de espacio de trabajo de solo lectura con soporte de MCP. Ninguno está fusionado.

¿Qué pasa cuando Meta cambia la API? Parcheas tu fork. No hay releases ni tags, así que no hay versión que fijar ni historia de actualización más allá de tirar de main. Un mantenedor tiene 108 de 191 commits muestreados, y Meta revisa las versiones de la Graph API con cadencia regular, así que la capacidad de mantenimiento es el riesgo real a largo plazo, más que cualquier error concreto.

¿Es seguro conectar mi cuenta de Instagram? El diseño es cumplidor más que ingenioso: solo API oficial de Instagram, sin scraping, sin automatización de navegador, sin manejo de contraseñas, tokens cifrados en reposo con AES-256-GCM. Los riesgos de cumplimiento son operativos: guarda una copia de ENCRYPTION_KEY en un sitio donde la encuentres, y mantén cerrada la lista ALLOWED_EMAILS, porque una lista sin definir significa que cualquiera que alcance tu URL puede pedir un enlace mágico y obtener su propio espacio de trabajo.

Conclusión

OpenReply es la rara «alternativa open source» que merece la etiqueta. La ingeniería es cuidadosa, la documentación está escrita desde la práctica y el stack gratuito publicado es lo bastante concreto como para auditarlo en lugar de intuirlo. Si gestionas tu propia cuenta de Instagram y quieres comentario-a-DM sin suscripción, esta es una vía creíble para conseguirlo, y la cantidad de conocimiento operativo codificado en docs/setup.md merece leerse incluso si eliges otra herramienta.

Lo que me gustaría que un lector se llevara es más estrecho que «es gratis». La función que automatiza está detrás de un permiso de Meta que la plataforma no reparte por mérito técnico. Para tu propia cuenta, ese permiso es efectivamente tuyo. Para la cuenta de un cliente, requiere una entidad legal, un screencast, justificaciones escritas y presupuesto para un reenvío, y la propia documentación del proyecto, escrita por un mantenedor que claramente intenta ser franco, te dice que te quedes con tu propia cuenta. Todo lo demás se deriva de esa línea: por qué el argumento del patrocinador es «we’ve done the platform reviews», por qué la capa gratuita se detiene donde se detiene, y por qué esto es una buena herramienta para un público y un desvío caro para otro.

Comprueba de qué lado del límite estás antes de desplegar. Se responde con una sola pregunta: las cuentas de Instagram que piensas conectar, ¿son tuyas o de otra persona?