whatsapp-store-db 1.3.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/handlers/chat.d.ts +5 -0
- package/dist/handlers/chat.js +163 -0
- package/dist/handlers/contact.d.ts +5 -0
- package/dist/handlers/contact.js +118 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.js +12 -0
- package/dist/handlers/message.d.ts +5 -0
- package/dist/handlers/message.js +369 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -0
- package/dist/session.d.ts +20 -0
- package/dist/session.js +133 -0
- package/dist/shared.d.ts +6 -0
- package/dist/shared.js +27 -0
- package/dist/store.d.ts +22 -0
- package/dist/store.js +56 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +2 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +553 -0
- package/package.json +43 -0
- package/prisma/schema.prisma +134 -0
package/.env.example
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Royhan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
> 🚨 **NOTICE**: `baileys` which is this project relied on, has been discontinued. Thus, this project will be archived and stopped receiving updates anymore. Thanks everyone who's been part of this❤️
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Baileys Store
|
|
6
|
+
|
|
7
|
+
Minimal Baileys data storage for your favorite DBMS built with Prisma. This library is a simple handler for Baileys event emitter that will listen and update your data in the database
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- **Prisma** version **4.7.x** or higher
|
|
12
|
+
- **Baileys** version **5.x.x** or higher
|
|
13
|
+
|
|
14
|
+
## Supported Databases
|
|
15
|
+
|
|
16
|
+
- MySQL and PostgreSQL database should support the default schema out of the box
|
|
17
|
+
- For CockroachDB, you need to do this small change in the schema file
|
|
18
|
+
|
|
19
|
+
```diff prisma
|
|
20
|
+
model Session {
|
|
21
|
+
pkId BigInt @id @default(autoincrement())
|
|
22
|
+
sessionId String
|
|
23
|
+
id String
|
|
24
|
+
- data String @db.Text
|
|
25
|
+
+ data String
|
|
26
|
+
|
|
27
|
+
@@unique([sessionId, id], map: "unique_id_per_session_id_session")
|
|
28
|
+
@@index([sessionId])
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- For MongoDB, you need to follow [this convention](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference?query=getdmff&page=1#mongodb-10) and update the `pkId` field. Then follow the previous CockroachDB guide
|
|
33
|
+
- SQLite and SQL Server database are not supported since they didn't support Prisma's `JSON` scalar type
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Using npm
|
|
39
|
+
npm i @ookamiiixd/baileys-store
|
|
40
|
+
|
|
41
|
+
# Using yarn
|
|
42
|
+
yarn add @ookamiiixd/baileys-store
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Setup
|
|
46
|
+
|
|
47
|
+
Before you can actually use this library, you have to setup your database first
|
|
48
|
+
|
|
49
|
+
1. Copy the `.env.example` file from this repository or from the `node_modules` directory (should be located at `node_modules/@ookamiiixd/baileys-store/.env.example`). Rename it into `.env` and then update your [connection url](https://www.prisma.io/docs/reference/database-reference/connection-urls) in the `DATABASE_URL` field
|
|
50
|
+
1. Copy the `prisma` directory from this repository or from the `node_modules` directory (should be located at `node_modules/@ookamiiixd/baileys-store/prisma/`). Additionaly, you may want to update your `provider` in the `schema.prisma` file if you're not using MySQL database
|
|
51
|
+
1. Run your [migration](https://www.prisma.io/docs/reference/api-reference/command-reference#prisma-migrate)
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import pino from 'pino';
|
|
57
|
+
import makeWASocket from 'baileys';
|
|
58
|
+
import { PrismaClient } from '@prisma/client';
|
|
59
|
+
import { initStore, Store } from '@ookamiiixd/baileys-store';
|
|
60
|
+
|
|
61
|
+
const logger = pino();
|
|
62
|
+
const socket = makeWASocket();
|
|
63
|
+
|
|
64
|
+
// Configure Prisma client with increased transaction timeout
|
|
65
|
+
const prisma = new PrismaClient({
|
|
66
|
+
transactionOptions: {
|
|
67
|
+
timeout: 60000, // 60 seconds (increase from default 5 seconds)
|
|
68
|
+
maxWait: 30000, // 30 seconds max wait time
|
|
69
|
+
isolationLevel: 'ReadCommitted', // Optional: set isolation level
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// You only need to run this once
|
|
74
|
+
initStore({
|
|
75
|
+
prisma, // Prisma client instance
|
|
76
|
+
logger, // Pino logger (Optional)
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Create a store and start listening to the events
|
|
80
|
+
const store = new Store('unique-session-id-here', socket.ev);
|
|
81
|
+
|
|
82
|
+
// That's it, you can now query from the prisma client without having to worry about handling the events
|
|
83
|
+
const messages = prisma.message.findMany();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Transaction Timeout Issue
|
|
87
|
+
|
|
88
|
+
If you encounter the `P2028` error (transaction timeout), it's because the default transaction timeout is 5 seconds. When processing large amounts of data (like message history), transactions may take longer. You can:
|
|
89
|
+
|
|
90
|
+
1. **Increase the timeout** (shown above) - Set `timeout` to 60000ms (60 seconds) or higher
|
|
91
|
+
2. **Optimize database performance** - Ensure proper indexing and database optimization
|
|
92
|
+
3. **Batch operations** - Process data in smaller chunks if dealing with very large datasets
|
|
93
|
+
|
|
94
|
+
For production environments, consider:
|
|
95
|
+
- Setting `timeout` to at least 30-60 seconds
|
|
96
|
+
- Monitoring database performance
|
|
97
|
+
- Using connection pooling if needed
|
|
98
|
+
|
|
99
|
+
## Contributing
|
|
100
|
+
|
|
101
|
+
PRs, issues, suggestions, etc are welcome. Please kindly open a new issue to discuss it
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const baileys_1 = require("baileys");
|
|
4
|
+
const client_1 = require(".prisma/client");
|
|
5
|
+
const shared_1 = require("../shared");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
function chatHandler(sessionId, event, getJid = undefined) {
|
|
8
|
+
const prisma = (0, shared_1.usePrisma)();
|
|
9
|
+
const logger = (0, shared_1.useLogger)();
|
|
10
|
+
let listening = false;
|
|
11
|
+
const resolveChatId = (id, chatOrUpdate) => {
|
|
12
|
+
// console.log("chatHandler:chatOrUpdate:", chatOrUpdate);
|
|
13
|
+
// Prefer primary number JID when id is a LID
|
|
14
|
+
if (id === null || id === void 0 ? void 0 : id.endsWith('@lid')) {
|
|
15
|
+
const candidate = (chatOrUpdate === null || chatOrUpdate === void 0 ? void 0 : chatOrUpdate.pnJid) || (chatOrUpdate === null || chatOrUpdate === void 0 ? void 0 : chatOrUpdate.senderPn) || (chatOrUpdate === null || chatOrUpdate === void 0 ? void 0 : chatOrUpdate.jid);
|
|
16
|
+
if (candidate) {
|
|
17
|
+
return (0, baileys_1.jidNormalizedUser)(candidate);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const jidByLid = typeof getJid === 'function' ? getJid(id || '') : undefined;
|
|
21
|
+
return (0, baileys_1.jidNormalizedUser)(jidByLid !== null && jidByLid !== void 0 ? jidByLid : id);
|
|
22
|
+
};
|
|
23
|
+
const persistChatRecord = async ({ id, createData, updateData, }) => {
|
|
24
|
+
const where = { sessionId, id };
|
|
25
|
+
const createPayload = Object.assign(Object.assign({}, createData), { id, sessionId });
|
|
26
|
+
const updatePayload = Object.assign({}, updateData);
|
|
27
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
28
|
+
try {
|
|
29
|
+
const updateResult = await prisma.chat.updateMany({
|
|
30
|
+
data: updatePayload,
|
|
31
|
+
where,
|
|
32
|
+
});
|
|
33
|
+
if (updateResult.count > 0) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await prisma.chat.create({
|
|
37
|
+
select: { pkId: true },
|
|
38
|
+
data: createPayload,
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err instanceof client_1.Prisma.PrismaClientKnownRequestError && err.code === 'P2002') {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
logger.error({ id, sessionId }, 'Failed to persist chat record after repeated retries');
|
|
50
|
+
};
|
|
51
|
+
const set = async ({ chats, isLatest }) => {
|
|
52
|
+
try {
|
|
53
|
+
await prisma.$transaction(async (tx) => {
|
|
54
|
+
if (isLatest)
|
|
55
|
+
await tx.chat.deleteMany({ where: { sessionId } });
|
|
56
|
+
// Process chats in batches to avoid timeout
|
|
57
|
+
const BATCH_SIZE = 100;
|
|
58
|
+
const normalizedChats = chats.map((c) => {
|
|
59
|
+
const id = resolveChatId(c.id, c);
|
|
60
|
+
const transformedData = (0, utils_1.transformPrisma)(c);
|
|
61
|
+
const validatedData = (0, utils_1.validateChatData)(transformedData);
|
|
62
|
+
return Object.assign(Object.assign({}, validatedData), { id });
|
|
63
|
+
});
|
|
64
|
+
const existingIds = (await tx.chat.findMany({
|
|
65
|
+
select: { id: true },
|
|
66
|
+
where: { id: { in: normalizedChats.map((c) => c.id) }, sessionId },
|
|
67
|
+
})).map((i) => i.id);
|
|
68
|
+
const newChats = normalizedChats.filter((c) => !existingIds.includes(c.id));
|
|
69
|
+
let totalAdded = 0;
|
|
70
|
+
for (let i = 0; i < newChats.length; i += BATCH_SIZE) {
|
|
71
|
+
const batch = newChats.slice(i, i + BATCH_SIZE);
|
|
72
|
+
const result = await tx.chat.createMany({
|
|
73
|
+
data: batch.map((c) => (Object.assign(Object.assign({}, c), { sessionId }))),
|
|
74
|
+
});
|
|
75
|
+
totalAdded += result.count;
|
|
76
|
+
}
|
|
77
|
+
logger.info({ chatsAdded: totalAdded }, 'Synced chats');
|
|
78
|
+
}, {
|
|
79
|
+
timeout: 30000, // 30 seconds for this specific transaction
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
logger.error(e, 'An error occured during chats set');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const upsert = async (chats) => {
|
|
87
|
+
try {
|
|
88
|
+
// Normalize and de-duplicate by resolved id (keep the last occurrence)
|
|
89
|
+
const dedupedById = new Map();
|
|
90
|
+
for (const c of chats) {
|
|
91
|
+
const id = resolveChatId(c.id, c);
|
|
92
|
+
const transformedData = (0, utils_1.transformPrisma)(c);
|
|
93
|
+
const validatedData = (0, utils_1.validateChatData)(transformedData);
|
|
94
|
+
dedupedById.set(id, Object.assign(Object.assign({}, validatedData), { id }));
|
|
95
|
+
}
|
|
96
|
+
const normalizedChats = Array.from(dedupedById.values());
|
|
97
|
+
await Promise.all(normalizedChats.map((data) => persistChatRecord({
|
|
98
|
+
id: data.id,
|
|
99
|
+
createData: Object.assign({}, data),
|
|
100
|
+
updateData: Object.assign(Object.assign({}, data), { id: undefined }),
|
|
101
|
+
})));
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
logger.error(e, 'An error occured during chats upsert');
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const update = async (updates) => {
|
|
108
|
+
for (const update of updates) {
|
|
109
|
+
if (!update.id) {
|
|
110
|
+
logger.warn({ update }, 'Skipping chat update with no ID');
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const chatId = resolveChatId(update.id, update);
|
|
115
|
+
const transformedData = (0, utils_1.transformPrisma)(update);
|
|
116
|
+
const validatedData = (0, utils_1.validateChatData)(transformedData);
|
|
117
|
+
await persistChatRecord({
|
|
118
|
+
id: chatId,
|
|
119
|
+
createData: Object.assign(Object.assign({}, validatedData), { id: chatId }),
|
|
120
|
+
updateData: Object.assign(Object.assign({}, validatedData), { id: undefined, unreadCount: typeof validatedData.unreadCount === 'number'
|
|
121
|
+
? validatedData.unreadCount > 0
|
|
122
|
+
? { increment: validatedData.unreadCount }
|
|
123
|
+
: { set: validatedData.unreadCount }
|
|
124
|
+
: undefined }),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
logger.error(e, 'An error occured during chat update');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const del = async (ids) => {
|
|
133
|
+
try {
|
|
134
|
+
const normalizedIds = ids.map((id) => resolveChatId(id));
|
|
135
|
+
await prisma.chat.deleteMany({
|
|
136
|
+
where: { id: { in: normalizedIds } },
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
logger.error(e, 'An error occured during chats delete');
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const listen = () => {
|
|
144
|
+
if (listening)
|
|
145
|
+
return;
|
|
146
|
+
event.on('messaging-history.set', set);
|
|
147
|
+
event.on('chats.upsert', upsert);
|
|
148
|
+
event.on('chats.update', update);
|
|
149
|
+
event.on('chats.delete', del);
|
|
150
|
+
listening = true;
|
|
151
|
+
};
|
|
152
|
+
const unlisten = () => {
|
|
153
|
+
if (!listening)
|
|
154
|
+
return;
|
|
155
|
+
event.off('messaging-history.set', set);
|
|
156
|
+
event.off('chats.upsert', upsert);
|
|
157
|
+
event.off('chats.update', update);
|
|
158
|
+
event.off('chats.delete', del);
|
|
159
|
+
listening = false;
|
|
160
|
+
};
|
|
161
|
+
return { listen, unlisten };
|
|
162
|
+
}
|
|
163
|
+
exports.default = chatHandler;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const baileys_1 = require("baileys");
|
|
4
|
+
const shared_1 = require("../shared");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
function contactHandler(sessionId, event, getJid = undefined) {
|
|
7
|
+
const prisma = (0, shared_1.usePrisma)();
|
|
8
|
+
const logger = (0, shared_1.useLogger)();
|
|
9
|
+
let listening = false;
|
|
10
|
+
const resolveContactId = (id, contact) => {
|
|
11
|
+
// console.log("contactHandler:contact:", contact);
|
|
12
|
+
// Prefer primary number when we get a LID id and contact carries pn/jid
|
|
13
|
+
if (id === null || id === void 0 ? void 0 : id.endsWith('@lid')) {
|
|
14
|
+
const candidate = ((contact === null || contact === void 0 ? void 0 : contact.senderPn) || (contact === null || contact === void 0 ? void 0 : contact.pnJid) || (contact === null || contact === void 0 ? void 0 : contact.jid));
|
|
15
|
+
if (candidate) {
|
|
16
|
+
return (0, baileys_1.jidNormalizedUser)(candidate);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const jidByLid = typeof getJid === 'function' ? getJid(id || '') : undefined;
|
|
20
|
+
return (0, baileys_1.jidNormalizedUser)(jidByLid !== null && jidByLid !== void 0 ? jidByLid : id);
|
|
21
|
+
};
|
|
22
|
+
const sanitizeContactData = (raw) => {
|
|
23
|
+
// Only keep fields that exist in the Contact model
|
|
24
|
+
const allowed = ['id', 'name', 'notify', 'verifiedName', 'imgUrl', 'status'];
|
|
25
|
+
const out = {};
|
|
26
|
+
for (const k of allowed) {
|
|
27
|
+
if (raw[k] !== undefined)
|
|
28
|
+
out[k] = raw[k];
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
};
|
|
32
|
+
const set = async ({ contacts }) => {
|
|
33
|
+
try {
|
|
34
|
+
const normalizedContacts = contacts.map((c) => {
|
|
35
|
+
const id = resolveContactId(c.id, c);
|
|
36
|
+
const data = sanitizeContactData((0, utils_1.transformPrisma)(c));
|
|
37
|
+
return Object.assign(Object.assign({}, data), { id });
|
|
38
|
+
});
|
|
39
|
+
const contactIds = normalizedContacts.map((c) => c.id);
|
|
40
|
+
const deletedOldContactIds = (await prisma.contact.findMany({
|
|
41
|
+
select: { id: true },
|
|
42
|
+
where: { id: { notIn: contactIds }, sessionId },
|
|
43
|
+
})).map((c) => c.id);
|
|
44
|
+
const upsertPromises = normalizedContacts
|
|
45
|
+
.map((data) => prisma.contact.upsert({
|
|
46
|
+
select: { pkId: true },
|
|
47
|
+
create: Object.assign(Object.assign({}, data), { sessionId }),
|
|
48
|
+
update: data,
|
|
49
|
+
where: { sessionId_id: { id: data.id, sessionId } },
|
|
50
|
+
}));
|
|
51
|
+
await Promise.any([
|
|
52
|
+
...upsertPromises,
|
|
53
|
+
prisma.contact.deleteMany({ where: { id: { in: deletedOldContactIds }, sessionId } }),
|
|
54
|
+
]);
|
|
55
|
+
logger.info({ deletedContacts: deletedOldContactIds.length, newContacts: contacts.length }, 'Synced contacts');
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
logger.error(e, 'An error occured during contacts set');
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const upsert = async (contacts) => {
|
|
62
|
+
try {
|
|
63
|
+
const normalizedContacts = contacts.map((c) => {
|
|
64
|
+
const id = resolveContactId(c.id, c);
|
|
65
|
+
const data = sanitizeContactData((0, utils_1.transformPrisma)(c));
|
|
66
|
+
return Object.assign(Object.assign({}, data), { id });
|
|
67
|
+
});
|
|
68
|
+
await Promise.any(normalizedContacts.map((data) => prisma.contact.upsert({
|
|
69
|
+
select: { pkId: true },
|
|
70
|
+
create: Object.assign(Object.assign({}, data), { sessionId }),
|
|
71
|
+
update: data,
|
|
72
|
+
where: { sessionId_id: { id: data.id, sessionId } },
|
|
73
|
+
})));
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
logger.error(e, 'An error occured during contacts upsert');
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const update = async (updates) => {
|
|
80
|
+
for (const update of updates) {
|
|
81
|
+
if (!update.id) {
|
|
82
|
+
logger.warn({ update }, 'Skipping contact update with no ID');
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const contactId = resolveContactId(update.id, update);
|
|
87
|
+
const transformedData = sanitizeContactData((0, utils_1.transformPrisma)(update));
|
|
88
|
+
await prisma.contact.upsert({
|
|
89
|
+
select: { pkId: true },
|
|
90
|
+
create: Object.assign(Object.assign({}, transformedData), { id: contactId, sessionId }),
|
|
91
|
+
update: transformedData,
|
|
92
|
+
where: { sessionId_id: { id: contactId, sessionId } },
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
logger.error(e, 'An error occured during contact update');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const listen = () => {
|
|
101
|
+
if (listening)
|
|
102
|
+
return;
|
|
103
|
+
event.on('messaging-history.set', set);
|
|
104
|
+
event.on('contacts.upsert', upsert);
|
|
105
|
+
event.on('contacts.update', update);
|
|
106
|
+
listening = true;
|
|
107
|
+
};
|
|
108
|
+
const unlisten = () => {
|
|
109
|
+
if (!listening)
|
|
110
|
+
return;
|
|
111
|
+
event.off('messaging-history.set', set);
|
|
112
|
+
event.off('contacts.upsert', upsert);
|
|
113
|
+
event.off('contacts.update', update);
|
|
114
|
+
listening = false;
|
|
115
|
+
};
|
|
116
|
+
return { listen, unlisten };
|
|
117
|
+
}
|
|
118
|
+
exports.default = contactHandler;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.contactHandler = exports.messageHandler = exports.chatHandler = void 0;
|
|
7
|
+
var chat_1 = require("./chat");
|
|
8
|
+
Object.defineProperty(exports, "chatHandler", { enumerable: true, get: function () { return __importDefault(chat_1).default; } });
|
|
9
|
+
var message_1 = require("./message");
|
|
10
|
+
Object.defineProperty(exports, "messageHandler", { enumerable: true, get: function () { return __importDefault(message_1).default; } });
|
|
11
|
+
var contact_1 = require("./contact");
|
|
12
|
+
Object.defineProperty(exports, "contactHandler", { enumerable: true, get: function () { return __importDefault(contact_1).default; } });
|