|
const { isJidBroadcast, isJidGroup, isJidNewsletter } = require('@whiskeysockets/baileys'); |
|
const fs = require('fs/promises') |
|
const path = require('path') |
|
const { DataTypes } = require('sequelize'); |
|
const { DATABASE } = require('../lib/database'); |
|
const storeDir = path.join(process.cwd(), 'store'); |
|
|
|
const readJSON = async (file) => { |
|
try { |
|
const filePath = path.join(storeDir, file); |
|
const data = await fs.readFile(filePath, 'utf8'); |
|
return JSON.parse(data); |
|
} catch { |
|
return []; |
|
} |
|
}; |
|
|
|
const writeJSON = async (file, data) => { |
|
const filePath = path.join(storeDir, file); |
|
await fs.mkdir(storeDir, { recursive: true }); |
|
await fs.writeFile(filePath, JSON.stringify(data, null, 2)); |
|
}; |
|
|
|
const saveContact = async (jid, name) => { |
|
if (!jid || !name || isJidGroup(jid) || isJidBroadcast(jid) || isJidNewsletter(jid)) return; |
|
const contacts = await readJSON('contact.json'); |
|
const index = contacts.findIndex((contact) => contact.jid === jid); |
|
if (index > -1) { |
|
contacts[index].name = name; |
|
} else { |
|
contacts.push({ jid, name }); |
|
} |
|
await writeJSON('contact.json', contacts); |
|
}; |
|
|
|
const getContacts = async () => { |
|
try { |
|
const contacts = await readJSON('contact.json'); |
|
return contacts; |
|
} catch (error) { |
|
return []; |
|
} |
|
}; |
|
|
|
const saveMessage = async (message) => { |
|
const jid = message.key.remoteJid; |
|
const id = message.key.id; |
|
if (!id || !jid || !message) return; |
|
await saveContact(message.sender, message.pushName); |
|
const messages = await readJSON('message.json'); |
|
const index = messages.findIndex((msg) => msg.id === id && msg.jid === jid); |
|
const timestamp = message.messageTimestamp ? message.messageTimestamp * 1000 : Date.now(); |
|
if (index > -1) { |
|
messages[index].message = message; |
|
messages[index].timestamp = timestamp; |
|
} else { |
|
messages.push({ id, jid, message, timestamp }); |
|
} |
|
await writeJSON('message.json', messages); |
|
}; |
|
|
|
const loadMessage = async (id) => { |
|
if (!id) return null; |
|
const messages = await readJSON('message.json'); |
|
return messages.find((msg) => msg.id === id) || null; |
|
}; |
|
|
|
const getName = async (jid) => { |
|
const contacts = await readJSON('contact.json'); |
|
const contact = contacts.find((contact) => contact.jid === jid); |
|
return contact ? contact.name : jid.split('@')[0].replace(/_/g, ' '); |
|
}; |
|
|
|
const saveGroupMetadata = async (jid, client) => { |
|
if (!isJidGroup(jid)) return; |
|
const groupMetadata = await client.groupMetadata(jid); |
|
const metadata = { |
|
jid: groupMetadata.id, |
|
subject: groupMetadata.subject, |
|
subjectOwner: groupMetadata.subjectOwner, |
|
subjectTime: groupMetadata.subjectTime |
|
? new Date(groupMetadata.subjectTime * 1000).toISOString() |
|
: null, |
|
size: groupMetadata.size, |
|
creation: groupMetadata.creation ? new Date(groupMetadata.creation * 1000).toISOString() : null, |
|
owner: groupMetadata.owner, |
|
desc: groupMetadata.desc, |
|
descId: groupMetadata.descId, |
|
linkedParent: groupMetadata.linkedParent, |
|
restrict: groupMetadata.restrict, |
|
announce: groupMetadata.announce, |
|
isCommunity: groupMetadata.isCommunity, |
|
isCommunityAnnounce: groupMetadata.isCommunityAnnounce, |
|
joinApprovalMode: groupMetadata.joinApprovalMode, |
|
memberAddMode: groupMetadata.memberAddMode, |
|
ephemeralDuration: groupMetadata.ephemeralDuration, |
|
}; |
|
|
|
const metadataList = await readJSON('metadata.json'); |
|
const index = metadataList.findIndex((meta) => meta.jid === jid); |
|
if (index > -1) { |
|
metadataList[index] = metadata; |
|
} else { |
|
metadataList.push(metadata); |
|
} |
|
await writeJSON('metadata.json', metadataList); |
|
|
|
const participants = groupMetadata.participants.map((participant) => ({ |
|
jid, |
|
participantId: participant.id, |
|
admin: participant.admin, |
|
})); |
|
await writeJSON(`${jid}_participants.json`, participants); |
|
}; |
|
|
|
const getGroupMetadata = async (jid) => { |
|
if (!isJidGroup(jid)) return null; |
|
const metadataList = await readJSON('metadata.json'); |
|
const metadata = metadataList.find((meta) => meta.jid === jid); |
|
if (!metadata) return null; |
|
|
|
const participants = await readJSON(`${jid}_participants.json`); |
|
return { ...metadata, participants }; |
|
}; |
|
const saveMessageCount = async (message) => { |
|
if (!message) return; |
|
const jid = message.key.remoteJid; |
|
const sender = message.key.participant || message.sender; |
|
if (!jid || !sender || !isJidGroup(jid)) return; |
|
|
|
const messageCounts = await readJSON('message_count.json'); |
|
const index = messageCounts.findIndex((record) => record.jid === jid && record.sender === sender); |
|
|
|
if (index > -1) { |
|
messageCounts[index].count += 1; |
|
} else { |
|
messageCounts.push({ jid, sender, count: 1 }); |
|
} |
|
|
|
await writeJSON('message_count.json', messageCounts); |
|
}; |
|
|
|
const getInactiveGroupMembers = async (jid) => { |
|
if (!isJidGroup(jid)) return []; |
|
const groupMetadata = await getGroupMetadata(jid); |
|
if (!groupMetadata) return []; |
|
|
|
const messageCounts = await readJSON('message_count.json'); |
|
const inactiveMembers = groupMetadata.participants.filter((participant) => { |
|
const record = messageCounts.find((msg) => msg.jid === jid && msg.sender === participant.id); |
|
return !record || record.count === 0; |
|
}); |
|
|
|
return inactiveMembers.map((member) => member.id); |
|
}; |
|
|
|
const getGroupMembersMessageCount = async (jid) => { |
|
if (!isJidGroup(jid)) return []; |
|
const messageCounts = await readJSON('message_count.json'); |
|
const groupCounts = messageCounts |
|
.filter((record) => record.jid === jid && record.count > 0) |
|
.sort((a, b) => b.count - a.count); |
|
|
|
return Promise.all( |
|
groupCounts.map(async (record) => ({ |
|
sender: record.sender, |
|
name: await getName(record.sender), |
|
messageCount: record.count, |
|
})) |
|
); |
|
}; |
|
|
|
const getChatSummary = async () => { |
|
const messages = await readJSON('message.json'); |
|
const distinctJids = [...new Set(messages.map((msg) => msg.jid))]; |
|
|
|
const summaries = await Promise.all( |
|
distinctJids.map(async (jid) => { |
|
const chatMessages = messages.filter((msg) => msg.jid === jid); |
|
const messageCount = chatMessages.length; |
|
const lastMessage = chatMessages.sort( |
|
(a, b) => new Date(b.timestamp) - new Date(a.timestamp) |
|
)[0]; |
|
const chatName = isJidGroup(jid) ? jid : await getName(jid); |
|
|
|
return { |
|
jid, |
|
name: chatName, |
|
messageCount, |
|
lastMessageTimestamp: lastMessage ? lastMessage.timestamp : null, |
|
}; |
|
}) |
|
); |
|
|
|
return summaries.sort( |
|
(a, b) => new Date(b.lastMessageTimestamp) - new Date(a.lastMessageTimestamp) |
|
); |
|
}; |
|
|
|
const saveMessageV1 = saveMessage; |
|
const saveMessageV2 = (message) => { |
|
return Promise.all([saveMessageV1(message), saveMessageCount(message)]); |
|
}; |
|
|
|
module.exports = { |
|
saveContact, |
|
loadMessage, |
|
getName, |
|
getChatSummary, |
|
saveGroupMetadata, |
|
getGroupMetadata, |
|
saveMessageCount, |
|
getInactiveGroupMembers, |
|
getGroupMembersMessageCount, |
|
saveMessage: saveMessageV2, |
|
}; |
|
|
|
|