feat(whatsapp): optimizar notificacion de aprobacion y rechazo interactivo en WhatsApp
This commit is contained in:
parent
886db53cab
commit
7ff2dd41fb
@ -48,7 +48,13 @@ export async function POST(req: Request) {
|
|||||||
|
|
||||||
// Ignorar mensajes generados por el bot para evitar bucle infinito,
|
// Ignorar mensajes generados por el bot para evitar bucle infinito,
|
||||||
// pero permitir tests que el administrador envíe desde el mismo celular del bot.
|
// pero permitir tests que el administrador envíe desde el mismo celular del bot.
|
||||||
if (fromMe && (rawText.includes('📰 *Publicación Procesada') || rawText.includes('✅ La publicación ha sido aprobada') || rawText.includes('❌ Error al publicar'))) {
|
if (fromMe && (
|
||||||
|
rawText.includes('SOLICITUD DE APROBACIÓN') ||
|
||||||
|
rawText.includes('Publicación Procesada') ||
|
||||||
|
rawText.includes('PUBLICACIÓN APROBADA') ||
|
||||||
|
rawText.includes('PUBLICACIÓN RECHAZADA') ||
|
||||||
|
rawText.includes('Error al publicar')
|
||||||
|
)) {
|
||||||
return NextResponse.json({ success: true, message: 'Ignored bot self-message loop' }, { status: 200 });
|
return NextResponse.json({ success: true, message: 'Ignored bot self-message loop' }, { status: 200 });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +78,7 @@ export async function POST(req: Request) {
|
|||||||
|
|
||||||
console.log(`[WhatsApp Webhook] Chat autorizado detectado: "${filterResult.resolvedName}" (JID: ${remoteJid})`);
|
console.log(`[WhatsApp Webhook] Chat autorizado detectado: "${filterResult.resolvedName}" (JID: ${remoteJid})`);
|
||||||
|
|
||||||
// Extraer texto del mensaje (ya guardado en rawText, lo mantenemos como text para retrocompatibilidad interna)
|
// Extraer texto del mensaje
|
||||||
const text = rawText;
|
const text = rawText;
|
||||||
const lowerText = text.trim().toLowerCase();
|
const lowerText = text.trim().toLowerCase();
|
||||||
|
|
||||||
@ -82,27 +88,71 @@ export async function POST(req: Request) {
|
|||||||
|
|
||||||
const { databases, storage } = await createAdminClient();
|
const { databases, storage } = await createAdminClient();
|
||||||
|
|
||||||
// LOGIC 1: APROBAR PUBLICACIÓN
|
// LOGIC 1: RESPUESTA DE APROBACIÓN O RECHAZO
|
||||||
if (isReply && lowerText.includes('aprobar')) {
|
const isApprovalWord = lowerText.includes('aprobar') || lowerText.includes('publicar') || lowerText === 'si' || lowerText === 'sí' || lowerText === 'ok';
|
||||||
// Extraer ID de la referencia en el mensaje del bot
|
const isRejectionWord = lowerText.includes('rechazar') || lowerText.includes('descartar') || lowerText.includes('cancelar') || lowerText === 'no';
|
||||||
const refMatch = quotedText.match(/Ref:\s*([a-zA-Z0-9_-]+)/);
|
|
||||||
if (refMatch && refMatch[1]) {
|
|
||||||
const postId = refMatch[1];
|
|
||||||
|
|
||||||
|
if (isApprovalWord || isRejectionWord) {
|
||||||
|
// Intentar extraer el ID de la referencia en el mensaje citado o en el texto
|
||||||
|
let postId: string | null = null;
|
||||||
|
const refMatch = quotedText.match(/Ref:\s*([a-zA-Z0-9_-]+)/) || rawText.match(/Ref:\s*([a-zA-Z0-9_-]+)/);
|
||||||
|
if (refMatch && refMatch[1]) {
|
||||||
|
postId = refMatch[1];
|
||||||
|
} else {
|
||||||
|
// Fallback: buscar el borrador más reciente
|
||||||
try {
|
try {
|
||||||
// Actualizar Appwrite
|
const drafts = await databases.listDocuments(
|
||||||
await databases.updateDocument(
|
|
||||||
APPWRITE_ALMEIRA_CONFIG.databaseId,
|
APPWRITE_ALMEIRA_CONFIG.databaseId,
|
||||||
APPWRITE_ALMEIRA_CONFIG.collections.posts,
|
APPWRITE_ALMEIRA_CONFIG.collections.posts,
|
||||||
postId,
|
[
|
||||||
{ estado: 'publicado' }
|
Query.equal('estado', 'borrador'),
|
||||||
|
Query.orderDesc('$createdAt'),
|
||||||
|
Query.limit(1)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
if (drafts.documents.length > 0) {
|
||||||
|
postId = drafts.documents[0].$id;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('No se pudo consultar el borrador más reciente:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await sendWhatsAppMessage(remoteJid, `✅ La publicación ha sido aprobada y publicada exitosamente.\n(ID: ${postId})`);
|
if (postId) {
|
||||||
return NextResponse.json({ success: true, message: 'Post aprobado' }, { status: 200 });
|
try {
|
||||||
|
if (isApprovalWord) {
|
||||||
|
const updatedPost = await databases.updateDocument(
|
||||||
|
APPWRITE_ALMEIRA_CONFIG.databaseId,
|
||||||
|
APPWRITE_ALMEIRA_CONFIG.collections.posts,
|
||||||
|
postId,
|
||||||
|
{ estado: 'publicado' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const approvalMsg = `✅ *¡PUBLICACIÓN APROBADA Y EN VIVO!*\n\n`
|
||||||
|
+ `📌 *${updatedPost.titulo}*\n`
|
||||||
|
+ `🌐 *Ver en el portal:* https://almeira.com.co/${updatedPost.slug}\n\n`
|
||||||
|
+ `(ID: ${postId})`;
|
||||||
|
|
||||||
|
await sendWhatsAppMessage(remoteJid, approvalMsg);
|
||||||
|
return NextResponse.json({ success: true, message: 'Post aprobado y publicado' }, { status: 200 });
|
||||||
|
} else if (isRejectionWord) {
|
||||||
|
await databases.updateDocument(
|
||||||
|
APPWRITE_ALMEIRA_CONFIG.databaseId,
|
||||||
|
APPWRITE_ALMEIRA_CONFIG.collections.posts,
|
||||||
|
postId,
|
||||||
|
{ estado: 'archivado' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const rejectionMsg = `🚫 *PUBLICACIÓN RECHAZADA*\n\n`
|
||||||
|
+ `El borrador ha sido descartado y no será publicado en Almeira Web.\n\n`
|
||||||
|
+ `(ID: ${postId})`;
|
||||||
|
|
||||||
|
await sendWhatsAppMessage(remoteJid, rejectionMsg);
|
||||||
|
return NextResponse.json({ success: true, message: 'Post rechazado y archivado' }, { status: 200 });
|
||||||
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error("Error approving post:", e);
|
console.error('Error al actualizar estado del post:', e);
|
||||||
await sendWhatsAppMessage(remoteJid, `❌ Error al publicar: ${e.message}`);
|
await sendWhatsAppMessage(remoteJid, `❌ Error al procesar tu decisión: ${e.message}`);
|
||||||
return NextResponse.json({ success: false, error: e.message }, { status: 500 });
|
return NextResponse.json({ success: false, error: e.message }, { status: 500 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,22 +294,27 @@ export async function POST(req: Request) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Notificar al grupo de WhatsApp pidiendo aprobación
|
// Notificar al grupo de WhatsApp pidiendo aprobación explícita
|
||||||
let imageNotice = '';
|
let imageNotice = '';
|
||||||
if (candidateMediaList.length > 1) {
|
if (candidateMediaList.length > 1) {
|
||||||
const chosenNum = (parsed.selected_image_index ?? 0) + 1;
|
const chosenNum = (parsed.selected_image_index ?? 0) + 1;
|
||||||
imageNotice = `*Imagen Destacada:* Foto #${chosenNum} de ${candidateMediaList.length} analizadas`
|
imageNotice = `🖼️ *Imagen Destacada:* Foto #${chosenNum} de ${candidateMediaList.length} analizadas`
|
||||||
+ (parsed.image_selection_reason ? ` (${parsed.image_selection_reason})\n` : '\n');
|
+ (parsed.image_selection_reason ? ` (${parsed.image_selection_reason})\n` : '\n');
|
||||||
} else if (candidateMediaList.length === 1) {
|
} else if (candidateMediaList.length === 1) {
|
||||||
imageNotice = `*Imagen Destacada:* 1 foto procesada (${isSquare ? 'Formato 640x640' : 'Formato 640x360'})\n`;
|
imageNotice = `🖼️ *Imagen Destacada:* 1 foto procesada (${isSquare ? 'Formato 640x640' : 'Formato 640x360'})\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestText = `📰 *Publicación Procesada (Pendiente de Aprobación)*\n\n`
|
const requestText = `🔔 *SOLICITUD DE APROBACIÓN DE PUBLICACIÓN* 🔔\n`
|
||||||
+ `*Título:* ${parsed.titulo}\n`
|
+ `_Almeira Web • Asistente Editorial con IA_\n\n`
|
||||||
+ `*Tipo:* ${parsed.tipo.toUpperCase()} (${isSquare ? 'Cuadrado 640x640' : 'Panorámico 640x360'})\n`
|
+ `📌 *Título:* ${parsed.titulo}\n`
|
||||||
|
+ `📂 *Categoría:* ${parsed.tipo.toUpperCase()} (${isSquare ? 'Cuadrado 640x640' : 'Panorámico 640x360'})\n`
|
||||||
+ (imageNotice ? `${imageNotice}` : '')
|
+ (imageNotice ? `${imageNotice}` : '')
|
||||||
+ `*SEO:* ${parsed.seo_descripcion}\n\n`
|
+ `📝 *Resumen:* ${parsed.seo_descripcion}\n\n`
|
||||||
+ `Para aprobar esta publicación, responde a este mismo mensaje con la palabra "Aprobar".\n\n`
|
+ `━━━━━━━━━━━━━━━━━━━━━━\n`
|
||||||
|
+ `¿Autorizas la publicación en el portal?\n\n`
|
||||||
|
+ `👉 Responde a este mensaje con:\n`
|
||||||
|
+ `✅ *Aprobar* (para publicar en vivo en la web)\n`
|
||||||
|
+ `❌ *Rechazar* (para descartar el borrador)\n\n`
|
||||||
+ `(Ref: ${newPost.$id})`;
|
+ `(Ref: ${newPost.$id})`;
|
||||||
|
|
||||||
await sendWhatsAppMessage(remoteJid, requestText);
|
await sendWhatsAppMessage(remoteJid, requestText);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user