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,
|
||||
// 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 });
|
||||
}
|
||||
|
||||
@ -72,7 +78,7 @@ export async function POST(req: Request) {
|
||||
|
||||
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 lowerText = text.trim().toLowerCase();
|
||||
|
||||
@ -82,27 +88,71 @@ export async function POST(req: Request) {
|
||||
|
||||
const { databases, storage } = await createAdminClient();
|
||||
|
||||
// LOGIC 1: APROBAR PUBLICACIÓN
|
||||
if (isReply && lowerText.includes('aprobar')) {
|
||||
// Extraer ID de la referencia en el mensaje del bot
|
||||
const refMatch = quotedText.match(/Ref:\s*([a-zA-Z0-9_-]+)/);
|
||||
if (refMatch && refMatch[1]) {
|
||||
const postId = refMatch[1];
|
||||
// LOGIC 1: RESPUESTA DE APROBACIÓN O RECHAZO
|
||||
const isApprovalWord = lowerText.includes('aprobar') || lowerText.includes('publicar') || lowerText === 'si' || lowerText === 'sí' || lowerText === 'ok';
|
||||
const isRejectionWord = lowerText.includes('rechazar') || lowerText.includes('descartar') || lowerText.includes('cancelar') || lowerText === 'no';
|
||||
|
||||
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 {
|
||||
// Actualizar Appwrite
|
||||
await databases.updateDocument(
|
||||
const drafts = await databases.listDocuments(
|
||||
APPWRITE_ALMEIRA_CONFIG.databaseId,
|
||||
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})`);
|
||||
return NextResponse.json({ success: true, message: 'Post aprobado' }, { status: 200 });
|
||||
if (postId) {
|
||||
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) {
|
||||
console.error("Error approving post:", e);
|
||||
await sendWhatsAppMessage(remoteJid, `❌ Error al publicar: ${e.message}`);
|
||||
console.error('Error al actualizar estado del post:', e);
|
||||
await sendWhatsAppMessage(remoteJid, `❌ Error al procesar tu decisión: ${e.message}`);
|
||||
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 = '';
|
||||
if (candidateMediaList.length > 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');
|
||||
} 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`
|
||||
+ `*Título:* ${parsed.titulo}\n`
|
||||
+ `*Tipo:* ${parsed.tipo.toUpperCase()} (${isSquare ? 'Cuadrado 640x640' : 'Panorámico 640x360'})\n`
|
||||
const requestText = `🔔 *SOLICITUD DE APROBACIÓN DE PUBLICACIÓN* 🔔\n`
|
||||
+ `_Almeira Web • Asistente Editorial con IA_\n\n`
|
||||
+ `📌 *Título:* ${parsed.titulo}\n`
|
||||
+ `📂 *Categoría:* ${parsed.tipo.toUpperCase()} (${isSquare ? 'Cuadrado 640x640' : 'Panorámico 640x360'})\n`
|
||||
+ (imageNotice ? `${imageNotice}` : '')
|
||||
+ `*SEO:* ${parsed.seo_descripcion}\n\n`
|
||||
+ `Para aprobar esta publicación, responde a este mismo mensaje con la palabra "Aprobar".\n\n`
|
||||
+ `📝 *Resumen:* ${parsed.seo_descripcion}\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})`;
|
||||
|
||||
await sendWhatsAppMessage(remoteJid, requestText);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user