const fs = require('fs'); const axios = require('axios'); const { Client, Databases, Storage, ID } = require('node-appwrite'); require('dotenv').config({ path: '.env.local' }); // Let's try to get InputFile if it exists in node-appwrite/file (for older SDKs) let InputFile; try { InputFile = require('node-appwrite/file').InputFile; } catch (e) { InputFile = null; } const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL; const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY; const EVOLUTION_INSTANCE_NAME = process.env.EVOLUTION_INSTANCE_NAME; const CHAT_ID = '573134848203-1408546044@g.us'; const client = new Client() .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT) .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID) .setKey(process.env.APPWRITE_API_KEY); const databases = new Databases(client); const storage = new Storage(client); const DB_ID = process.env.APPWRITE_DATABASE_ID; const BUCKET_ID = process.env.NEXT_PUBLIC_APPWRITE_MEDIA_BUCKET_ID; async function getCollectionIds() { const list = await databases.listCollections(DB_ID); const map = {}; list.collections.forEach(c => { map[c.name.toLowerCase()] = c.$id; }); return map; } async function run() { console.log("Starting publishing process..."); try { const collections = await getCollectionIds(); const postsCollectionId = collections['posts'] || 'posts'; const mediaCollectionId = collections['media'] || 'media'; const pubTypesCollectionId = collections['publication types'] || collections['publication_types'] || 'publication_types'; const pubTypes = await databases.listDocuments(DB_ID, pubTypesCollectionId); const defaultPubTypeId = pubTypes.documents.length > 0 ? pubTypes.documents[0].$id : null; if (!defaultPubTypeId) { console.error("No publication types found. Can't create posts."); return; } const allImages = []; let currentPage = 1; let totalPages = 1; console.log("Fetching messages from Evolution API..."); do { const response = await axios.post( `${EVOLUTION_API_URL}/chat/findMessages/${EVOLUTION_INSTANCE_NAME}?page=${currentPage}&limit=100`, { where: { "key": { "remoteJid": CHAT_ID } } }, { headers: { 'apikey': EVOLUTION_API_KEY, 'Content-Type': 'application/json' } } ); const messagesObj = response.data.messages || {}; totalPages = messagesObj.pages || 1; const records = messagesObj.records || []; for (const msg of records) { if (msg.messageType === 'imageMessage') { allImages.push(msg); } } if (currentPage > 40) break; currentPage++; } while (currentPage <= totalPages); console.log(`Total images found in chat history: ${allImages.length}`); // We need 32 images (8 for March, 8 for April, 8 for May, 8 for June) // If we don't have enough images, we'll just use as many as we have. // We'll distribute them artificially over the months if the actual timestamps are all from June. let targetMonths = [3, 4, 5, 6]; let imageIndex = 0; for (const month of targetMonths) { console.log(`\n--- Publishing for Month ${month} ---`); let publishedCount = 0; while (publishedCount < 8 && imageIndex < allImages.length) { const msg = allImages[imageIndex]; imageIndex++; try { // Get base64 const base64Res = await axios.post( `${EVOLUTION_API_URL}/chat/getBase64FromMediaMessage/${EVOLUTION_INSTANCE_NAME}`, { message: msg }, { headers: { 'apikey': EVOLUTION_API_KEY, 'Content-Type': 'application/json' } } ); const base64Data = base64Res.data.base64; if (!base64Data) continue; const buffer = Buffer.from(base64Data, 'base64'); const filePath = `/tmp/image-${month}-${publishedCount}.jpeg`; const filename = `image-${month}-${publishedCount}.jpeg`; fs.writeFileSync(filePath, buffer); // Appwrite File Upload Compatibility let fileParam; if (InputFile && InputFile.fromPath) { fileParam = InputFile.fromPath(filePath, filename); } else if (InputFile && InputFile.fromBuffer) { fileParam = InputFile.fromBuffer(buffer, filename); } else { // Fallback to node fs read stream (works in some SDKs) or directly passing string path if supported // Appwrite 1.x Node SDK usually accepts a ReadStream fileParam = fs.createReadStream(filePath); } const file = await storage.createFile( BUCKET_ID, ID.unique(), fileParam ); let mediaDoc; try { mediaDoc = await databases.createDocument( DB_ID, mediaCollectionId, ID.unique(), { file_id: file.$id, bucket_id: BUCKET_ID, titulo: `Pieza Gráfica Gobernación del Cauca - Mes ${month}`, tipo: 'imagen' } ); } catch (e) { console.error("Media error:", e.message); throw e; } let caption = msg.message?.imageMessage?.caption || `Pieza gráfica de la Gobernación del Cauca correspondiente al mes ${month}.`; let title = `Boletín Gobernación - Mes ${month} #${publishedCount + 1}`; if (caption && caption.length >= 5) { const lines = caption.split('\n').map(l => l.trim()).filter(l => l.length > 5); if (lines.length > 0) { title = lines[0]; if ((title.toUpperCase() === title || title.includes("GOBERNACIÓN")) && lines.length > 1) { title = lines[1]; } title = title.replace(/^[\p{Emoji}\s]+/gu, ''); if (title.length > 100) title = title.substring(0, 100) + '...'; } } const slug = `gobernacion-cauca-mes-${month}-pub-${publishedCount}-${Date.now()}`; const realDate = new Date(msg.messageTimestamp * 1000).toISOString(); const cleanCaption = caption || `Publicación gráfica de la Gobernación del Cauca para el mes de ${month}.`; try { await databases.createDocument( DB_ID, postsCollectionId, ID.unique(), { titulo: title, slug: slug, tipo_publicacion_id: defaultPubTypeId, estado: 'borrador', // Cambiado a borrador para revisión fecha_publicacion: realDate, // Fecha real del mensaje contenido: `
${cleanCaption.replace(/\n/g, '
')}