| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- import {readFileSync, writeFileSync, existsSync} from 'fs';
- /**
- * @type {import('@whiskeysockets/baileys')}
- */
- const {initAuthCreds, BufferJSON, proto} = (await import('@whiskeysockets/baileys')).default;
- /**
- * @param {import('@whiskeysockets/baileys').WASocket | import('@whiskeysockets/baileys').WALegacySocket}
- */
- function bind(conn) {
- if (!conn.chats) conn.chats = {};
- /**
- *
- * @param {import('@whiskeysockets/baileys').Contact[]|{contacts:import('@whiskeysockets/baileys').Contact[]}} contacts
- * @returns
- */
- function updateNameToDb(contacts) {
- if (!contacts) return;
- try {
- contacts = contacts.contacts || contacts;
- for (const contact of contacts) {
- const id = conn.decodeJid(contact.id);
- if (!id || id === 'status@broadcast') continue;
- let chats = conn.chats[id];
- if (!chats) chats = conn.chats[id] = {...contact, id};
- conn.chats[id] = {
- ...chats,
- ...({
- ...contact, id, ...(id.endsWith('@g.us') ?
- {subject: contact.subject || contact.name || chats.subject || ''} :
- {name: contact.notify || contact.name || chats.name || chats.notify || ''}),
- } || {}),
- };
- }
- } catch (e) {
- // console.error(e);
- }
- }
- conn.ev.on('contacts.upsert', updateNameToDb);
- conn.ev.on('groups.update', updateNameToDb);
- conn.ev.on('contacts.set', updateNameToDb);
- conn.ev.on('chats.set', async ({chats}) => {
- try {
- for (let {id, name, readOnly} of chats) {
- id = conn.decodeJid(id);
- if (!id || id === 'status@broadcast') continue;
- const isGroup = id.endsWith('@g.us');
- let chats = conn.chats[id];
- if (!chats) chats = conn.chats[id] = {id};
- chats.isChats = !readOnly;
- if (name) chats[isGroup ? 'subject' : 'name'] = name;
- if (isGroup) {
- const metadata = await conn.groupMetadata(id).catch((_) => null);
- if (name || metadata?.subject) chats.subject = name || metadata.subject;
- if (!metadata) continue;
- chats.metadata = metadata;
- }
- }
- } catch (e) {
- // console.error(e);
- }
- });
- conn.ev.on('group-participants.update', async function updateParticipantsToDb({id, participants, action}) {
- if (!id) return;
- id = conn.decodeJid(id);
- if (id === 'status@broadcast') return;
- if (!(id in conn.chats)) conn.chats[id] = {id};
- const chats = conn.chats[id];
- chats.isChats = true;
- const groupMetadata = await conn.groupMetadata(id).catch((_) => null);
- if (!groupMetadata) return;
- chats.subject = groupMetadata.subject;
- chats.metadata = groupMetadata;
- });
- conn.ev.on('groups.update', async function groupUpdatePushToDb(groupsUpdates) {
- try {
- for (const update of groupsUpdates) {
- const id = conn.decodeJid(update.id);
- if (!id || id === 'status@broadcast') continue;
- const isGroup = id.endsWith('@g.us');
- if (!isGroup) continue;
- let chats = conn.chats[id];
- if (!chats) chats = conn.chats[id] = {id};
- chats.isChats = true;
- const metadata = await conn.groupMetadata(id).catch((_) => null);
- if (metadata) chats.metadata = metadata;
- if (update.subject || metadata?.subject) chats.subject = update.subject || metadata.subject;
- }
- } catch (e) {
- // console.error(e);
- }
- });
- conn.ev.on('chats.upsert', function chatsUpsertPushToDb(chatsUpsert) {
- try {
- const {id, name} = chatsUpsert;
- if (!id || id === 'status@broadcast') return;
- conn.chats[id] = {...(conn.chats[id] || {}), ...chatsUpsert, isChats: true};
- const isGroup = id.endsWith('@g.us');
- if (isGroup) conn.insertAllGroup().catch((_) => null);
- } catch (e) {
- // console.error(e);
- }
- });
- conn.ev.on('presence.update', async function presenceUpdatePushToDb({id, presences}) {
- try {
- const sender = Object.keys(presences)[0] || id;
- const _sender = conn.decodeJid(sender);
- const presence = presences[sender]['lastKnownPresence'] || 'composing';
- let chats = conn.chats[_sender];
- if (!chats) chats = conn.chats[_sender] = {id: sender};
- chats.presences = presence;
- if (id.endsWith('@g.us')) {
- let chats = conn.chats[id];
- if (!chats) chats = conn.chats[id] = {id};
- }
- } catch (e) {
- // console.error(e);
- }
- });
- }
- const KEY_MAP = {
- 'pre-key': 'preKeys',
- 'session': 'sessions',
- 'sender-key': 'senderKeys',
- 'app-state-sync-key': 'appStateSyncKeys',
- 'app-state-sync-version': 'appStateVersions',
- 'sender-key-memory': 'senderKeyMemory',
- };
- /**
- *
- * @param {String} filename
- * @param {import('pino').Logger} logger
- * @returns
- */
- function useSingleFileAuthState(filename, logger) {
- let creds; let keys = {}; let saveCount = 0;
- // save the authentication state to a file
- const saveState = (forceSave) => {
- logger?.trace('saving auth state');
- saveCount++;
- if (forceSave || saveCount > 5) {
- writeFileSync(
- filename,
- // BufferJSON replacer utility saves buffers nicely
- JSON.stringify({creds, keys}, BufferJSON.replacer, 2),
- );
- saveCount = 0;
- }
- };
- if (existsSync(filename)) {
- const result = JSON.parse(
- readFileSync(filename, {encoding: 'utf-8'}),
- BufferJSON.reviver,
- );
- creds = result.creds;
- keys = result.keys;
- } else {
- creds = initAuthCreds();
- keys = {};
- }
- return {
- state: {
- creds,
- keys: {
- get: (type, ids) => {
- const key = KEY_MAP[type];
- return ids.reduce(
- (dict, id) => {
- let value = keys[key]?.[id];
- if (value) {
- if (type === 'app-state-sync-key') {
- value = proto.AppStateSyncKeyData.fromObject(value);
- }
- dict[id] = value;
- }
- return dict;
- }, {},
- );
- },
- set: (data) => {
- for (const _key in data) {
- const key = KEY_MAP[_key];
- keys[key] = keys[key] || {};
- Object.assign(keys[key], data[_key]);
- }
- saveState();
- },
- },
- },
- saveState,
- };
- }
- function loadMessage(jid, id = null) {
- let message = null;
- // If only 1 param, first param is assumed to be id not jid
- if (jid && !id) {
- id = jid;
- /** @type {(m: import('@whiskeysockets/baileys').proto.WebMessageInfo) => Boolean} */
- const filter = (m) => m.key?.id == id;
- const messages = {};
- const messageFind = Object.entries(messages)
- .find(([, msgs]) => {
- return msgs.find(filter);
- });
- message = messageFind?.[1]?.find(filter);
- } else {
- // @ts-ignore
- jid = jid?.decodeJid?.();
- const messages = {};
- if (!(jid in messages)) return null;
- message = messages[jid].find((m) => m.key.id == id);
- }
- return message ? message : null;
- }
- export default {
- bind,
- useSingleFileAuthState,
- loadMessage,
- };
|