Actualizar server.js
This commit is contained in:
54
server.js
54
server.js
@@ -310,8 +310,12 @@ function genCode6() { return String(Math.floor(100000 + Math.random() * 900000))
|
||||
// 🛡️ MIDDLEWARE DE PLANES (CORREGIDO)
|
||||
async function requirePlan(req, res, next, feature) {
|
||||
try {
|
||||
// Quitamos subscription_status para que no dé error en BD actualizadas
|
||||
const q = await pool.query("SELECT plan_tier FROM users WHERE id=$1", [req.user.accountId]);
|
||||
const userPlan = 'pro'; // Forzamos PRO para pruebas
|
||||
|
||||
// ⚠️ TRUCO TEMPORAL: Forzamos a que el sistema te lea como 'pro' para que puedas probar WhatsApp sin bloqueos
|
||||
const userPlan = 'pro'; // Cuando quieras restringir planes, cambia esto por: q.rows[0]?.plan_tier || 'free';
|
||||
|
||||
const limits = PLAN_LIMITS[userPlan];
|
||||
|
||||
if (!limits || !limits[feature]) {
|
||||
@@ -353,6 +357,7 @@ async function sendWhatsAppAuto(originalPhone, text, instanceName, useDelay = tr
|
||||
let payloadConEscribiendo;
|
||||
const typingTimeMs = Math.min(Math.max(text.length * 30, 1500), 8000);
|
||||
|
||||
// Añadimos una cabecera para que sepas a quién iba dirigido realmente el mensaje
|
||||
const textWithNotice = `*(PRUEBA - Iba para: ${originalPhone})*\n\n` + text;
|
||||
|
||||
if(useDelay) {
|
||||
@@ -637,13 +642,12 @@ async function triggerWhatsAppEvent(ownerId, serviceId, eventType) {
|
||||
// 2. Buscamos qué plantilla corresponde a este evento
|
||||
const tplTypeMap = {
|
||||
'wa_evt_welcome': 'welcome',
|
||||
'wa_evt_assigned': 'assigned', // <--- NUEVO: Asignado a operario
|
||||
'wa_evt_date': 'appointment',
|
||||
'wa_evt_update': 'update',
|
||||
'wa_evt_assigned': 'assigned', // NUEVO: Asignado a operario
|
||||
'wa_evt_date': 'appointment', // Plantilla: Cita Creada
|
||||
'wa_evt_update': 'update', // Plantilla: Modificación de Servicio
|
||||
'wa_evt_onway': 'on_way',
|
||||
'wa_evt_survey': 'survey'
|
||||
};
|
||||
|
||||
};
|
||||
const tplQ = await pool.query("SELECT content FROM message_templates WHERE owner_id=$1 AND type=$2", [ownerId, tplTypeMap[eventType]]);
|
||||
if (tplQ.rowCount === 0 || !tplQ.rows[0].content) return;
|
||||
let text = tplQ.rows[0].content;
|
||||
@@ -660,7 +664,7 @@ async function triggerWhatsAppEvent(ownerId, serviceId, eventType) {
|
||||
const phoneClean = phone.replace('+34', '').trim();
|
||||
const clientQ = await pool.query("SELECT portal_token FROM clients WHERE phone LIKE $1 AND owner_id=$2 LIMIT 1", [`%${phoneClean}%`, ownerId]);
|
||||
const token = clientQ.rowCount > 0 ? clientQ.rows[0].portal_token : "ERROR";
|
||||
const linkMagico = `https://portal.integrarepara.es/?token=${token}`;
|
||||
const linkMagico = `https://portal.integrarepara.es/?token=${token}&service=${serviceId}`;
|
||||
|
||||
// ==========================================
|
||||
// 🔄 5. TRADUCTOR DE FECHAS AL FORMATO ESPAÑOL + DÍA
|
||||
@@ -691,7 +695,6 @@ async function triggerWhatsAppEvent(ownerId, serviceId, eventType) {
|
||||
} catch (e) { console.error("Error Motor WA:", e.message); }
|
||||
}
|
||||
|
||||
|
||||
app.get("/providers/credentials", authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const q = await pool.query("SELECT provider, username, last_sync, status FROM provider_credentials WHERE owner_id=$1", [req.user.accountId]);
|
||||
@@ -786,6 +789,8 @@ app.post("/providers/automate/:id", authMiddleware, async (req, res) => {
|
||||
VALUES ($1, $2, $3, CURRENT_TIMESTAMP + INTERVAL '5 minutes')
|
||||
`, [id, worker.id, token]);
|
||||
|
||||
// CÁLCULO DE HORA 100% FIABLE: Se lo pedimos a Node forzando a España
|
||||
// Así siempre saldrá "0:40" en lugar de "23:40" en el texto de WhatsApp
|
||||
const horaCaducidad = new Date(Date.now() + 5 * 60 * 1000).toLocaleTimeString('es-ES', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
@@ -807,6 +812,7 @@ app.post("/providers/automate/:id", authMiddleware, async (req, res) => {
|
||||
|
||||
🔗 ${link}`;
|
||||
|
||||
// SAAS: INSTANCIA DE CLIENTE ESPECÍFICA SIN AWAIT PARA NO BLOQUEAR
|
||||
const instanceName = `cliente_${req.user.accountId}`;
|
||||
sendWhatsAppAuto(worker.phone, mensaje, instanceName, useDelay).catch(console.error);
|
||||
|
||||
@@ -966,29 +972,19 @@ app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => {
|
||||
const statusQ = await pool.query("SELECT name FROM service_statuses WHERE id=$1", [status_operativo]);
|
||||
const stName = statusQ.rows[0]?.name.toLowerCase() || "";
|
||||
|
||||
// ... dentro de la lógica del Motor en set-appointment ...
|
||||
const stName = statusQ.rows[0]?.name.toLowerCase() || "";
|
||||
|
||||
if (stName.includes('asignado')) {
|
||||
// Si el estado contiene "asignado", disparamos el nuevo evento
|
||||
// --- MOTOR DE EVENTOS CORREGIDO ---
|
||||
if (stName.includes('asignado')) {
|
||||
// Si el estado contiene "asignado", disparar plantilla específica
|
||||
triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_assigned');
|
||||
} else if (stName.includes('citado') && newDate !== "") {
|
||||
// ... resto de lógica que ya tenemos ...
|
||||
|
||||
|
||||
|
||||
// REGLA ESTRICTA: ¿Es estado Citado y tiene fecha?
|
||||
if (stName.includes('citado') && newDate !== "") {
|
||||
} else if (stName.includes('citado') && newDate !== "") {
|
||||
if (oldDate === "") {
|
||||
// No tenía fecha antes -> Dispara "Cita Creada"
|
||||
// Primera vez que se pone fecha
|
||||
triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_date');
|
||||
} else if (oldDate !== newDate || oldTime !== newTime) {
|
||||
// Ya tenía fecha y se ha cambiado -> Dispara "Modificación"
|
||||
// Cambio de fecha u hora
|
||||
triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_update');
|
||||
}
|
||||
}
|
||||
// Otras reglas
|
||||
else if (stName.includes('camino')) {
|
||||
} else if (stName.includes('camino')) {
|
||||
triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_onway');
|
||||
} else if (stName.includes('finalizado') || stName.includes('terminado')) {
|
||||
triggerWhatsAppEvent(req.user.accountId, id, 'wa_evt_survey');
|
||||
@@ -1007,10 +1003,14 @@ app.post("/services/manual-high", authMiddleware, async (req, res) => {
|
||||
const { phone, name, address, description, guild_id, assigned_to, mode } = req.body;
|
||||
const serviceRef = "MAN-" + Date.now().toString().slice(-6);
|
||||
const rawData = { "Nombre Cliente": name, "Teléfono": phone, "Dirección": address, "Descripción": description, "guild_id": guild_id };
|
||||
await pool.query(`
|
||||
const insert = await pool.query(`
|
||||
INSERT INTO scraped_services (owner_id, provider, service_ref, raw_data, status, automation_status, assigned_to)
|
||||
VALUES ($1, 'MANUAL', $2, $3, 'pending', $4, $5)
|
||||
VALUES ($1, 'MANUAL', $2, $3, 'pending', $4, $5) RETURNING id
|
||||
`, [req.user.accountId, serviceRef, JSON.stringify(rawData), mode === 'auto' ? 'manual' : 'completed', mode === 'manual' ? assigned_to : null]);
|
||||
|
||||
// Disparar Bienvenida / Alta
|
||||
triggerWhatsAppEvent(req.user.accountId, insert.rows[0].id, 'wa_evt_welcome');
|
||||
|
||||
res.json({ ok: true });
|
||||
} catch (e) { res.status(500).json({ ok: false }); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user