almeira-web/publish-cauca.js

205 lines
8.7 KiB
JavaScript

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: `<p>${cleanCaption.replace(/\n/g, '<br/>')}</p>`, // Formato HTML básico
imagen_destacada_id: mediaDoc.$id
}
);
} catch(e) {
console.error("Post error:", e.message);
throw e;
}
console.log(`[Success] Published post ${publishedCount + 1}/8 for Month ${month}`);
publishedCount++;
} catch (err) {
console.error(`Failed to publish image for month ${month}:`, err.message);
}
}
if (publishedCount < 8) {
console.log(`Could only publish ${publishedCount} images for Month ${month} (ran out of images).`);
}
}
console.log("All done!");
} catch (e) {
console.error("Error:", e.message);
}
}
run();