@rexxhayanasi/elaina-baileys 1.2.1-rc.4 → 1.2.1-rc.6
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/lib/Signal/Group/keyhelper.js +10 -43
- package/lib/Socket/communities.js +441 -0
- package/lib/Socket/index.js +43 -10
- package/lib/Socket/messages-recv.js +14 -3
- package/lib/Socket/socket.js +76 -126
- package/lib/Utils/messages.js +22 -13
- package/package.json +1 -1
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Signal Group Key Helper
|
|
4
|
-
* Helper functions to generate sender keys and signing keys safely.
|
|
5
|
-
*/
|
|
6
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
3
|
if (k2 === undefined) k2 = k;
|
|
8
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
9
|
}) : (function(o, m, k, k2) {
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
-
|
|
14
13
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
14
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
15
|
}) : function(o, v) {
|
|
17
16
|
o["default"] = v;
|
|
18
17
|
});
|
|
19
|
-
|
|
20
18
|
var __importStar = (this && this.__importStar) || (function () {
|
|
21
19
|
var ownKeys = function(o) {
|
|
22
20
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
@@ -34,55 +32,24 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
32
|
return result;
|
|
35
33
|
};
|
|
36
34
|
})();
|
|
37
|
-
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.generateSenderKey = generateSenderKey;
|
|
40
37
|
exports.generateSenderKeyId = generateSenderKeyId;
|
|
41
38
|
exports.generateSenderSigningKey = generateSenderSigningKey;
|
|
42
|
-
|
|
43
39
|
const nodeCrypto = __importStar(require("crypto"));
|
|
44
|
-
const curve_1 = require("libsignal/src/curve");
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Generates a random 32-byte Sender Key.
|
|
48
|
-
* @returns {Buffer} The generated key.
|
|
49
|
-
*/
|
|
40
|
+
const curve_1 = require("libsignal/src/curve");
|
|
50
41
|
function generateSenderKey() {
|
|
51
|
-
|
|
52
|
-
if (key.length !== 32) {
|
|
53
|
-
throw new Error("Failed to generate a valid 32-byte Sender Key");
|
|
54
|
-
}
|
|
55
|
-
return key;
|
|
42
|
+
return nodeCrypto.randomBytes(32);
|
|
56
43
|
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Generates a random Sender Key ID.
|
|
60
|
-
* @returns {number} The generated Key ID.
|
|
61
|
-
*/
|
|
62
44
|
function generateSenderKeyId() {
|
|
63
|
-
|
|
64
|
-
if (!id || typeof id !== 'number') {
|
|
65
|
-
throw new Error("Failed to generate Sender Key ID");
|
|
66
|
-
}
|
|
67
|
-
return id;
|
|
45
|
+
return nodeCrypto.randomInt(2147483647);
|
|
68
46
|
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Generates a Sender Signing Key Pair.
|
|
72
|
-
* Uses libsignal's curve implementation.
|
|
73
|
-
* @param {Object} [key] Optional existing key pair.
|
|
74
|
-
* @returns {Object} The key pair (public/private).
|
|
75
|
-
*/
|
|
76
47
|
function generateSenderSigningKey(key) {
|
|
77
48
|
if (!key) {
|
|
78
49
|
key = (0, curve_1.generateKeyPair)();
|
|
79
50
|
}
|
|
80
|
-
|
|
81
|
-
if (!key || !key.pubKey || !key.privKey) {
|
|
82
|
-
throw new Error("Invalid KeyPair generated from Curve");
|
|
83
|
-
}
|
|
84
51
|
return {
|
|
85
|
-
public: key.pubKey,
|
|
86
|
-
private: key.privKey
|
|
52
|
+
public: Buffer.from(key.pubKey),
|
|
53
|
+
private: Buffer.from(key.privKey)
|
|
87
54
|
};
|
|
88
55
|
}
|
|
@@ -0,0 +1,441 @@
|
|
|
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.extractCommunityMetadata = exports.makeCommunitiesSocket = void 0;
|
|
7
|
+
const WAProto_1 = require("../../WAProto/index.js");
|
|
8
|
+
const Types_1 = require("../Types");
|
|
9
|
+
const Utils_1 = require("../Utils");
|
|
10
|
+
const logger_1 = __importDefault(require("../Utils/logger"));
|
|
11
|
+
const WABinary_1 = require("../WABinary");
|
|
12
|
+
const business_1 = require("./business");
|
|
13
|
+
|
|
14
|
+
const makeCommunitiesSocket = (config) => {
|
|
15
|
+
const sock = (0, business_1.makeBusinessSocket)(config);
|
|
16
|
+
const { authState, ev, query, upsertMessage } = sock;
|
|
17
|
+
const communityQuery = async (jid, type, content) => query({
|
|
18
|
+
tag: 'iq',
|
|
19
|
+
attrs: {
|
|
20
|
+
type,
|
|
21
|
+
xmlns: 'w:g2',
|
|
22
|
+
to: jid
|
|
23
|
+
},
|
|
24
|
+
content
|
|
25
|
+
});
|
|
26
|
+
const communityMetadata = async (jid) => {
|
|
27
|
+
const result = await communityQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }]);
|
|
28
|
+
return (0, exports.extractCommunityMetadata)(result);
|
|
29
|
+
};
|
|
30
|
+
const communityFetchAllParticipating = async () => {
|
|
31
|
+
const result = await query({
|
|
32
|
+
tag: 'iq',
|
|
33
|
+
attrs: {
|
|
34
|
+
to: '@g.us',
|
|
35
|
+
xmlns: 'w:g2',
|
|
36
|
+
type: 'get'
|
|
37
|
+
},
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
tag: 'participating',
|
|
41
|
+
attrs: {},
|
|
42
|
+
content: [
|
|
43
|
+
{ tag: 'participants', attrs: {} },
|
|
44
|
+
{ tag: 'description', attrs: {} }
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
const data = {};
|
|
50
|
+
const communitiesChild = (0, WABinary_1.getBinaryNodeChild)(result, 'communities');
|
|
51
|
+
if (communitiesChild) {
|
|
52
|
+
const communities = (0, WABinary_1.getBinaryNodeChildren)(communitiesChild, 'community');
|
|
53
|
+
for (const communityNode of communities) {
|
|
54
|
+
const meta = (0, exports.extractCommunityMetadata)({
|
|
55
|
+
tag: 'result',
|
|
56
|
+
attrs: {},
|
|
57
|
+
content: [communityNode]
|
|
58
|
+
});
|
|
59
|
+
data[meta.id] = meta;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
sock.ev.emit('groups.update', Object.values(data));
|
|
63
|
+
return data;
|
|
64
|
+
};
|
|
65
|
+
async function parseGroupResult(node) {
|
|
66
|
+
logger_1.default.info({ node }, 'parseGroupResult');
|
|
67
|
+
const groupNode = (0, WABinary_1.getBinaryNodeChild)(node, 'group');
|
|
68
|
+
if (groupNode) {
|
|
69
|
+
try {
|
|
70
|
+
logger_1.default.info({ groupNode }, 'groupNode');
|
|
71
|
+
const metadata = await sock.groupMetadata(`${groupNode.attrs.id}@g.us`);
|
|
72
|
+
return metadata ? metadata : Optional.empty();
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('Error parsing group metadata:', error);
|
|
76
|
+
return Optional.empty();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return Optional.empty();
|
|
80
|
+
}
|
|
81
|
+
const Optional = {
|
|
82
|
+
empty: () => null,
|
|
83
|
+
of: (value) => (value !== null ? { value } : null)
|
|
84
|
+
};
|
|
85
|
+
sock.ws.on('CB:ib,,dirty', async (node) => {
|
|
86
|
+
const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty');
|
|
87
|
+
if (attrs.type !== 'communities') {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await communityFetchAllParticipating();
|
|
91
|
+
await sock.cleanDirtyBits('groups');
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
...sock,
|
|
95
|
+
communityMetadata,
|
|
96
|
+
communityCreate: async (subject, body) => {
|
|
97
|
+
const descriptionId = (0, Utils_1.generateMessageID)().substring(0, 12);
|
|
98
|
+
const result = await communityQuery('@g.us', 'set', [
|
|
99
|
+
{
|
|
100
|
+
tag: 'create',
|
|
101
|
+
attrs: { subject },
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
tag: 'description',
|
|
105
|
+
attrs: { id: descriptionId },
|
|
106
|
+
content: [
|
|
107
|
+
{
|
|
108
|
+
tag: 'body',
|
|
109
|
+
attrs: {},
|
|
110
|
+
content: Buffer.from(body || '', 'utf-8')
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
tag: 'parent',
|
|
116
|
+
attrs: { default_membership_approval_mode: 'request_required' }
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
tag: 'allow_non_admin_sub_group_creation',
|
|
120
|
+
attrs: {}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
tag: 'create_general_chat',
|
|
124
|
+
attrs: {}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
]);
|
|
129
|
+
return await parseGroupResult(result);
|
|
130
|
+
},
|
|
131
|
+
communityCreateGroup: async (subject, participants, parentCommunityJid) => {
|
|
132
|
+
const key = (0, Utils_1.generateMessageIDV2)();
|
|
133
|
+
const result = await communityQuery('@g.us', 'set', [
|
|
134
|
+
{
|
|
135
|
+
tag: 'create',
|
|
136
|
+
attrs: {
|
|
137
|
+
subject,
|
|
138
|
+
key
|
|
139
|
+
},
|
|
140
|
+
content: [
|
|
141
|
+
...participants.map(jid => ({
|
|
142
|
+
tag: 'participant',
|
|
143
|
+
attrs: { jid }
|
|
144
|
+
})),
|
|
145
|
+
{ tag: 'linked_parent', attrs: { jid: parentCommunityJid } }
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
]);
|
|
149
|
+
return await parseGroupResult(result);
|
|
150
|
+
},
|
|
151
|
+
communityLeave: async (id) => {
|
|
152
|
+
await communityQuery('@g.us', 'set', [
|
|
153
|
+
{
|
|
154
|
+
tag: 'leave',
|
|
155
|
+
attrs: {},
|
|
156
|
+
content: [{ tag: 'community', attrs: { id } }]
|
|
157
|
+
}
|
|
158
|
+
]);
|
|
159
|
+
},
|
|
160
|
+
communityUpdateSubject: async (jid, subject) => {
|
|
161
|
+
await communityQuery(jid, 'set', [
|
|
162
|
+
{
|
|
163
|
+
tag: 'subject',
|
|
164
|
+
attrs: {},
|
|
165
|
+
content: Buffer.from(subject, 'utf-8')
|
|
166
|
+
}
|
|
167
|
+
]);
|
|
168
|
+
},
|
|
169
|
+
communityLinkGroup: async (groupJid, parentCommunityJid) => {
|
|
170
|
+
await communityQuery(parentCommunityJid, 'set', [
|
|
171
|
+
{
|
|
172
|
+
tag: 'links',
|
|
173
|
+
attrs: {},
|
|
174
|
+
content: [
|
|
175
|
+
{
|
|
176
|
+
tag: 'link',
|
|
177
|
+
attrs: { link_type: 'sub_group' },
|
|
178
|
+
content: [{ tag: 'group', attrs: { jid: groupJid } }]
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
]);
|
|
183
|
+
},
|
|
184
|
+
communityUnlinkGroup: async (groupJid, parentCommunityJid) => {
|
|
185
|
+
await communityQuery(parentCommunityJid, 'set', [
|
|
186
|
+
{
|
|
187
|
+
tag: 'unlink',
|
|
188
|
+
attrs: { unlink_type: 'sub_group' },
|
|
189
|
+
content: [{ tag: 'group', attrs: { jid: groupJid } }]
|
|
190
|
+
}
|
|
191
|
+
]);
|
|
192
|
+
},
|
|
193
|
+
communityFetchLinkedGroups: async (jid) => {
|
|
194
|
+
let communityJid = jid;
|
|
195
|
+
let isCommunity = false;
|
|
196
|
+
// Try to determine if it is a subgroup or a community
|
|
197
|
+
const metadata = await sock.groupMetadata(jid);
|
|
198
|
+
if (metadata.linkedParent) {
|
|
199
|
+
// It is a subgroup, get the community jid
|
|
200
|
+
communityJid = metadata.linkedParent;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// It is a community
|
|
204
|
+
isCommunity = true;
|
|
205
|
+
}
|
|
206
|
+
// Fetch all subgroups of the community
|
|
207
|
+
const result = await communityQuery(communityJid, 'get', [{ tag: 'sub_groups', attrs: {} }]);
|
|
208
|
+
const linkedGroupsData = [];
|
|
209
|
+
const subGroupsNode = (0, WABinary_1.getBinaryNodeChild)(result, 'sub_groups');
|
|
210
|
+
if (subGroupsNode) {
|
|
211
|
+
const groupNodes = (0, WABinary_1.getBinaryNodeChildren)(subGroupsNode, 'group');
|
|
212
|
+
for (const groupNode of groupNodes) {
|
|
213
|
+
linkedGroupsData.push({
|
|
214
|
+
id: groupNode.attrs.id ? (0, WABinary_1.jidEncode)(groupNode.attrs.id, 'g.us') : undefined,
|
|
215
|
+
subject: groupNode.attrs.subject || '',
|
|
216
|
+
creation: groupNode.attrs.creation ? Number(groupNode.attrs.creation) : undefined,
|
|
217
|
+
owner: groupNode.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(groupNode.attrs.creator) : undefined,
|
|
218
|
+
size: groupNode.attrs.size ? Number(groupNode.attrs.size) : undefined
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
communityJid,
|
|
224
|
+
isCommunity,
|
|
225
|
+
linkedGroups: linkedGroupsData
|
|
226
|
+
};
|
|
227
|
+
},
|
|
228
|
+
communityRequestParticipantsList: async (jid) => {
|
|
229
|
+
const result = await communityQuery(jid, 'get', [
|
|
230
|
+
{
|
|
231
|
+
tag: 'membership_approval_requests',
|
|
232
|
+
attrs: {}
|
|
233
|
+
}
|
|
234
|
+
]);
|
|
235
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_approval_requests');
|
|
236
|
+
const participants = (0, WABinary_1.getBinaryNodeChildren)(node, 'membership_approval_request');
|
|
237
|
+
return participants.map(v => v.attrs);
|
|
238
|
+
},
|
|
239
|
+
communityRequestParticipantsUpdate: async (jid, participants, action) => {
|
|
240
|
+
const result = await communityQuery(jid, 'set', [
|
|
241
|
+
{
|
|
242
|
+
tag: 'membership_requests_action',
|
|
243
|
+
attrs: {},
|
|
244
|
+
content: [
|
|
245
|
+
{
|
|
246
|
+
tag: action,
|
|
247
|
+
attrs: {},
|
|
248
|
+
content: participants.map(jid => ({
|
|
249
|
+
tag: 'participant',
|
|
250
|
+
attrs: { jid }
|
|
251
|
+
}))
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
]);
|
|
256
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_requests_action');
|
|
257
|
+
const nodeAction = (0, WABinary_1.getBinaryNodeChild)(node, action);
|
|
258
|
+
const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(nodeAction, 'participant');
|
|
259
|
+
return participantsAffected.map(p => {
|
|
260
|
+
return { status: p.attrs.error || '200', jid: p.attrs.jid };
|
|
261
|
+
});
|
|
262
|
+
},
|
|
263
|
+
communityParticipantsUpdate: async (jid, participants, action) => {
|
|
264
|
+
const result = await communityQuery(jid, 'set', [
|
|
265
|
+
{
|
|
266
|
+
tag: action,
|
|
267
|
+
attrs: action === 'remove' ? { linked_groups: 'true' } : {},
|
|
268
|
+
content: participants.map(jid => ({
|
|
269
|
+
tag: 'participant',
|
|
270
|
+
attrs: { jid }
|
|
271
|
+
}))
|
|
272
|
+
}
|
|
273
|
+
]);
|
|
274
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, action);
|
|
275
|
+
const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(node, 'participant');
|
|
276
|
+
return participantsAffected.map(p => {
|
|
277
|
+
return { status: p.attrs.error || '200', jid: p.attrs.jid, content: p };
|
|
278
|
+
});
|
|
279
|
+
},
|
|
280
|
+
communityUpdateDescription: async (jid, description) => {
|
|
281
|
+
const metadata = await communityMetadata(jid);
|
|
282
|
+
const prev = metadata.descId ?? null;
|
|
283
|
+
await communityQuery(jid, 'set', [
|
|
284
|
+
{
|
|
285
|
+
tag: 'description',
|
|
286
|
+
attrs: {
|
|
287
|
+
...(description ? { id: (0, Utils_1.generateMessageID)() } : { delete: 'true' }),
|
|
288
|
+
...(prev ? { prev } : {})
|
|
289
|
+
},
|
|
290
|
+
content: description ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }] : undefined
|
|
291
|
+
}
|
|
292
|
+
]);
|
|
293
|
+
},
|
|
294
|
+
communityInviteCode: async (jid) => {
|
|
295
|
+
const result = await communityQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]);
|
|
296
|
+
const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite');
|
|
297
|
+
return inviteNode === null || inviteNode === void 0 ? void 0 : inviteNode.attrs.code;
|
|
298
|
+
},
|
|
299
|
+
communityRevokeInvite: async (jid) => {
|
|
300
|
+
const result = await communityQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]);
|
|
301
|
+
const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite');
|
|
302
|
+
return inviteNode === null || inviteNode === void 0 ? void 0 : inviteNode.attrs.code;
|
|
303
|
+
},
|
|
304
|
+
communityAcceptInvite: async (code) => {
|
|
305
|
+
const results = await communityQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]);
|
|
306
|
+
const result = (0, WABinary_1.getBinaryNodeChild)(results, 'community');
|
|
307
|
+
return result === null || result === void 0 ? void 0 : result.attrs.jid;
|
|
308
|
+
},
|
|
309
|
+
/**
|
|
310
|
+
* revoke a v4 invite for someone
|
|
311
|
+
* @param communityJid community jid
|
|
312
|
+
* @param invitedJid jid of person you invited
|
|
313
|
+
* @returns true if successful
|
|
314
|
+
*/
|
|
315
|
+
communityRevokeInviteV4: async (communityJid, invitedJid) => {
|
|
316
|
+
const result = await communityQuery(communityJid, 'set', [
|
|
317
|
+
{ tag: 'revoke', attrs: {}, content: [{ tag: 'participant', attrs: { jid: invitedJid } }] }
|
|
318
|
+
]);
|
|
319
|
+
return !!result;
|
|
320
|
+
},
|
|
321
|
+
/**
|
|
322
|
+
* accept a CommunityInviteMessage
|
|
323
|
+
* @param key the key of the invite message, or optionally only provide the jid of the person who sent the invite
|
|
324
|
+
* @param inviteMessage the message to accept
|
|
325
|
+
*/
|
|
326
|
+
communityAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => {
|
|
327
|
+
var _a;
|
|
328
|
+
key = typeof key === 'string' ? { remoteJid: key } : key;
|
|
329
|
+
const results = await communityQuery(inviteMessage.groupJid, 'set', [
|
|
330
|
+
{
|
|
331
|
+
tag: 'accept',
|
|
332
|
+
attrs: {
|
|
333
|
+
code: inviteMessage.inviteCode,
|
|
334
|
+
expiration: inviteMessage.inviteExpiration.toString(),
|
|
335
|
+
admin: key.remoteJid
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
]);
|
|
339
|
+
// if we have the full message key
|
|
340
|
+
// update the invite message to be expired
|
|
341
|
+
if (key.id) {
|
|
342
|
+
// create new invite message that is expired
|
|
343
|
+
inviteMessage = WAProto_1.proto.Message.GroupInviteMessage.fromObject(inviteMessage);
|
|
344
|
+
inviteMessage.inviteExpiration = 0;
|
|
345
|
+
inviteMessage.inviteCode = '';
|
|
346
|
+
ev.emit('messages.update', [
|
|
347
|
+
{
|
|
348
|
+
key,
|
|
349
|
+
update: {
|
|
350
|
+
message: {
|
|
351
|
+
groupInviteMessage: inviteMessage
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
]);
|
|
356
|
+
}
|
|
357
|
+
// generate the community add message
|
|
358
|
+
await upsertMessage({
|
|
359
|
+
key: {
|
|
360
|
+
remoteJid: inviteMessage.groupJid,
|
|
361
|
+
id: (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id),
|
|
362
|
+
fromMe: false,
|
|
363
|
+
participant: key.remoteJid // TODO: investigate if this makes any sense at all
|
|
364
|
+
},
|
|
365
|
+
messageStubType: Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD,
|
|
366
|
+
messageStubParameters: [JSON.stringify(authState.creds.me)],
|
|
367
|
+
participant: key.remoteJid,
|
|
368
|
+
messageTimestamp: (0, Utils_1.unixTimestampSeconds)()
|
|
369
|
+
}, 'notify');
|
|
370
|
+
return results.attrs.from;
|
|
371
|
+
}),
|
|
372
|
+
communityGetInviteInfo: async (code) => {
|
|
373
|
+
const results = await communityQuery('@g.us', 'get', [{ tag: 'invite', attrs: { code } }]);
|
|
374
|
+
return (0, exports.extractCommunityMetadata)(results);
|
|
375
|
+
},
|
|
376
|
+
communityToggleEphemeral: async (jid, ephemeralExpiration) => {
|
|
377
|
+
const content = ephemeralExpiration
|
|
378
|
+
? { tag: 'ephemeral', attrs: { expiration: ephemeralExpiration.toString() } }
|
|
379
|
+
: { tag: 'not_ephemeral', attrs: {} };
|
|
380
|
+
await communityQuery(jid, 'set', [content]);
|
|
381
|
+
},
|
|
382
|
+
communitySettingUpdate: async (jid, setting) => {
|
|
383
|
+
await communityQuery(jid, 'set', [{ tag: setting, attrs: {} }]);
|
|
384
|
+
},
|
|
385
|
+
communityMemberAddMode: async (jid, mode) => {
|
|
386
|
+
await communityQuery(jid, 'set', [{ tag: 'member_add_mode', attrs: {}, content: mode }]);
|
|
387
|
+
},
|
|
388
|
+
communityJoinApprovalMode: async (jid, mode) => {
|
|
389
|
+
await communityQuery(jid, 'set', [
|
|
390
|
+
{ tag: 'membership_approval_mode', attrs: {}, content: [{ tag: 'community_join', attrs: { state: mode } }] }
|
|
391
|
+
]);
|
|
392
|
+
},
|
|
393
|
+
communityFetchAllParticipating
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
exports.makeCommunitiesSocket = makeCommunitiesSocket;
|
|
397
|
+
|
|
398
|
+
const extractCommunityMetadata = (result) => {
|
|
399
|
+
var _a, _b;
|
|
400
|
+
const community = (0, WABinary_1.getBinaryNodeChild)(result, 'community');
|
|
401
|
+
const descChild = (0, WABinary_1.getBinaryNodeChild)(community, 'description');
|
|
402
|
+
let desc;
|
|
403
|
+
let descId;
|
|
404
|
+
if (descChild) {
|
|
405
|
+
desc = (0, WABinary_1.getBinaryNodeChildString)(descChild, 'body');
|
|
406
|
+
descId = descChild.attrs.id;
|
|
407
|
+
}
|
|
408
|
+
const communityId = ((_a = community.attrs.id) === null || _a === void 0 ? void 0 : _a.includes('@'))
|
|
409
|
+
? community.attrs.id
|
|
410
|
+
: (0, WABinary_1.jidEncode)(community.attrs.id || '', 'g.us');
|
|
411
|
+
const eph = (_b = (0, WABinary_1.getBinaryNodeChild)(community, 'ephemeral')) === null || _b === void 0 ? void 0 : _b.attrs.expiration;
|
|
412
|
+
const memberAddMode = (0, WABinary_1.getBinaryNodeChildString)(community, 'member_add_mode') === 'all_member_add';
|
|
413
|
+
const metadata = {
|
|
414
|
+
id: communityId,
|
|
415
|
+
subject: community.attrs.subject || '',
|
|
416
|
+
subjectOwner: community.attrs.s_o,
|
|
417
|
+
subjectTime: Number(community.attrs.s_t || 0),
|
|
418
|
+
size: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').length,
|
|
419
|
+
creation: Number(community.attrs.creation || 0),
|
|
420
|
+
owner: community.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(community.attrs.creator) : undefined,
|
|
421
|
+
desc,
|
|
422
|
+
descId,
|
|
423
|
+
linkedParent: (0, WABinary_1.getBinaryNodeChild)(community, 'linked_parent')?.attrs.jid || undefined,
|
|
424
|
+
restrict: !!(0, WABinary_1.getBinaryNodeChild)(community, 'locked'),
|
|
425
|
+
announce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'announcement'),
|
|
426
|
+
isCommunity: !!(0, WABinary_1.getBinaryNodeChild)(community, 'parent'),
|
|
427
|
+
isCommunityAnnounce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'default_sub_community'),
|
|
428
|
+
joinApprovalMode: !!(0, WABinary_1.getBinaryNodeChild)(community, 'membership_approval_mode'),
|
|
429
|
+
memberAddMode,
|
|
430
|
+
participants: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').map(({ attrs }) => {
|
|
431
|
+
return {
|
|
432
|
+
id: attrs.jid,
|
|
433
|
+
admin: (attrs.type || null)
|
|
434
|
+
};
|
|
435
|
+
}),
|
|
436
|
+
ephemeralDuration: eph ? +eph : undefined,
|
|
437
|
+
addressingMode: (0, WABinary_1.getBinaryNodeChildString)(community, 'addressing_mode')
|
|
438
|
+
};
|
|
439
|
+
return metadata;
|
|
440
|
+
};
|
|
441
|
+
exports.extractCommunityMetadata = extractCommunityMetadata;
|
package/lib/Socket/index.js
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const { DEFAULT_CONNECTION_CONFIG } = require("../Defaults");
|
|
6
|
+
const communities_1 = require("./communities");
|
|
7
|
+
global.__SOCKET_MAP__ = global.__SOCKET_MAP__ || new Map()
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* * @param {Object} config - Konfigurasi Baileys
|
|
11
|
+
* @param {String} sessionId - ID Unik
|
|
12
|
+
*/
|
|
13
|
+
const makeWASocket = (config, sessionId = 'primary') => {
|
|
14
|
+
if (global.__SOCKET_MAP__.has(sessionId)) {
|
|
15
|
+
const oldSock = global.__SOCKET_MAP__.get(sessionId)
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
oldSock.ws?.close?.()
|
|
19
|
+
oldSock.ws?.terminate?.()
|
|
20
|
+
oldSock.ws?.removeAllListeners?.()
|
|
21
|
+
oldSock.ev?.removeAllListeners?.()
|
|
22
|
+
} catch (e) {
|
|
23
|
+
}
|
|
24
|
+
global.__SOCKET_MAP__.delete(sessionId)
|
|
25
|
+
}
|
|
26
|
+
// -----------------------------------
|
|
27
|
+
|
|
28
|
+
const sock = (0, communities_1.makeCommunitiesSocket)({
|
|
29
|
+
...Defaults_1.DEFAULT_CONNECTION_CONFIG,
|
|
30
|
+
...config
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
global.__SOCKET_MAP__.set(sessionId, sock)
|
|
34
|
+
sock.ws.on('close', () => {
|
|
35
|
+
if (global.__SOCKET_MAP__.get(sessionId) === sock) {
|
|
36
|
+
global.__SOCKET_MAP__.delete(sessionId)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
return sock
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
exports.default = makeWASocket
|
|
@@ -747,10 +747,21 @@ const makeMessagesRecvSocket = (config) => {
|
|
|
747
747
|
try {
|
|
748
748
|
await Promise.all([
|
|
749
749
|
processingMutex.mutex(async () => {
|
|
750
|
-
var _a, _b, _c, _d, _e, _f;
|
|
751
|
-
|
|
752
|
-
|
|
750
|
+
var _a, _b, _c, _d, _e, _f;
|
|
751
|
+
try {
|
|
752
|
+
await decrypt();
|
|
753
|
+
} catch (err) {
|
|
754
|
+
const errStr = String(err);
|
|
755
|
+
if (errStr.includes('Bad MAC') || errStr.includes('Invalid MAC')) {
|
|
756
|
+
logger.warn({ msgId: node.attrs.id, from: node.attrs.from }, '⚠️ Bad MAC detected (Node 20/24 issue) - Forcing Retry...');
|
|
757
|
+
msg.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
|
|
758
|
+
msg.messageStubParameters = [Utils_1.MISSING_KEYS_ERROR_TEXT];
|
|
759
|
+
} else {
|
|
760
|
+
throw err;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
753
763
|
if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
|
764
|
+
|
|
754
765
|
if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
|
|
755
766
|
return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
|
|
756
767
|
}
|
package/lib/Socket/socket.js
CHANGED
|
@@ -40,19 +40,6 @@ const makeSocket = (config) => {
|
|
|
40
40
|
routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
|
|
41
41
|
});
|
|
42
42
|
const { creds } = authState;
|
|
43
|
-
if (!creds.noiseKey?.public) {
|
|
44
|
-
creds.noiseKey = Utils_1.Curve.generateKeyPair()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!creds.signedIdentityKey?.public) {
|
|
48
|
-
creds.signedIdentityKey = Utils_1.Curve.generateKeyPair()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!creds.advSecretKey) {
|
|
52
|
-
creds.advSecretKey = (0, crypto_1.randomBytes)(32).toString('base64')
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
ev.emit('creds.update', creds)
|
|
56
43
|
// add transaction capability
|
|
57
44
|
const keys = (0, Utils_1.addTransactionCapability)(authState.keys, logger, transactionOpts);
|
|
58
45
|
const signalRepository = makeSignalRepository({ creds, keys });
|
|
@@ -66,26 +53,20 @@ ev.emit('creds.update', creds)
|
|
|
66
53
|
const sendPromise = (0, util_1.promisify)(ws.send);
|
|
67
54
|
/** send a raw buffer */
|
|
68
55
|
const sendRawMessage = async (data) => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const bytes = noise.encodeFrame(data)
|
|
76
|
-
|
|
77
|
-
await (0, Utils_1.promiseTimeout)(
|
|
78
|
-
connectTimeoutMs,
|
|
79
|
-
async (resolve, reject) => {
|
|
56
|
+
if (!ws.isOpen) {
|
|
57
|
+
throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
|
|
58
|
+
}
|
|
59
|
+
const bytes = noise.encodeFrame(data);
|
|
60
|
+
await (0, Utils_1.promiseTimeout)(connectTimeoutMs, async (resolve, reject) => {
|
|
80
61
|
try {
|
|
81
|
-
await sendPromise.call(ws, bytes)
|
|
82
|
-
resolve()
|
|
83
|
-
} catch (error) {
|
|
84
|
-
reject(error)
|
|
62
|
+
await sendPromise.call(ws, bytes);
|
|
63
|
+
resolve();
|
|
85
64
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
reject(error);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
89
70
|
/** send a binary node */
|
|
90
71
|
const sendNode = (frame) => {
|
|
91
72
|
if (logger.level === 'trace') {
|
|
@@ -413,104 +394,73 @@ const end = (error) => {
|
|
|
413
394
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
|
|
414
395
|
};
|
|
415
396
|
const requestPairingCode = async (phoneNumber, pairKey = "ELAINAMD") => {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
authState.creds.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
type: 'set',
|
|
444
|
-
id: generateMessageTag(),
|
|
445
|
-
xmlns: 'md'
|
|
446
|
-
},
|
|
447
|
-
content: [
|
|
448
|
-
{
|
|
449
|
-
tag: 'link_code_companion_reg',
|
|
450
|
-
attrs: {
|
|
451
|
-
jid: authState.creds.me.id,
|
|
452
|
-
stage: 'companion_hello',
|
|
453
|
-
should_show_push_notification: 'true'
|
|
454
|
-
},
|
|
455
|
-
content: [
|
|
456
|
-
{
|
|
457
|
-
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
458
|
-
attrs: {},
|
|
459
|
-
content: await generatePairingKey()
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
tag: 'companion_server_auth_key_pub',
|
|
463
|
-
attrs: {},
|
|
464
|
-
content: authState.creds.noiseKey.public
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
tag: 'companion_platform_id',
|
|
468
|
-
attrs: {},
|
|
469
|
-
content: (0, Utils_1.getPlatformId)(browser[1])
|
|
470
|
-
},
|
|
471
|
-
{
|
|
472
|
-
tag: 'companion_platform_display',
|
|
473
|
-
attrs: {},
|
|
474
|
-
content: `${browser[1]} (${browser[0]})`
|
|
397
|
+
if (pairKey) {
|
|
398
|
+
authState.creds.pairingCode = pairKey.toUpperCase();
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
authState.creds.pairingCode = (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5));
|
|
402
|
+
}
|
|
403
|
+
authState.creds.me = {
|
|
404
|
+
id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
|
|
405
|
+
name: '~'
|
|
406
|
+
};
|
|
407
|
+
ev.emit('creds.update', authState.creds);
|
|
408
|
+
await sendNode({
|
|
409
|
+
tag: 'iq',
|
|
410
|
+
attrs: {
|
|
411
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
412
|
+
type: 'set',
|
|
413
|
+
id: generateMessageTag(),
|
|
414
|
+
xmlns: 'md'
|
|
415
|
+
},
|
|
416
|
+
content: [
|
|
417
|
+
{
|
|
418
|
+
tag: 'link_code_companion_reg',
|
|
419
|
+
attrs: {
|
|
420
|
+
jid: authState.creds.me.id,
|
|
421
|
+
stage: 'companion_hello',
|
|
422
|
+
// eslint-disable-next-line camelcase
|
|
423
|
+
should_show_push_notification: 'true'
|
|
475
424
|
},
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
425
|
+
content: [
|
|
426
|
+
{
|
|
427
|
+
tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
|
|
428
|
+
attrs: {},
|
|
429
|
+
content: await generatePairingKey()
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
tag: 'companion_server_auth_key_pub',
|
|
433
|
+
attrs: {},
|
|
434
|
+
content: authState.creds.noiseKey.public
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
tag: 'companion_platform_id',
|
|
438
|
+
attrs: {},
|
|
439
|
+
content: (0, Utils_1.getPlatformId)(browser[1])
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
tag: 'companion_platform_display',
|
|
443
|
+
attrs: {},
|
|
444
|
+
content: `${browser[1]} (${browser[0]})`
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
tag: 'link_code_pairing_nonce',
|
|
448
|
+
attrs: {},
|
|
449
|
+
content: '0'
|
|
450
|
+
}
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
});
|
|
455
|
+
return authState.creds.pairingCode;
|
|
456
|
+
};
|
|
488
457
|
async function generatePairingKey() {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
458
|
+
const salt = (0, crypto_1.randomBytes)(32);
|
|
459
|
+
const randomIv = (0, crypto_1.randomBytes)(16);
|
|
460
|
+
const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
|
|
461
|
+
const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
|
|
462
|
+
return Buffer.concat([salt, randomIv, ciphered]);
|
|
492
463
|
}
|
|
493
|
-
|
|
494
|
-
if (!authState.creds.pairingCode) {
|
|
495
|
-
throw new Error("Pairing code belum tersedia")
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const salt = (0, crypto_1.randomBytes)(32)
|
|
499
|
-
const randomIv = (0, crypto_1.randomBytes)(16)
|
|
500
|
-
|
|
501
|
-
const key = await (0, Utils_1.derivePairingCodeKey)(
|
|
502
|
-
authState.creds.pairingCode,
|
|
503
|
-
salt
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
const ciphered = (0, Utils_1.aesEncryptCTR)(
|
|
507
|
-
authState.creds.pairingEphemeralKeyPair.public,
|
|
508
|
-
key,
|
|
509
|
-
randomIv
|
|
510
|
-
)
|
|
511
|
-
|
|
512
|
-
return Buffer.concat([salt, randomIv, ciphered])
|
|
513
|
-
}
|
|
514
464
|
const sendWAMBuffer = (wamBuffer) => {
|
|
515
465
|
return query({
|
|
516
466
|
tag: 'iq',
|
package/lib/Utils/messages.js
CHANGED
|
@@ -108,6 +108,10 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
const isNewsletter = !!options.jid && (0, WABinary_1.isJidNewsletter)(options.jid);
|
|
111
|
+
|
|
112
|
+
if (isNewsletter && mediaType === 'audio') {
|
|
113
|
+
uploadData.mimetype = 'audio/mp4';
|
|
114
|
+
}
|
|
111
115
|
|
|
112
116
|
if (isNewsletter) {
|
|
113
117
|
logger === null || logger === void 0 ? void 0 : logger.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
@@ -138,11 +142,20 @@ await fs_1.promises.unlink(filePath);
|
|
|
138
142
|
media: undefined
|
|
139
143
|
})
|
|
140
144
|
});
|
|
145
|
+
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
if (uploadData.ptv && mediaType === 'video') {
|
|
148
|
+
obj.ptvMessage = obj.videoMessage;
|
|
149
|
+
delete obj.videoMessage;
|
|
150
|
+
|
|
151
|
+
delete obj.ptvMessage.jpegThumbnail;
|
|
152
|
+
delete obj.ptvMessage.seconds;
|
|
153
|
+
delete obj.ptvMessage.gifPlayback;
|
|
154
|
+
delete obj.ptvMessage.contextInfo;
|
|
155
|
+
|
|
156
|
+
obj.ptvMessage.ptv = true;
|
|
157
|
+
obj.ptvMessage.mimetype = 'video/mp4';
|
|
158
|
+
}
|
|
146
159
|
|
|
147
160
|
|
|
148
161
|
if (obj.stickerMessage) {
|
|
@@ -239,11 +252,11 @@ await fs_1.promises.unlink(filePath);
|
|
|
239
252
|
})
|
|
240
253
|
});
|
|
241
254
|
|
|
242
|
-
if (uploadData.ptv) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
255
|
+
if (uploadData.ptv && mediaType === 'video') {
|
|
256
|
+
obj.ptvMessage = obj.videoMessage;
|
|
257
|
+
delete obj.videoMessage;
|
|
258
|
+
}
|
|
259
|
+
|
|
247
260
|
if (cacheableKey) {
|
|
248
261
|
logger === null || logger === void 0 ? void 0 : logger.debug({ cacheableKey }, 'set cache');
|
|
249
262
|
options.mediaCache.set(cacheableKey, Types_1.WAProto.Message.encode(obj).finish());
|
|
@@ -435,10 +448,6 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
435
448
|
break;
|
|
436
449
|
}
|
|
437
450
|
}
|
|
438
|
-
else if ('ptv' in message && message.ptv) {
|
|
439
|
-
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
440
|
-
m.ptvMessage = videoMessage;
|
|
441
|
-
}
|
|
442
451
|
else if ('product' in message) {
|
|
443
452
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
444
453
|
m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
|