91 lines
2.9 KiB
JavaScript
91 lines
2.9 KiB
JavaScript
const { Client, LocalAuth } = require('whatsapp-web.js');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const DATA_DIR = './data';
|
|
const MESSAGES_FILE = path.join(DATA_DIR, 'messages.jsonl');
|
|
const CHATS_FILE = path.join(DATA_DIR, 'chats.json');
|
|
const LIMIT_PER_CHAT = 50; // messages to fetch per chat per run
|
|
|
|
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
|
|
// Load already saved message IDs to avoid duplicates
|
|
function loadSavedIds() {
|
|
if (!fs.existsSync(MESSAGES_FILE)) return new Set();
|
|
const lines = fs.readFileSync(MESSAGES_FILE, 'utf8').trim().split('\n').filter(Boolean);
|
|
return new Set(lines.map(l => JSON.parse(l).id));
|
|
}
|
|
|
|
// Append new messages to jsonl
|
|
function saveMessages(messages) {
|
|
const lines = messages.map(m => JSON.stringify(m)).join('\n') + '\n';
|
|
fs.appendFileSync(MESSAGES_FILE, lines);
|
|
}
|
|
|
|
// Save chat index
|
|
function saveChats(chats) {
|
|
fs.writeFileSync(CHATS_FILE, JSON.stringify(chats, null, 2));
|
|
}
|
|
|
|
const client = new Client({
|
|
authStrategy: new LocalAuth(),
|
|
puppeteer: {
|
|
executablePath: '/usr/sbin/chromium',
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
|
|
}
|
|
});
|
|
|
|
client.on('qr', (qr) => {
|
|
// Only needed first time — after that LocalAuth handles it
|
|
const qrcode = require('qrcode-terminal');
|
|
qrcode.generate(qr, { small: true });
|
|
});
|
|
|
|
client.on('ready', async () => {
|
|
console.log('✅ Connected — starting sync...');
|
|
|
|
const savedIds = loadSavedIds();
|
|
const chats = await client.getChats();
|
|
const chatIndex = [];
|
|
const newMessages = [];
|
|
|
|
for (const chat of chats) {
|
|
console.log(`📥 Fetching: ${chat.name}`);
|
|
chatIndex.push({
|
|
id: chat.id._serialized,
|
|
name: chat.name,
|
|
isGroup: chat.isGroup,
|
|
lastSync: new Date().toISOString()
|
|
});
|
|
|
|
try {
|
|
const messages = await chat.fetchMessages({ limit: LIMIT_PER_CHAT });
|
|
for (const msg of messages) {
|
|
if (savedIds.has(msg.id._serialized)) continue; // skip duplicates
|
|
newMessages.push({
|
|
id: msg.id._serialized,
|
|
chat: chat.name,
|
|
chatId: chat.id._serialized,
|
|
from: msg.from,
|
|
fromName: msg.author || msg.from,
|
|
timestamp: msg.timestamp,
|
|
date: new Date(msg.timestamp * 1000).toISOString(),
|
|
body: msg.body,
|
|
type: msg.type,
|
|
isGroup: chat.isGroup,
|
|
hasMedia: msg.hasMedia
|
|
});
|
|
}
|
|
} catch (err) {
|
|
console.error(`❌ Failed on ${chat.name}:`, err.message);
|
|
}
|
|
}
|
|
|
|
saveChats(chatIndex);
|
|
saveMessages(newMessages);
|
|
console.log(`✅ Sync done — ${newMessages.length} new messages saved.`);
|
|
process.exit(0);
|
|
});
|
|
|
|
client.initialize();
|