📩 DM Responder (Messenger + Instagram)
Archivo: /Users/user/rifai-agents/agentes/social/dm-responder.ts · Plist: com.rifai.dm-responder (solo en ~/Library/LaunchAgents/, no en cron/) · Horario: cada 3 min (StartInterval 180s, RunAtLoad false)
Qué hace
Cada 3 minutos lee las conversaciones de Facebook Messenger e Instagram Direct de RifKings y responde los DMs cuyo último mensaje es del cliente, encarnando a "Sergio". Usa un LLM local enriquecido con el Brain: productos del catálogo, conversaciones similares ganadoras y memoria cross-conversación del propio cliente (perfil e histórico). Hace lead scoring por intent; si el lead es red_hot intenta crear un draft order en Shopify y adjunta el link de pago directo. Escala quejas y leads calientes por notificación a Cristina/Sergio. No realiza cobros: solo genera el draft (link de pago).
Cómo funciona
1. Carga .env y estado data/dm-responder-state.json (replied_msg_ids, conversaciones, historial).
2. Por plataforma (fb, ig): pide a Graph API hasta 20 conversaciones con sus 5 últimos mensajes.
3. Ordena mensajes por fecha; procesa solo si el último es del cliente (no de la página/IG business) y no fue respondido.
4. Calcula isComplaint / isPurchaseIntent por keywords y scoreLead() (de tools/shopify-sales.js) sobre el mensaje + turnos previos.
5. buildSystemPrompt() añade al prompt base: perfil del cliente (getCustomerProfile), histórico (getCustomerHistory), productos (getRelatedProducts) y conversaciones similares (getSimilarConversations).
6. Genera respuesta con claude() (haiku, máx ~50 palabras).
7. Si band === 'red_hot' y no es queja: findVariantByQuery() + createDraftOrder() y añade el invoice_url al mensaje.
8. Envía con Graph API (/me/messages FB, /{IG_ID}/messages IG). Guarda historial. Escala: queja → cs_complaint; lead hot/red_hot → cs_question con datos del draft.
Cómo funciona la escalación / autonomía
Responde DMs solo (alineado con feedback_secretario_autonomia: Sergio sí contesta comerciales). Crea draft orders (no cobra). Quejas y leads calientes se notifican para revisión humana.
Datos/APIs
- Meta Graph API v21.0 (Messenger + IG Direct):
pages_messaging+instagram_manage_messages. - Shopify Admin API vía
tools/shopify-sales.js:scoreLead,findVariantByQuery,createDraftOrder. - Brain (
brain/tools/brain.js):getRelatedProducts,getSimilarConversations,getCustomerHistory,getCustomerProfile. - LLM local
tools/gemini-cli(haiku). - notify-router: eventos
cs_question,cs_complaint,social_engagement. - Vars
.env:META_PAGE_ID(fallback 112610281241802),META_PAGE_TOKEN/META_ACCESS_TOKEN,INSTAGRAM_BUSINESS_ID(fallback 17841401185807202); indirectamente las de Shopify que useshopify-sales.js.
Cómo probarlo
cd /Users/user/rifai-agents && npx tsx agentes/social/dm-responder.ts
Sin flag FORCE; consulta API real y responde DMs reales. Salida esperada: cabecera 📩 DM Responder, nº de conversaciones FB/IG, líneas ✅ [cliente] mensaje → respuesta, posibles 💰 Draft order ... invoice_url, y resumen 📊 DMs procesados / Respondidos / Quejas escaladas.
Si se rompe / recuperar
launchctl unload ~/Library/LaunchAgents/com.rifai.dm-responder.plist
launchctl load ~/Library/LaunchAgents/com.rifai.dm-responder.plist
Logs: /Users/user/rifai-agents/logs/dm-responder.out.log y .err.log. Fallos típicos: token Meta sin permisos de mensajería (ventana de 24h de Messenger), Shopify token caducado (drafts fallan pero el DM se responde igual), Brain caído (cae al prompt base). Plist NO versionado en cron/.
Cómo replicarlo
- Token de Página Meta con
pages_messaging+instagram_manage_messagesy IDs en.env. tools/shopify-sales.jscon acceso a Shopify Admin (draft orders) — opcional si se quita el cierre.- Brain con perfil/histórico/productos/conversaciones (memoria cross-conversación).
- LLM local
tools/gemini-cliytools/notify-router. - Estado JSON para deduplicar mensajes + plist
StartInterval180.