diff --git a/dripzone-app/android/app/src/main/java/co/dripzone/app/security/SecurityManager.kt b/dripzone-app/android/app/src/main/java/co/dripzone/app/security/SecurityManager.kt index c7372cc..e99db39 100644 --- a/dripzone-app/android/app/src/main/java/co/dripzone/app/security/SecurityManager.kt +++ b/dripzone-app/android/app/src/main/java/co/dripzone/app/security/SecurityManager.kt @@ -15,7 +15,8 @@ object SecurityManager { private const val TAG = "DripSecurity" private const val PREFS_FILE = "dripzone_secure_prefs" - const val WHATSAPP_STORE_PHONE = "573167455877" + const val WHATSAPP_STORE_PHONE = "573106390296" // Línea oficial exclusiva de DripZone + const val CARLOS_PERSONAL_PHONE = "573167455877" // WhatsApp personal de Carlos /** * Initializes secure EncryptedSharedPreferences using Android KeyStore MasterKey (AES-256 GCM) diff --git a/dripzone-app/docker-compose.prod.yml b/dripzone-app/docker-compose.prod.yml index 3dc049a..cedfc7d 100644 --- a/dripzone-app/docker-compose.prod.yml +++ b/dripzone-app/docker-compose.prod.yml @@ -16,8 +16,11 @@ services: - NEXT_PUBLIC_APPWRITE_MEDIA_BUCKET_ID=sneakers_media_bucket - APPWRITE_API_KEY=standard_cce3cdb866ea6433888d40cedd24dc45987372308fdc3dd0697de08648c0e5c7e04b02c3bcee271403fd656b00a5820f04c08b51631284a6e8a3582d8aed2aa33234f3c29cc777e9b162eb54810b789251b0d006a9a3b081ebc2da53b9baa94614b124b3508ad849fd9a4187cc6094f506d4b57f409b69d9562a74df594f3ec3 - EVOLUTION_API_URL=https://evolution.almeira.com.co - - EVOLUTION_API_KEY=EE49029EEB85-4568-8F81-C9FDFC6E2943 - - EVOLUTION_INSTANCE_NAME=AutomataAlmeira + - EVOLUTION_INSTANCE_NAME=DripZone + - EVOLUTION_API_KEY=83B5BD230796-4324-AE73-3508F69E279D + - EVOLUTION_FEED_INSTANCE_NAME=AutomataAlmeira + - EVOLUTION_FEED_API_KEY=EE49029EEB85-4568-8F81-C9FDFC6E2943 + - NEXT_PUBLIC_WHATSAPP_PHONE=573106390296 - GEMINI_API_KEY=AIzaSyC7JMkREYxl4qoEUGzd4hzbJ6RFg_YMxx0 - BOLD_ENVIRONMENT=sandbox - BOLD_SANDBOX_IDENTITY_KEY=GatyXH-WVfX1pv17z8GAoNekbqps8Mdxdvj0yRg4BSk diff --git a/dripzone-app/src/app/api/whatsapp-feed/route.ts b/dripzone-app/src/app/api/whatsapp-feed/route.ts index 2b619fe..2b2d249 100644 --- a/dripzone-app/src/app/api/whatsapp-feed/route.ts +++ b/dripzone-app/src/app/api/whatsapp-feed/route.ts @@ -15,8 +15,8 @@ import { import { SupplierPost, MonitoredWhatsAppGroup } from '@/types'; const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL || 'https://evolution.almeira.com.co'; -const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; -const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_INSTANCE_NAME || 'AutomataAlmeira'; +const EVOLUTION_API_KEY = process.env.EVOLUTION_FEED_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; +const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_FEED_INSTANCE_NAME || 'AutomataAlmeira'; export async function GET(request: Request) { try { diff --git a/dripzone-app/src/app/api/whatsapp-groups/route.ts b/dripzone-app/src/app/api/whatsapp-groups/route.ts index 397e390..ea8d76a 100644 --- a/dripzone-app/src/app/api/whatsapp-groups/route.ts +++ b/dripzone-app/src/app/api/whatsapp-groups/route.ts @@ -8,8 +8,8 @@ import { } from '@/lib/server-appwrite'; const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL || 'https://evolution.almeira.com.co'; -const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; -const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_INSTANCE_NAME || 'AutomataAlmeira'; +const EVOLUTION_API_KEY = process.env.EVOLUTION_FEED_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; +const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_FEED_INSTANCE_NAME || 'AutomataAlmeira'; export async function GET(request: Request) { try { diff --git a/dripzone-app/src/lib/evolution-api.ts b/dripzone-app/src/lib/evolution-api.ts index 6976842..42b5124 100644 --- a/dripzone-app/src/lib/evolution-api.ts +++ b/dripzone-app/src/lib/evolution-api.ts @@ -2,8 +2,14 @@ import axios from 'axios'; import { formatCOP } from './pricing-engine'; const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL || 'https://evolution.almeira.com.co'; -const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; -const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_INSTANCE_NAME || 'AutomataAlmeira'; + +// Instancia oficial exclusiva de DripZone (Para pedidos, confirmaciones, OTP, cobros Bold y atención a clientes) +const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || '83B5BD230796-4324-AE73-3508F69E279D'; +const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_INSTANCE_NAME || 'DripZone'; + +// Instancia personal de Carlos (Para scraping de publicaciones y grupos de WhatsApp) +export const EVOLUTION_FEED_API_KEY = process.env.EVOLUTION_FEED_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943'; +export const EVOLUTION_FEED_INSTANCE_NAME = process.env.EVOLUTION_FEED_INSTANCE_NAME || 'AutomataAlmeira'; function resolveRecipient(target: string): string { const trimmed = target.trim(); @@ -16,14 +22,23 @@ function resolveRecipient(target: string): string { /** * Enviar mensaje de texto por WhatsApp a través de Evolution API v2 + * Usa por defecto la línea oficial DripZone */ -export async function sendWhatsAppMessage(toPhone: string, message: string): Promise { +export async function sendWhatsAppMessage( + toPhone: string, + message: string, + customInstance?: string, + customApiKey?: string +): Promise { const recipient = resolveRecipient(toPhone); if (!recipient) return false; + const instance = customInstance || EVOLUTION_INSTANCE_NAME; + const apiKey = customApiKey || EVOLUTION_API_KEY; + try { const response = await axios.post( - `${EVOLUTION_API_URL}/message/sendText/${EVOLUTION_INSTANCE_NAME}`, + `${EVOLUTION_API_URL}/message/sendText/${instance}`, { number: recipient, text: message, @@ -31,7 +46,7 @@ export async function sendWhatsAppMessage(toPhone: string, message: string): Pro }, { headers: { - apikey: EVOLUTION_API_KEY, + apikey: apiKey, 'Content-Type': 'application/json', }, timeout: 20000, @@ -39,21 +54,31 @@ export async function sendWhatsAppMessage(toPhone: string, message: string): Pro ); return response.status === 200 || response.status === 201; } catch (error: any) { - console.error('Error enviando mensaje de WhatsApp:', error?.response?.data || error?.message); + console.error(`Error enviando mensaje de WhatsApp (${instance}):`, error?.response?.data || error?.message); return false; } } /** * Enviar mensaje con foto/catálogo a través de Evolution API v2 + * Usa por defecto la línea oficial DripZone */ -export async function sendWhatsAppMedia(toPhone: string, imageUrl: string, caption: string): Promise { +export async function sendWhatsAppMedia( + toPhone: string, + imageUrl: string, + caption: string, + customInstance?: string, + customApiKey?: string +): Promise { const recipient = resolveRecipient(toPhone); if (!recipient) return false; + const instance = customInstance || EVOLUTION_INSTANCE_NAME; + const apiKey = customApiKey || EVOLUTION_API_KEY; + try { const response = await axios.post( - `${EVOLUTION_API_URL}/message/sendMedia/${EVOLUTION_INSTANCE_NAME}`, + `${EVOLUTION_API_URL}/message/sendMedia/${instance}`, { number: recipient, mediatype: 'image', @@ -64,7 +89,7 @@ export async function sendWhatsAppMedia(toPhone: string, imageUrl: string, capti }, { headers: { - apikey: EVOLUTION_API_KEY, + apikey: apiKey, 'Content-Type': 'application/json', }, timeout: 25000, @@ -72,7 +97,7 @@ export async function sendWhatsAppMedia(toPhone: string, imageUrl: string, capti ); return response.status === 200 || response.status === 201; } catch (error: any) { - console.error('Error enviando media por WhatsApp:', error?.response?.data || error?.message); + console.error(`Error enviando media por WhatsApp (${instance}):`, error?.response?.data || error?.message); return false; } } diff --git a/scripts/deploy_vps.py b/scripts/deploy_vps.py index 2dd54df..fa981b3 100644 --- a/scripts/deploy_vps.py +++ b/scripts/deploy_vps.py @@ -18,8 +18,8 @@ REMOTE_BASE = "/home/carlos/apps/dripzone-app" LOCAL_BASE = r"c:\Users\Carlos\dev\almeira-web\dripzone-app" EVOLUTION_API_URL = "https://evolution.almeira.com.co" -EVOLUTION_API_KEY = "EE49029EEB85-4568-8F81-C9FDFC6E2943" -INSTANCE_NAME = "AutomataAlmeira" +EVOLUTION_API_KEY = "83B5BD230796-4324-AE73-3508F69E279D" +INSTANCE_NAME = "DripZone" TARGET_PHONE = "573167455877" APK_URL = "https://dripzone.almeira.com.co/DripZone.apk" @@ -31,6 +31,8 @@ FILES_TO_SYNC = [ "src/app/api/bold/status/route.ts", "src/app/api/webhook/bold/route.ts", "src/app/api/whatsapp-media/route.ts", + "src/app/api/whatsapp-feed/route.ts", + "src/app/api/whatsapp-groups/route.ts", "src/app/api/users/route.ts", "src/app/checkout/page.tsx", "src/components/store/CartDrawer.tsx", @@ -115,23 +117,20 @@ def main(): print("[5/5] Enviando notificación detallada y archivo APK al WhatsApp de Carlos (+57 316 745 5877)...") message_text = ( - "🚀 *DripZone v1.5 - Dominio drip-zone.online & Pasarela Bold Bre-B*\n\n" - "Hola Carlos, se ha implementado en producción la configuración completa:\n\n" - "🌐 *1. Dominio Oficial drip-zone.online:*\n" - "• Configurado el servidor de producción (Traefik y Docker) para responder en *drip-zone.online*, *www.drip-zone.online* y el alias de respaldo `dripzone.almeira.com.co`.\n" - "• Certificados SSL automáticos (Let's Encrypt) habilitados.\n" - "• *Paso restante en tu registrador:* Asegúrate de apuntar los registros A de `drip-zone.online` y `www.drip-zone.online` a la IP del VPS: `161.97.93.156`.\n\n" - "💳 *2. Cobro de Separación con QR Bre-B y Pasarela Bold:*\n" - "• Al registrar el pedido, se genera la orden de cobro en Bold por *$10.000 COP*.\n" - "• En la Web y en la App Nativa se renderiza en tiempo real el *Código QR Bre-B*, permitiendo escanear y pagar al instante desde Bancolombia, Nequi, Daviplata o cualquier banco.\n" - "• Incluye botón directo al checkout seguro de Bold para tarjetas de crédito/débito o PSE.\n\n" - "⚡ *3. Acreditación Automática en Tiempo Real:*\n" - "• Detección inmediata en vivo con Webhook (`/api/webhook/bold`) y sondeo reactivo.\n" - "• Cuando el cliente paga, la orden pasa a `deposit_received`, se descuenta el anticipo del saldo contraentrega y se te envía notificación inmediata con los datos del pago.\n\n" - "🔑 *4. Modo Sandbox Activo para Pruebas:*\n" - "• Operando con las llaves de prueba de la API (`GatyXH...` / `BAFlCP...`) para pruebas sin costo. Las llaves de producción ya están listas para activarse.\n\n" - "📲 *5. App Nativa Android v1.5:*\n" - "• Compilada con soporte dinámico para `drip-zone.online` y QR Bre-B.\n\n" + "🚀 *DripZone v1.6 - Línea Oficial Exclusiva & Instancia DripZone Conectada*\n\n" + "Hola Carlos, se ha implementado en producción la división operativa solicitada:\n\n" + "📱 *1. Línea Celular Exclusiva DripZone (+57 310 639 0296):*\n" + "• Conectada exitosamente en Evolution API bajo la instancia *DripZone* (Token: `83B5BD230796-4324-AE73-3508F69E279D`).\n" + "• Todos los envíos de códigos de seguridad OTP, confirmaciones de pedidos, recibos de abono Bold y chats de soporte con clientes ahora se emiten de forma exclusiva desde esta línea oficial.\n\n" + "📥 *2. Recepción de Productos y Publicaciones (Tu WhatsApp Personal):*\n" + "• Se mantiene conectada tu instancia personal *AutomataAlmeira* para la lectura de los grupos de proveedores mayoristas donde recibes el calzado.\n" + "• Ninguna publicación se interrumpe y la catalogación inteligente sigue operando con tus grupos personales.\n\n" + "🌐 *3. Dominio Oficial drip-zone.online:*\n" + "• Configurado el servidor de producción (Traefik y Docker) para responder en *drip-zone.online*, *www.drip-zone.online* y el alias `dripzone.almeira.com.co`.\n\n" + "💳 *4. Pasarela Bold & QR Bre-B en Vivo:*\n" + "• Generación dinámica de QR Bre-B para el cobro de la separación de $10.000 COP y acreditación automática en tiempo real.\n\n" + "📲 *5. App Nativa Android v1.6 Sincronizada:*\n" + "• Compilada con la nueva línea de atención oficial (+57 310 639 0296) y soporte dinámico para `drip-zone.online`.\n\n" f"🔗 *Descarga Directa:* {APK_URL}\n\n" "Te adjunto el APK compilado para que puedas instalarlo y probar la experiencia de usuario." )