UNPKG

baileys-bottle-devstroupe

Version:

A little package made by deadlinecode and updated by vspok for storing all the data from baileys in whatever database you want to use by using typeorm

637 lines 29.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const baileys_1 = require("baileys"); const Chat_1 = require("../entity/Chat"); const Contact_1 = require("../entity/Contact"); const Message_1 = require("../entity/Message"); const MessageDic_1 = require("../entity/MessageDic"); const PresenceDic_1 = require("../entity/PresenceDic"); const GroupMetadata_1 = require("../entity/GroupMetadata"); const typeorm_1 = require("typeorm"); const lodash_1 = require("lodash"); const moment_1 = __importDefault(require("moment")); class StoreHandle { constructor(ds, auth, options) { this.ds = ds; this.auth = auth; this.options = options; this.repos = { contacts: this.ds.getRepository(Contact_1.Contact), chats: this.ds.getRepository(Chat_1.Chat), messageDics: this.ds.getRepository(MessageDic_1.MessageDic), messages: this.ds.getRepository(Message_1.Message), presenceDics: this.ds.getRepository(PresenceDic_1.PresenceDic), groups: this.ds.getRepository(GroupMetadata_1.GroupMetadata), }; this.state = { connection: "close" }; this.chats = { all: () => this.repos.chats.findBy({ DBAuth: { id: this.auth.id, }, }), id: (id) => this.repos.chats.findOneBy({ id, DBAuth: { id: this.auth.id, }, }), }; this.contacts = { all: () => this.repos.contacts.findBy({ DBAuth: { id: this.auth.id, }, }), id: (id) => this.repos.contacts.findOneBy({ id, DBAuth: { id: this.auth.id, }, }), }; this.messages = { all: (jid) => __awaiter(this, void 0, void 0, function* () { var _a; return (_a = (yield this.repos.messageDics.findOne({ where: { jid, DBAuth: { id: this.auth.id, }, }, relations: ["messages"], }))) === null || _a === void 0 ? void 0 : _a.messages; }), id: (jid, msgId) => __awaiter(this, void 0, void 0, function* () { var _a; return (_a = (yield this.repos.messageDics.findOne({ where: { jid, DBAuth: { id: this.auth.id, }, }, relations: ["messages"], }))) === null || _a === void 0 ? void 0 : _a.messages.find((x) => x.msgId === msgId); }), }; this.groupMetadata = { all: () => this.repos.groups.findBy({ DBAuth: { id: this.auth.id, }, }), id: (id) => this.repos.groups.findOneBy({ id, DBAuth: { id: this.auth.id, }, }), }; this.presence = { all: (id) => __awaiter(this, void 0, void 0, function* () { var _a; return (_a = (yield this.repos.presenceDics.findOne({ where: { id, DBAuth: { id: this.auth.id, }, }, relations: ["presences"], }))) === null || _a === void 0 ? void 0 : _a.presences; }), id: (id, participant) => __awaiter(this, void 0, void 0, function* () { var _a; return (_a = (yield this.repos.presenceDics.findOne({ where: { id, DBAuth: { id: this.auth.id, }, }, relations: ["presences"], }))) === null || _a === void 0 ? void 0 : _a.presences.find((x) => x.participant === participant); }), }; this.contactsUpsert = (newContacts) => __awaiter(this, void 0, void 0, function* () { // Atualiza os contatos existentes com os novos dados ou adiciona novos contatos // for (const contact of newContacts) { // const contactsOld = await this.repos.contacts.findOneBy({ // DBAuth: { // id: this.auth.id, // }, // id: contact.id // }); // // Se o contato já existe, atualiza-o // if (contactsOld) { // this.repos.contacts.update(contactsOld.DBId, Object.assign(contactsOld, contact)) // } else { // // Se não existe, adiciona-o // this.repos.contacts.save(Object.assign({ DBAuth: { id: this.auth.id } } as DBContact, contact)); // } // } const entities = newContacts.map(c => ({ id: c.id, name: c.name, notify: c.notify, verifiedName: c.verifiedName, imgUrl: c.imgUrl, status: c.status, authId: this.auth.id, })); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { return yield this.repos.contacts.upsert(entities, ["id", "authId"] // chave composta que você definiu no @Unique ); })); }); this.assertMessageList = (jid) => __awaiter(this, void 0, void 0, function* () { // return this.ds.transaction(async (manager) => { let messageDic = yield this.repos.messageDics.findOne({ where: { jid, DBAuth: { id: this.auth.id } }, }); if (!messageDic) { messageDic = yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { return yield this.repos.messageDics.save({ jid, DBAuth: { id: this.auth.id } }); })); } return messageDic; // }); }); this.bind = (ev) => { ev.on("connection.update", (update) => Object.assign(this.state, update)); ev.on("messaging-history.set", (_a) => __awaiter(this, [_a], void 0, function* ({ chats: newChats, contacts: newContacts, messages: newMessages, isLatest, }) { var _b; // if(isLatest) { try { let messages = (0, lodash_1.cloneDeep)(newMessages); if (!isLatest) { messages = messages.filter(message => ((typeof message.messageTimestamp == 'number' ? message.messageTimestamp : message.messageTimestamp.low) * 1000) > (0, moment_1.default)().subtract(1, 'days').valueOf()); } yield this.contactsUpsert(newContacts); // console.log(messages.length, 'count'); for (let index = 0; index < messages.length; index++) { const msg = messages[index]; // } // for (const msg of newMessages) { const jid = msg.key.remoteJid; // Realiza a consulta diretamente no banco de dados para verificar se a mensagem já existe const existingMessage = yield this.repos.messages.findOne({ where: { msgId: msg.key.id, dictionary: { jid, DBAuth: { id: this.auth.id } }, }, }); if (!existingMessage) { // Se a mensagem não existir, salva-a no banco de dados yield this.repos.messages.save(Object.assign(Object.assign({}, msg), { msgId: (_b = msg.key) === null || _b === void 0 ? void 0 : _b.id, dictionary: yield this.assertMessageList(jid) })); continue; } // Se a mensagem já existir, atualiza-a Object.assign(existingMessage, msg); yield this.repos.messages.save(existingMessage); } } catch (error) { console.error(error); } // } })); ev.on("contacts.upsert", (contacts) => __awaiter(this, void 0, void 0, function* () { this.contactsUpsert(contacts); })); ev.on("contacts.update", (contacts) => __awaiter(this, void 0, void 0, function* () { this.contactsUpsert(contacts); })); ev.on("chats.upsert", (newChats) => __awaiter(this, void 0, void 0, function* () { try { // for (const chat of newChats) { // let chat_db = await this.repos.chats.findOne({ // where: { // id: chat.id, // DBAuth: { id: this.auth.id }, // }, // }); // if (!chat_db) { // this.repos.chats.save({ // ...chat, // DBAuth: { id: this.auth.id }, // }) // } // } const entities = newChats.map(c => ({ id: c.id, conversationTimestamp: c.conversationTimestamp, unreadCount: c.unreadCount, authId: this.auth.id, })); // insere ou atualiza em lote yield this.repos.chats.upsert(entities, ["id", "authId"]); } catch (_a) { } })); ev.on("chats.update", (updates) => __awaiter(this, void 0, void 0, function* () { for (let update of updates) { var chat = yield this.repos.chats.findOneBy({ id: update.id, DBAuth: { id: this.auth.id }, }); if (!chat) return; if (update.unreadCount > 0) { update = Object.assign({}, update); update.unreadCount = (chat.unreadCount || 0) + update.unreadCount; } Object.assign(chat, update); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.chats.save(chat); })); } })); ev.on("presence.update", (_a) => __awaiter(this, [_a], void 0, function* ({ id, presences: update }) { var chat = (yield this.repos.presenceDics.findOne({ where: { id, DBAuth: { id: this.auth.id }, }, relations: ["presences"], })) || { id, presences: [], DBAuth: { id: this.auth.id }, }; Object.entries(update).forEach(([id, presence]) => { var participant = chat.presences.find((x) => x.participant === id); participant ? Object.assign(participant, presence) : chat.presences.push(Object.assign(Object.assign({}, presence), { participant: id })); }); try { yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.presenceDics.save(chat); })); } catch (_b) { } })); ev.on("chats.delete", (deletions) => __awaiter(this, void 0, void 0, function* () { return !this.options.disableDelete.includes("chats") && Promise.all(deletions.map((id) => this.repos.chats.delete({ id, DBAuth: { id: this.auth.id }, }))); })); ev.on("messages.upsert", (_a) => __awaiter(this, [_a], void 0, function* ({ messages: newMessages, type }) { if (type !== "append" && type !== "notify") { return; } for (const msg of newMessages) { const jid = (0, baileys_1.jidNormalizedUser)(msg.key.remoteJid); // Verifica se a mensagem já existe no dicionário const existingMessage = yield this.repos.messages.findOne({ where: { msgId: msg.key.id, dictionary: { jid, DBAuth: { id: this.auth.id } }, }, }); if (!existingMessage) { // Se a mensagem não existir, salva-a no banco de dados yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { var _a; yield this.repos.messages.save(Object.assign(Object.assign({}, msg), { msgId: (_a = msg.key) === null || _a === void 0 ? void 0 : _a.id, dictionary: yield this.assertMessageList(jid) })); })); // Emite um evento de atualização do chat se for uma notificação if (type === "notify") { const chat = yield this.repos.chats.findOneBy({ id: jid, DBAuth: { id: this.auth.id }, }); if (!chat) { ev.emit("chats.upsert", [ { id: jid, conversationTimestamp: (0, baileys_1.toNumber)(msg.messageTimestamp), unreadCount: 1, }, ]); } } } else { // Se a mensagem já existir, atualiza-a Object.assign(existingMessage, msg); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.messages.save(existingMessage); })); } } })); ev.on("messages.update", (updates) => __awaiter(this, void 0, void 0, function* () { for (const { update, key } of updates) { const jid = key.remoteJid; // Verifica se a mensagem existe no dicionário const message = yield this.repos.messages.findOne({ where: { msgId: key.id, dictionary: { jid, DBAuth: { id: this.auth.id } }, }, }); if (message) { // Se a mensagem existir, atualiza-a Object.assign(message, update); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.messages.save(message); })); } } })); ev.on("messages.delete", (item) => __awaiter(this, void 0, void 0, function* () { if (this.options.disableDelete.includes("messages")) return; if ("all" in item) { const dictionary = yield this.repos.messageDics.findOne({ where: { jid: item.jid, DBAuth: { id: this.auth.id }, }, relations: ["messages"], }); if (!dictionary) return; this.repos.messages.remove(dictionary.messages); } else { const jid = item.keys[0].remoteJid; const dictionary = yield this.repos.messageDics.findOne({ where: { jid, DBAuth: { id: this.auth.id }, }, relations: ["messages"], }); if (!dictionary) return; const idSet = new Set(item.keys.map((k) => k.id)); yield this.repos.messages.remove(dictionary.messages.filter((msg) => Array.from(idSet).includes(msg.msgId))); } })); ev.on("groups.update", (updates) => __awaiter(this, void 0, void 0, function* () { for (const update of updates) { const id = update.id; let group = yield this.repos.groups.findOneBy({ id, DBAuth: { id: this.auth.id }, }); if (!group) return; Object.assign(group, update); yield this.repos.groups.save(group); } })); ev.on("group-participants.update", (_a) => __awaiter(this, [_a], void 0, function* ({ id, participants, action }) { const metadata = yield this.repos.groups.findOneBy({ id, DBAuth: { id: this.auth.id }, }); if (!metadata) return; switch (action) { case "add": metadata.participants.push(...participants.map((id) => ({ id, isAdmin: false, isSuperAdmin: false, }))); break; case "demote": case "promote": metadata.participants.forEach((participant) => participants.includes(participant.id) && (participant.isAdmin = action === "promote")); break; case "remove": metadata.participants = metadata.participants.filter((p) => !participants.includes(p.id)); break; } yield this.repos.groups.save(metadata); })); ev.on("message-receipt.update", (updates) => __awaiter(this, void 0, void 0, function* () { for (const { key, receipt } of updates) { const dictionary = yield this.repos.messageDics.findOne({ where: { jid: key.remoteJid, DBAuth: { id: this.auth.id }, }, relations: ["messages"], }); if (!dictionary) return; const msg = dictionary.messages.find((x) => x.key.id === key.id); if (!msg) continue; (0, baileys_1.updateMessageWithReceipt)(msg, receipt); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.messageDics.save(dictionary); })); } })); ev.on("messages.reaction", (reactions) => __awaiter(this, void 0, void 0, function* () { for (const { key, reaction } of reactions) { const dictionary = yield this.repos.messageDics.findOne({ where: { jid: key.remoteJid, DBAuth: { id: this.auth.id }, }, relations: ["messages"], }); if (!dictionary) return; const msg = dictionary.messages.find((x) => x.key.id === key.id); if (!msg) continue; (0, baileys_1.updateMessageWithReaction)(msg, reaction); yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { yield this.repos.messageDics.save(dictionary); })); } })); }; this.loadMessages = (jid, count, cursor) => __awaiter(this, void 0, void 0, function* () { const dictionary = yield this.repos.messageDics.findOne({ where: { jid, DBAuth: { id: this.auth.id } }, relations: ["messages"], }); if (!dictionary) { return []; } const mode = !cursor || "before" in cursor ? "before" : "after"; const cursorKey = cursor && "before" in cursor ? cursor.before : cursor === null || cursor === void 0 ? void 0 : cursor['after']; const cursorValue = cursorKey ? dictionary.messages.find((x) => x.msgId === cursorKey.id) : undefined; let messages = []; if (mode === "before" && (!cursorKey || cursorValue)) { if (cursorValue) { const msgIdx = dictionary.messages.findIndex((m) => m.key.id === (cursorKey === null || cursorKey === void 0 ? void 0 : cursorKey.id)); messages = dictionary.messages.slice(Math.max(0, msgIdx - count), msgIdx); } else { messages = dictionary.messages; } const diff = count - messages.length; if (diff > 0) { const remainingMessages = yield this.repos.messages.find({ where: { id: (0, typeorm_1.In)(dictionary.messages.map((msg) => msg.id)), msgId: (0, typeorm_1.LessThan)(messages[0].msgId), }, order: { msgId: "DESC", }, take: diff, }); messages = remainingMessages.concat(messages); } } return messages; }); // loadMessage = async ( // jid: string, // id: string // ): Promise<DBMessage | undefined> => // ( // // await this.repos.messageDics.findOne({ // // where: { // // jid, // // DBAuth: { id: this.auth.id }, // // }, // // relations: ["messages"], // // }) // await this.repos.messageDics.createQueryBuilder("dic") // .leftJoinAndSelect("dic.DBAuth", "auth") // .leftJoinAndSelect("dic.messages", "messages") // .where("dic.jid = :jid", { jid }) // .andWhere("auth.id = :id", { id: this.auth.id }) // .andWhere("messages.msgId = :id", { id }) // .getOne() // )?.messages.find((x) => x.msgId === id); this.loadMessage = (jid, id) => __awaiter(this, void 0, void 0, function* () { const message = yield this.repos.messages.findOne({ where: { msgId: id, dictionary: { jid, // DBAuth: this.auth, DBAuth: { id: this.auth.id } }, }, }); return message; }); this.mostRecentMessage = (jid) => __awaiter(this, void 0, void 0, function* () { const message = yield this.repos.messages.findOne({ where: { dictionary: { jid, DBAuth: { id: this.auth.id } }, }, order: { msgId: "DESC", }, }); return message; }); this.fetchImageUrl = (jid, sock) => __awaiter(this, void 0, void 0, function* () { const contact = yield this.repos.contacts.findOne({ where: { id: jid } }); if (!contact) return sock === null || sock === void 0 ? void 0 : sock.profilePictureUrl(jid); if (typeof contact.imgUrl === "undefined") yield this.repos.contacts.save(Object.assign(Object.assign({}, contact), { imgUrl: yield (sock === null || sock === void 0 ? void 0 : sock.profilePictureUrl(jid)) })); return contact.imgUrl; }); this.fetchGroupMetadata = (jid, sock) => __awaiter(this, void 0, void 0, function* () { var group = yield this.repos.groups.findOneBy({ id: jid, DBAuth: { id: this.auth.id }, }); if (!group) { const metadata = yield (sock === null || sock === void 0 ? void 0 : sock.groupMetadata(jid).catch((error) => console.log('fetchGroupMetadata groupMetadata error', error))); metadata && (group = yield this.retryOperation(() => __awaiter(this, void 0, void 0, function* () { return yield this.repos.groups.save(Object.assign(Object.assign({}, metadata), { DBAuth: { id: this.auth.id } })); }))); } return group; }); this.fetchMessageReceipts = (_a) => __awaiter(this, [_a], void 0, function* ({ remoteJid, id }) { const receipt = yield this.repos.messages.findOne({ // relations: { // dictionary: true, // }, where: { msgId: id, dictionary: { jid: remoteJid, DBAuth: { id: this.auth.id } }, }, select: ["userReceipt"], }); return receipt === null || receipt === void 0 ? void 0 : receipt.userReceipt; }); this.options = Object.assign({ disableDelete: [] }, (this.options || {})); } retryOperation(operation_1) { return __awaiter(this, arguments, void 0, function* (operation, maxRetries = 3, delay = 100) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return yield operation(); } catch (error) { if (error.code === 'SQLITE_BUSY' && attempt < maxRetries) { console.warn(`Database busy, retrying (${attempt}/${maxRetries})...`); yield this.sleep(delay * attempt); // Backoff exponencial continue; } throw error; } } }); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } } exports.default = StoreHandle; //# sourceMappingURL=StoreHandle.js.map