@ryuu-reinzz/haruka-lib 2.3.0 → 2.4.0
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/main/audio-to-opus.js +40 -0
- package/main/index.js +17 -4
- package/main/socket.js +602 -581
- package/main/sqliteAuth.js +82 -78
- package/main/sticker-engine/image-to-webp.js +46 -44
- package/main/sticker-engine/index.js +10 -3
- package/main/sticker-engine/main-sticker.js +83 -77
- package/main/sticker-engine/video-to-webp.js +56 -54
- package/package.json +30 -29
package/main/socket.js
CHANGED
|
@@ -2,8 +2,12 @@ import crypto from "crypto";
|
|
|
2
2
|
import fetch from "node-fetch";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
fileURLToPath
|
|
7
|
+
} from 'url';
|
|
8
|
+
import {
|
|
9
|
+
dirname
|
|
10
|
+
} from 'path';
|
|
7
11
|
import Sticker from './sticker-engine/index.js';
|
|
8
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
13
|
const __dirname = dirname(__filename);
|
|
@@ -13,152 +17,158 @@ const __dirname = dirname(__filename);
|
|
|
13
17
|
*/
|
|
14
18
|
|
|
15
19
|
export default function addProperty(socket, store, smsg, baileys) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} = baileys;
|
|
25
|
-
|
|
26
|
-
Object.assign(socket, {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
20
|
+
const {
|
|
21
|
+
proto,
|
|
22
|
+
generateWAMessageFromContent,
|
|
23
|
+
jidDecode,
|
|
24
|
+
downloadContentFromMessage,
|
|
25
|
+
prepareWAMessageMedia,
|
|
26
|
+
generateMessageID,
|
|
27
|
+
generateWAMessage
|
|
28
|
+
} = baileys;
|
|
29
|
+
|
|
30
|
+
Object.assign(socket, {
|
|
31
|
+
sendCard: async (jid, options = {}) => {
|
|
32
|
+
const {
|
|
33
|
+
text = "",
|
|
34
|
+
footer = "",
|
|
35
|
+
cards = [],
|
|
36
|
+
quoted = null,
|
|
37
|
+
sender = jid
|
|
38
|
+
} = options
|
|
39
|
+
|
|
40
|
+
if (!cards.length) throw new Error("cards cannot be empty")
|
|
41
|
+
|
|
42
|
+
let carouselCards = []
|
|
43
|
+
const getImageMedia = async (image) => {
|
|
44
|
+
if (!image) throw new Error("Image cannot be empty")
|
|
45
|
+
|
|
46
|
+
if (typeof image === "string") {
|
|
47
|
+
return await prepareWAMessageMedia({
|
|
48
|
+
image: {
|
|
49
|
+
url: image
|
|
50
|
+
}
|
|
51
|
+
}, {
|
|
52
|
+
upload: socket.waUploadToServer
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (Buffer.isBuffer(image)) {
|
|
57
|
+
return await prepareWAMessageMedia({
|
|
58
|
+
image
|
|
59
|
+
}, {
|
|
60
|
+
upload: socket.waUploadToServer
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (typeof image === "object") {
|
|
65
|
+
return await prepareWAMessageMedia({
|
|
66
|
+
image
|
|
67
|
+
}, {
|
|
68
|
+
upload: socket.waUploadToServer
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new Error("Format image tidak didukung")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < cards.length; i++) {
|
|
76
|
+
const item = cards[i]
|
|
77
|
+
|
|
78
|
+
let img = await getImageMedia(item.image)
|
|
79
|
+
|
|
80
|
+
carouselCards.push({
|
|
81
|
+
header: proto.Message.InteractiveMessage.Header.fromObject({
|
|
82
|
+
title: item.caption || `Card ${i + 1}`,
|
|
83
|
+
hasMediaAttachment: true,
|
|
84
|
+
...img
|
|
85
|
+
}),
|
|
86
|
+
nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
|
|
87
|
+
buttons: Array.isArray(item.buttons) ? item.buttons : []
|
|
88
|
+
}),
|
|
89
|
+
footer: proto.Message.InteractiveMessage.Footer.create({
|
|
90
|
+
text: footer
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const msg = await generateWAMessageFromContent(
|
|
96
|
+
jid, {
|
|
97
|
+
viewOnceMessage: {
|
|
98
|
+
message: {
|
|
99
|
+
messageContextInfo: {
|
|
100
|
+
deviceListMetadata: {},
|
|
101
|
+
deviceListMetadataVersion: 2
|
|
102
|
+
},
|
|
103
|
+
interactiveMessage: proto.Message.InteractiveMessage.fromObject({
|
|
104
|
+
body: proto.Message.InteractiveMessage.Body.fromObject({
|
|
105
|
+
text
|
|
106
|
+
}),
|
|
107
|
+
carouselMessage: proto.Message.InteractiveMessage.CarouselMessage.fromObject({
|
|
108
|
+
cards: carouselCards
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, {
|
|
114
|
+
userJid: sender,
|
|
115
|
+
quoted
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return await socket.relayMessage(jid, msg.message, {
|
|
120
|
+
messageId: msg.key.id
|
|
101
121
|
})
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
let stickerPath
|
|
126
|
-
|
|
127
|
-
if (Buffer.isBuffer(options.sticker)) {
|
|
128
|
-
stickerPath = path.join(tmpDir, `sticker_${Date.now()}.webp`)
|
|
129
|
-
fs.writeFileSync(stickerPath, options.sticker)
|
|
130
|
-
} else if (typeof options.sticker === 'string') {
|
|
131
|
-
if (!fs.existsSync(options.sticker))
|
|
132
|
-
throw new Error(`File not found: ${options.sticker}`)
|
|
133
|
-
stickerPath = options.sticker
|
|
134
|
-
} else {
|
|
135
|
-
throw new Error('Sticker format not recognized (must be buffer or file path).')
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const sticker = new Sticker(stickerPath, {
|
|
139
|
-
pack: options.packname || "Made By",
|
|
140
|
-
author: options.author || "漏 饾檷廷饾櫘饾櫔饾櫔 饾檷廷饾櫄饾櫈饾櫍饾櫙饾櫙"
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
const buffer = await sticker.build()
|
|
144
|
-
const result = await socket.sendMessage(jid, { sticker: buffer })
|
|
145
|
-
|
|
146
|
-
if (Buffer.isBuffer(options.sticker)) fs.unlinkSync(stickerPath)
|
|
147
|
-
|
|
148
|
-
return result
|
|
149
|
-
} catch (e) {
|
|
150
|
-
console.error('[sendSticker Error]', e)
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
sendButton:
|
|
155
|
-
async (jid, content = {}, options = {}) => {
|
|
156
|
-
if (!socket.user?.id) {
|
|
157
|
-
throw new Error("User not authenticated");
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
sendSticker: async (jid, options = {}) => {
|
|
125
|
+
try {
|
|
126
|
+
if (!options.sticker)
|
|
127
|
+
throw new Error('Please enter the path or buffer of the sticker.')
|
|
128
|
+
|
|
129
|
+
const tmpDir = path.join(__dirname, './tmp')
|
|
130
|
+
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, {
|
|
131
|
+
recursive: true
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
let stickerPath
|
|
135
|
+
|
|
136
|
+
if (Buffer.isBuffer(options.sticker)) {
|
|
137
|
+
stickerPath = path.join(tmpDir, `sticker_${Date.now()}.webp`)
|
|
138
|
+
fs.writeFileSync(stickerPath, options.sticker)
|
|
139
|
+
} else if (typeof options.sticker === 'string') {
|
|
140
|
+
if (!fs.existsSync(options.sticker))
|
|
141
|
+
throw new Error(`File not found: ${options.sticker}`)
|
|
142
|
+
stickerPath = options.sticker
|
|
143
|
+
} else {
|
|
144
|
+
throw new Error('Sticker format not recognized (must be buffer or file path).')
|
|
158
145
|
}
|
|
159
146
|
|
|
160
|
-
const {
|
|
161
|
-
|
|
147
|
+
const sticker = new Sticker(stickerPath, {
|
|
148
|
+
pack: options.packname || "Made By",
|
|
149
|
+
author: options.author || "漏 饾檷廷饾櫘饾櫔饾櫔 饾檷廷饾櫄饾櫈饾櫍饾櫙饾櫙"
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const buffer = await sticker.build()
|
|
153
|
+
const result = await socket.sendMessage(jid, {
|
|
154
|
+
sticker: buffer
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
if (Buffer.isBuffer(options.sticker)) fs.unlinkSync(stickerPath)
|
|
158
|
+
|
|
159
|
+
return result
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.error('[sendSticker Error]', e)
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
sendButton: async (jid, content = {}, options = {}) => {
|
|
166
|
+
if (!socket.user?.id) {
|
|
167
|
+
throw new Error("User not authenticated");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const {
|
|
171
|
+
text = "",
|
|
162
172
|
caption = "",
|
|
163
173
|
title = "",
|
|
164
174
|
footer = "",
|
|
@@ -174,488 +184,499 @@ Object.assign(socket, {
|
|
|
174
184
|
product = null,
|
|
175
185
|
businessOwnerJid = null,
|
|
176
186
|
externalAdReply = null,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (!Array.isArray(buttons) || buttons.length === 0) {
|
|
180
|
-
throw new Error("buttons must be a non-empty array");
|
|
181
|
-
}
|
|
187
|
+
} = content;
|
|
182
188
|
|
|
183
|
-
|
|
189
|
+
if (!Array.isArray(buttons) || buttons.length === 0) {
|
|
190
|
+
throw new Error("buttons must be a non-empty array");
|
|
191
|
+
}
|
|
184
192
|
|
|
185
|
-
|
|
186
|
-
const btn = buttons[i];
|
|
193
|
+
const processedButtons = [];
|
|
187
194
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
195
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
196
|
+
const btn = buttons[i];
|
|
191
197
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
198
|
+
if (!btn || typeof btn !== "object") {
|
|
199
|
+
throw new Error(`interactiveButton[${i}] must be an object`);
|
|
200
|
+
}
|
|
196
201
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
display_text: btn.text || btn.displayText || `Button ${i + 1}`,
|
|
202
|
-
id: btn.id || `quick_${i + 1}`,
|
|
203
|
-
}),
|
|
204
|
-
});
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
202
|
+
if (btn.name && btn.buttonParamsJson) {
|
|
203
|
+
processedButtons.push(btn);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
207
206
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
207
|
+
if (btn.id || btn.text || btn.displayText) {
|
|
208
|
+
processedButtons.push({
|
|
209
|
+
name: "quick_reply",
|
|
210
|
+
buttonParamsJson: JSON.stringify({
|
|
211
|
+
display_text: btn.text || btn.displayText || `Button ${i + 1}`,
|
|
212
|
+
id: btn.id || `quick_${i + 1}`,
|
|
213
|
+
}),
|
|
214
|
+
});
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
218
217
|
|
|
219
|
-
|
|
218
|
+
if (btn.buttonId && btn.buttonText?.displayText) {
|
|
219
|
+
processedButtons.push({
|
|
220
|
+
name: "quick_reply",
|
|
221
|
+
buttonParamsJson: JSON.stringify({
|
|
222
|
+
display_text: btn.buttonText.displayText,
|
|
223
|
+
id: btn.buttonId,
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
continue;
|
|
220
227
|
}
|
|
221
228
|
|
|
222
|
-
|
|
229
|
+
throw new Error(`interactiveButton[${i}] has invalid shape`);
|
|
230
|
+
}
|
|
223
231
|
|
|
224
|
-
|
|
225
|
-
const mediaInput = {};
|
|
226
|
-
if (Buffer.isBuffer(image)) {
|
|
227
|
-
mediaInput.image = image;
|
|
228
|
-
} else if (typeof image === "object" && image.url) {
|
|
229
|
-
mediaInput.image = { url: image.url };
|
|
230
|
-
} else if (typeof image === "string") {
|
|
231
|
-
mediaInput.image = { url: image };
|
|
232
|
-
}
|
|
232
|
+
let messageContent = {};
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
if (image) {
|
|
235
|
+
const mediaInput = {};
|
|
236
|
+
if (Buffer.isBuffer(image)) {
|
|
237
|
+
mediaInput.image = image;
|
|
238
|
+
} else if (typeof image === "object" && image.url) {
|
|
239
|
+
mediaInput.image = {
|
|
240
|
+
url: image.url
|
|
241
|
+
};
|
|
242
|
+
} else if (typeof image === "string") {
|
|
243
|
+
mediaInput.image = {
|
|
244
|
+
url: image
|
|
245
|
+
};
|
|
246
|
+
}
|
|
237
247
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
248
|
+
const preparedMedia = await prepareWAMessageMedia(mediaInput, {
|
|
249
|
+
upload: socket.waUploadToServer,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
messageContent.header = {
|
|
253
|
+
title: title || "",
|
|
254
|
+
hasMediaAttachment: hasMediaAttachment || true,
|
|
255
|
+
imageMessage: preparedMedia.imageMessage,
|
|
256
|
+
};
|
|
257
|
+
} else if (video) {
|
|
258
|
+
const mediaInput = {};
|
|
259
|
+
if (Buffer.isBuffer(video)) {
|
|
260
|
+
mediaInput.video = video;
|
|
261
|
+
} else if (typeof video === "object" && video.url) {
|
|
262
|
+
mediaInput.video = {
|
|
263
|
+
url: video.url
|
|
242
264
|
};
|
|
243
|
-
} else if (video) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
mediaInput.video = { url: video.url };
|
|
249
|
-
} else if (typeof video === "string") {
|
|
250
|
-
mediaInput.video = { url: video };
|
|
251
|
-
}
|
|
265
|
+
} else if (typeof video === "string") {
|
|
266
|
+
mediaInput.video = {
|
|
267
|
+
url: video
|
|
268
|
+
};
|
|
269
|
+
}
|
|
252
270
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
271
|
+
const preparedMedia = await prepareWAMessageMedia(mediaInput, {
|
|
272
|
+
upload: socket.waUploadToServer,
|
|
273
|
+
});
|
|
256
274
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
275
|
+
messageContent.header = {
|
|
276
|
+
title: title || "",
|
|
277
|
+
hasMediaAttachment: hasMediaAttachment || true,
|
|
278
|
+
videoMessage: preparedMedia.videoMessage,
|
|
279
|
+
};
|
|
280
|
+
} else if (document) {
|
|
281
|
+
const mediaInput = {
|
|
282
|
+
document: {}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
if (Buffer.isBuffer(document)) {
|
|
286
|
+
mediaInput.document = document;
|
|
287
|
+
} else if (typeof document === "object" && document.url) {
|
|
288
|
+
mediaInput.document = {
|
|
289
|
+
url: document.url
|
|
261
290
|
};
|
|
262
|
-
} else if (document) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
} else if (typeof document === "object" && document.url) {
|
|
268
|
-
mediaInput.document = { url: document.url };
|
|
269
|
-
} else if (typeof document === "string") {
|
|
270
|
-
mediaInput.document = { url: document };
|
|
271
|
-
}
|
|
291
|
+
} else if (typeof document === "string") {
|
|
292
|
+
mediaInput.document = {
|
|
293
|
+
url: document
|
|
294
|
+
};
|
|
295
|
+
}
|
|
272
296
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
297
|
+
if (fileName) {
|
|
298
|
+
if (typeof mediaInput.document === "object") {
|
|
299
|
+
mediaInput.document.fileName = fileName;
|
|
277
300
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (mimetype) {
|
|
304
|
+
if (typeof mediaInput.document === "object") {
|
|
305
|
+
mediaInput.document.mimetype = mimetype;
|
|
283
306
|
}
|
|
307
|
+
}
|
|
284
308
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
309
|
+
if (jpegThumbnail) {
|
|
310
|
+
if (typeof mediaInput.document === "object") {
|
|
311
|
+
if (Buffer.isBuffer(jpegThumbnail)) {
|
|
312
|
+
mediaInput.document.jpegThumbnail = jpegThumbnail;
|
|
313
|
+
} else if (typeof jpegThumbnail === "string") {
|
|
314
|
+
try {
|
|
315
|
+
const response = await fetch(jpegThumbnail);
|
|
316
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
317
|
+
mediaInput.document.jpegThumbnail = Buffer.from(arrayBuffer);
|
|
318
|
+
} catch {
|
|
319
|
+
//
|
|
297
320
|
}
|
|
298
321
|
}
|
|
299
322
|
}
|
|
323
|
+
}
|
|
300
324
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
messageContent.header = {
|
|
306
|
-
title: title || "",
|
|
307
|
-
hasMediaAttachment: hasMediaAttachment || true,
|
|
308
|
-
documentMessage: preparedMedia.documentMessage,
|
|
309
|
-
};
|
|
310
|
-
} else if (location && typeof location === "object") {
|
|
311
|
-
messageContent.header = {
|
|
312
|
-
title: title || location.name || "Location",
|
|
313
|
-
hasMediaAttachment: hasMediaAttachment || false,
|
|
314
|
-
locationMessage: {
|
|
315
|
-
degreesLatitude:
|
|
316
|
-
location.degressLatitude || location.degreesLatitude || 0,
|
|
317
|
-
degreesLongitude:
|
|
318
|
-
location.degressLongitude || location.degreesLongitude || 0,
|
|
319
|
-
name: location.name || "",
|
|
320
|
-
address: location.address || "",
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
} else if (product && typeof product === "object") {
|
|
324
|
-
let productImageMessage = null;
|
|
325
|
-
if (product.productImage) {
|
|
326
|
-
const mediaInput = {};
|
|
327
|
-
if (Buffer.isBuffer(product.productImage)) {
|
|
328
|
-
mediaInput.image = product.productImage;
|
|
329
|
-
} else if (
|
|
330
|
-
typeof product.productImage === "object" &&
|
|
331
|
-
product.productImage.url
|
|
332
|
-
) {
|
|
333
|
-
mediaInput.image = {
|
|
334
|
-
url: product.productImage.url,
|
|
335
|
-
};
|
|
336
|
-
} else if (typeof product.productImage === "string") {
|
|
337
|
-
mediaInput.image = {
|
|
338
|
-
url: product.productImage,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
325
|
+
const preparedMedia = await prepareWAMessageMedia(mediaInput, {
|
|
326
|
+
upload: socket.waUploadToServer,
|
|
327
|
+
});
|
|
341
328
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
329
|
+
messageContent.header = {
|
|
330
|
+
title: title || "",
|
|
331
|
+
hasMediaAttachment: hasMediaAttachment || true,
|
|
332
|
+
documentMessage: preparedMedia.documentMessage,
|
|
333
|
+
};
|
|
334
|
+
} else if (location && typeof location === "object") {
|
|
335
|
+
messageContent.header = {
|
|
336
|
+
title: title || location.name || "Location",
|
|
337
|
+
hasMediaAttachment: hasMediaAttachment || false,
|
|
338
|
+
locationMessage: {
|
|
339
|
+
degreesLatitude: location.degressLatitude || location.degreesLatitude || 0,
|
|
340
|
+
degreesLongitude: location.degressLongitude || location.degreesLongitude || 0,
|
|
341
|
+
name: location.name || "",
|
|
342
|
+
address: location.address || "",
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
} else if (product && typeof product === "object") {
|
|
346
|
+
let productImageMessage = null;
|
|
347
|
+
if (product.productImage) {
|
|
348
|
+
const mediaInput = {};
|
|
349
|
+
if (Buffer.isBuffer(product.productImage)) {
|
|
350
|
+
mediaInput.image = product.productImage;
|
|
351
|
+
} else if (
|
|
352
|
+
typeof product.productImage === "object" &&
|
|
353
|
+
product.productImage.url
|
|
354
|
+
) {
|
|
355
|
+
mediaInput.image = {
|
|
356
|
+
url: product.productImage.url,
|
|
357
|
+
};
|
|
358
|
+
} else if (typeof product.productImage === "string") {
|
|
359
|
+
mediaInput.image = {
|
|
360
|
+
url: product.productImage,
|
|
361
|
+
};
|
|
346
362
|
}
|
|
347
363
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
product: {
|
|
353
|
-
productImage: productImageMessage,
|
|
354
|
-
productId: product.productId || "",
|
|
355
|
-
title: product.title || "",
|
|
356
|
-
description: product.description || "",
|
|
357
|
-
currencyCode: product.currencyCode || "USD",
|
|
358
|
-
priceAmount1000: parseInt(product.priceAmount1000) || 0,
|
|
359
|
-
retailerId: product.retailerId || "",
|
|
360
|
-
url: product.url || "",
|
|
361
|
-
productImageCount: product.productImageCount || 1,
|
|
362
|
-
},
|
|
363
|
-
businessOwnerJid:
|
|
364
|
-
businessOwnerJid || product.businessOwnerJid || socket.user.id,
|
|
365
|
-
},
|
|
366
|
-
};
|
|
367
|
-
} else if (title) {
|
|
368
|
-
messageContent.header = {
|
|
369
|
-
title: title,
|
|
370
|
-
hasMediaAttachment: false,
|
|
371
|
-
};
|
|
364
|
+
const preparedMedia = await prepareWAMessageMedia(mediaInput, {
|
|
365
|
+
upload: socket.waUploadToServer,
|
|
366
|
+
});
|
|
367
|
+
productImageMessage = preparedMedia.imageMessage;
|
|
372
368
|
}
|
|
373
369
|
|
|
374
|
-
|
|
375
|
-
|
|
370
|
+
messageContent.header = {
|
|
371
|
+
title: title || product.title || "Product",
|
|
372
|
+
hasMediaAttachment: hasMediaAttachment || false,
|
|
373
|
+
productMessage: {
|
|
374
|
+
product: {
|
|
375
|
+
productImage: productImageMessage,
|
|
376
|
+
productId: product.productId || "",
|
|
377
|
+
title: product.title || "",
|
|
378
|
+
description: product.description || "",
|
|
379
|
+
currencyCode: product.currencyCode || "USD",
|
|
380
|
+
priceAmount1000: parseInt(product.priceAmount1000) || 0,
|
|
381
|
+
retailerId: product.retailerId || "",
|
|
382
|
+
url: product.url || "",
|
|
383
|
+
productImageCount: product.productImageCount || 1,
|
|
384
|
+
},
|
|
385
|
+
businessOwnerJid: businessOwnerJid || product.businessOwnerJid || socket.user.id,
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
} else if (title) {
|
|
389
|
+
messageContent.header = {
|
|
390
|
+
title: title,
|
|
391
|
+
hasMediaAttachment: false,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
376
394
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
395
|
+
const hasMedia = !!(image || video || document || location || product);
|
|
396
|
+
const bodyText = hasMedia ? caption : text || caption;
|
|
380
397
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
398
|
+
if (bodyText) {
|
|
399
|
+
messageContent.body = {
|
|
400
|
+
text: bodyText
|
|
401
|
+
};
|
|
402
|
+
}
|
|
384
403
|
|
|
385
|
-
|
|
386
|
-
|
|
404
|
+
if (footer) {
|
|
405
|
+
messageContent.footer = {
|
|
406
|
+
text: footer
|
|
387
407
|
};
|
|
408
|
+
}
|
|
388
409
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
+
messageContent.nativeFlowMessage = {
|
|
411
|
+
buttons: processedButtons,
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
if (externalAdReply && typeof externalAdReply === "object") {
|
|
415
|
+
messageContent.contextInfo = {
|
|
416
|
+
externalAdReply: {
|
|
417
|
+
title: externalAdReply.title || "",
|
|
418
|
+
body: externalAdReply.body || "",
|
|
419
|
+
mediaType: externalAdReply.mediaType || 1,
|
|
420
|
+
sourceUrl: externalAdReply.sourceUrl || externalAdReply.url || "",
|
|
421
|
+
thumbnailUrl: externalAdReply.thumbnailUrl || "",
|
|
422
|
+
renderLargerThumbnail: externalAdReply.renderLargerThumbnail || false,
|
|
423
|
+
showAdAttribution: externalAdReply.showAdAttribution !== false,
|
|
424
|
+
containsAutoReply: externalAdReply.containsAutoReply || false,
|
|
425
|
+
...(externalAdReply.mediaUrl && {
|
|
426
|
+
mediaUrl: externalAdReply.mediaUrl,
|
|
427
|
+
}),
|
|
428
|
+
...(externalAdReply.thumbnail &&
|
|
429
|
+
Buffer.isBuffer(externalAdReply.thumbnail) && {
|
|
430
|
+
thumbnail: externalAdReply.thumbnail,
|
|
410
431
|
}),
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
mentionedJid: options.mentionedJid,
|
|
432
|
+
...(externalAdReply.jpegThumbnail && {
|
|
433
|
+
jpegThumbnail: externalAdReply.jpegThumbnail,
|
|
414
434
|
}),
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
messageContent.contextInfo = {
|
|
435
|
+
},
|
|
436
|
+
...(options.mentionedJid && {
|
|
418
437
|
mentionedJid: options.mentionedJid,
|
|
419
|
-
}
|
|
420
|
-
}
|
|
438
|
+
}),
|
|
439
|
+
};
|
|
440
|
+
} else if (options.mentionedJid) {
|
|
441
|
+
messageContent.contextInfo = {
|
|
442
|
+
mentionedJid: options.mentionedJid,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
421
445
|
|
|
422
|
-
|
|
446
|
+
const payload = proto.Message.InteractiveMessage.create(messageContent);
|
|
423
447
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
{
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
interactiveMessage: payload,
|
|
430
|
-
},
|
|
448
|
+
const msg = generateWAMessageFromContent(
|
|
449
|
+
jid, {
|
|
450
|
+
viewOnceMessage: {
|
|
451
|
+
message: {
|
|
452
|
+
interactiveMessage: payload,
|
|
431
453
|
},
|
|
432
454
|
},
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
type: "native_flow",
|
|
448
|
-
v: "1",
|
|
449
|
-
},
|
|
450
|
-
content: [
|
|
451
|
-
{
|
|
452
|
-
tag: "native_flow",
|
|
453
|
-
attrs: {
|
|
454
|
-
v: "9",
|
|
455
|
-
name: "mixed",
|
|
456
|
-
},
|
|
457
|
-
},
|
|
458
|
-
],
|
|
459
|
-
},
|
|
460
|
-
],
|
|
455
|
+
}, {
|
|
456
|
+
userJid: socket.user.id,
|
|
457
|
+
quoted: options?.quoted || null,
|
|
458
|
+
}
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
const additionalNodes = [{
|
|
462
|
+
tag: "biz",
|
|
463
|
+
attrs: {},
|
|
464
|
+
content: [{
|
|
465
|
+
tag: "interactive",
|
|
466
|
+
attrs: {
|
|
467
|
+
type: "native_flow",
|
|
468
|
+
v: "1",
|
|
461
469
|
},
|
|
462
|
-
|
|
470
|
+
content: [{
|
|
471
|
+
tag: "native_flow",
|
|
472
|
+
attrs: {
|
|
473
|
+
v: "9",
|
|
474
|
+
name: "mixed",
|
|
475
|
+
},
|
|
476
|
+
}, ],
|
|
477
|
+
}, ],
|
|
478
|
+
}, ];
|
|
463
479
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
480
|
+
await socket.relayMessage(jid, msg.message, {
|
|
481
|
+
messageId: msg.key.id,
|
|
482
|
+
additionalNodes,
|
|
483
|
+
});
|
|
468
484
|
|
|
469
|
-
|
|
485
|
+
return msg;
|
|
470
486
|
},
|
|
471
487
|
sendAlbum: async (jid, items = [], options = {}) => {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const messageSecret = new Uint8Array(32);
|
|
477
|
-
crypto.getRandomValues(messageSecret);
|
|
478
|
-
|
|
479
|
-
const messageContent = {
|
|
480
|
-
messageContextInfo: { messageSecret },
|
|
481
|
-
albumMessage: {
|
|
482
|
-
expectedImageCount: items.filter((a) =>
|
|
483
|
-
a?.image).length,
|
|
484
|
-
expectedVideoCount: items.filter((a) =>
|
|
485
|
-
a?.video).length,
|
|
486
|
-
},
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
const generationOptions = {
|
|
490
|
-
userJid: socket.user.id,
|
|
491
|
-
upload: socket.waUploadToServer,
|
|
492
|
-
quoted: options?.quoted || null,
|
|
493
|
-
ephemeralExpiration: options?.quoted
|
|
494
|
-
?.expiration ?? 0,
|
|
495
|
-
};
|
|
496
|
-
|
|
497
|
-
const album = generateWAMessageFromContent(jid,
|
|
498
|
-
messageContent, generationOptions);
|
|
499
|
-
|
|
500
|
-
await socket.relayMessage(album.key.remoteJid, album
|
|
501
|
-
.message, {
|
|
502
|
-
messageId: album.key.id,
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
await Promise.all(
|
|
506
|
-
items.map(async (content) => {
|
|
507
|
-
const mediaSecret =
|
|
508
|
-
new Uint8Array(32);
|
|
509
|
-
crypto.getRandomValues(
|
|
510
|
-
mediaSecret);
|
|
511
|
-
|
|
512
|
-
const mediaMsg =
|
|
513
|
-
await generateWAMessage(
|
|
514
|
-
album.key.remoteJid,
|
|
515
|
-
content, {
|
|
516
|
-
upload: socket
|
|
517
|
-
.waUploadToServer,
|
|
518
|
-
ephemeralExpiration: options
|
|
519
|
-
?.quoted
|
|
520
|
-
?.expiration ??
|
|
521
|
-
0,
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
mediaMsg.message
|
|
525
|
-
.messageContextInfo = {
|
|
526
|
-
messageSecret: mediaSecret,
|
|
527
|
-
messageAssociation: {
|
|
528
|
-
associationType: 1,
|
|
529
|
-
parentMessageKey: album
|
|
530
|
-
.key,
|
|
531
|
-
},
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
return socket.relayMessage(
|
|
535
|
-
mediaMsg.key.remoteJid,
|
|
536
|
-
mediaMsg.message, {
|
|
537
|
-
messageId: mediaMsg
|
|
538
|
-
.key.id,
|
|
539
|
-
});
|
|
540
|
-
})
|
|
541
|
-
);
|
|
542
|
-
|
|
543
|
-
return album;
|
|
544
|
-
},
|
|
545
|
-
|
|
546
|
-
sendOrder: async (jid, orderData, options = {}) => {
|
|
547
|
-
if (!socket.user?.id) {
|
|
548
|
-
throw new Error("User not authenticated");
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
let thumbnail = null;
|
|
552
|
-
if (orderData.thumbnail) {
|
|
553
|
-
if (Buffer.isBuffer(orderData.thumbnail)) {
|
|
554
|
-
thumbnail = orderData.thumbnail;
|
|
555
|
-
} else if (typeof orderData.thumbnail === "string") {
|
|
556
|
-
try {
|
|
557
|
-
if (orderData.thumbnail.startsWith("http")) {
|
|
558
|
-
const response = await fetch(orderData.thumbnail);
|
|
559
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
560
|
-
thumbnail = Buffer.from(arrayBuffer);
|
|
561
|
-
} else {
|
|
562
|
-
thumbnail = Buffer.from(orderData.thumbnail, "base64");
|
|
488
|
+
if (!socket.user?.id) {
|
|
489
|
+
throw new Error("User not authenticated");
|
|
563
490
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
491
|
+
|
|
492
|
+
const messageSecret = new Uint8Array(32);
|
|
493
|
+
crypto.getRandomValues(messageSecret);
|
|
494
|
+
|
|
495
|
+
const messageContent = {
|
|
496
|
+
messageContextInfo: {
|
|
497
|
+
messageSecret
|
|
498
|
+
},
|
|
499
|
+
albumMessage: {
|
|
500
|
+
expectedImageCount: items.filter((a) =>
|
|
501
|
+
a?.image).length,
|
|
502
|
+
expectedVideoCount: items.filter((a) =>
|
|
503
|
+
a?.video).length,
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const generationOptions = {
|
|
508
|
+
userJid: socket.user.id,
|
|
509
|
+
upload: socket.waUploadToServer,
|
|
510
|
+
quoted: options?.quoted || null,
|
|
511
|
+
ephemeralExpiration: options?.quoted
|
|
512
|
+
?.expiration ?? 0,
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const album = generateWAMessageFromContent(jid,
|
|
516
|
+
messageContent, generationOptions);
|
|
517
|
+
|
|
518
|
+
await socket.relayMessage(album.key.remoteJid, album
|
|
519
|
+
.message, {
|
|
520
|
+
messageId: album.key.id,
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
await Promise.all(
|
|
524
|
+
items.map(async (content) => {
|
|
525
|
+
const mediaSecret =
|
|
526
|
+
new Uint8Array(32);
|
|
527
|
+
crypto.getRandomValues(
|
|
528
|
+
mediaSecret);
|
|
529
|
+
|
|
530
|
+
const mediaMsg =
|
|
531
|
+
await generateWAMessage(
|
|
532
|
+
album.key.remoteJid,
|
|
533
|
+
content, {
|
|
534
|
+
upload: socket
|
|
535
|
+
.waUploadToServer,
|
|
536
|
+
ephemeralExpiration: options
|
|
537
|
+
?.quoted
|
|
538
|
+
?.expiration ??
|
|
539
|
+
0,
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
mediaMsg.message
|
|
543
|
+
.messageContextInfo = {
|
|
544
|
+
messageSecret: mediaSecret,
|
|
545
|
+
messageAssociation: {
|
|
546
|
+
associationType: 1,
|
|
547
|
+
parentMessageKey: album
|
|
548
|
+
.key,
|
|
549
|
+
},
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
return socket.relayMessage(
|
|
553
|
+
mediaMsg.key.remoteJid,
|
|
554
|
+
mediaMsg.message, {
|
|
555
|
+
messageId: mediaMsg
|
|
556
|
+
.key.id,
|
|
557
|
+
});
|
|
558
|
+
})
|
|
570
559
|
);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
560
|
+
|
|
561
|
+
return album;
|
|
562
|
+
},
|
|
563
|
+
|
|
564
|
+
sendOrder: async (jid, orderData, options = {}) => {
|
|
565
|
+
if (!socket.user?.id) {
|
|
566
|
+
throw new Error("User not authenticated");
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
let thumbnail = null;
|
|
570
|
+
if (orderData.thumbnail) {
|
|
571
|
+
if (Buffer.isBuffer(orderData.thumbnail)) {
|
|
572
|
+
thumbnail = orderData.thumbnail;
|
|
573
|
+
} else if (typeof orderData.thumbnail === "string") {
|
|
574
|
+
try {
|
|
575
|
+
if (orderData.thumbnail.startsWith("http")) {
|
|
576
|
+
const response = await fetch(orderData.thumbnail);
|
|
577
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
578
|
+
thumbnail = Buffer.from(arrayBuffer);
|
|
579
|
+
} else {
|
|
580
|
+
thumbnail = Buffer.from(orderData.thumbnail, "base64");
|
|
581
|
+
}
|
|
582
|
+
} catch (e) {
|
|
583
|
+
socket.logger?.warn({
|
|
584
|
+
err: e.message
|
|
585
|
+
},
|
|
586
|
+
"Failed to fetch/convert thumbnail"
|
|
587
|
+
);
|
|
588
|
+
thumbnail = null;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const orderMessage = proto.Message.OrderMessage.fromObject({
|
|
594
|
+
orderId: orderData.orderId || generateMessageID(),
|
|
595
|
+
thumbnail: thumbnail,
|
|
596
|
+
itemCount: orderData.itemCount || 1,
|
|
597
|
+
status: orderData.status || proto.Message.OrderMessage.OrderStatus.INQUIRY,
|
|
598
|
+
surface: orderData.surface || proto.Message.OrderMessage.OrderSurface.CATALOG,
|
|
599
|
+
message: orderData.message || "",
|
|
600
|
+
orderTitle: orderData.orderTitle || "Order",
|
|
601
|
+
sellerJid: orderData.sellerJid || socket.user.id,
|
|
602
|
+
token: orderData.token || "",
|
|
603
|
+
totalAmount1000: orderData.totalAmount1000 || 0,
|
|
604
|
+
totalCurrencyCode: orderData.totalCurrencyCode || "IDR",
|
|
605
|
+
contextInfo: {
|
|
606
|
+
...(options.contextInfo || {}),
|
|
607
|
+
...(options.mentions ? {
|
|
608
|
+
mentionedJid: options.mentions,
|
|
609
|
+
} : {}),
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
const msg = proto.Message.create({
|
|
614
|
+
orderMessage,
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
const message = generateWAMessageFromContent(jid, msg, {
|
|
618
|
+
userJid: socket.user.id,
|
|
619
|
+
timestamp: options.timestamp || new Date(),
|
|
620
|
+
quoted: options.quoted || null,
|
|
621
|
+
ephemeralExpiration: options.ephemeralExpiration || 0,
|
|
622
|
+
messageId: options.messageId || null,
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
return await socket.relayMessage(message.key.remoteJid, message.message, {
|
|
626
|
+
messageId: message.key.id,
|
|
627
|
+
});
|
|
628
|
+
},
|
|
629
|
+
|
|
630
|
+
getPNFromLid: async (m, lidInput) => {
|
|
631
|
+
if (!lidInput) throw new Error("Misssing input");
|
|
632
|
+
try {
|
|
633
|
+
let chat = m.chat
|
|
634
|
+
if (chat.endsWith('@g.us')) {
|
|
635
|
+
|
|
636
|
+
const metadata = await socket.groupMetadata(chat);
|
|
637
|
+
if (!metadata || !metadata.participants) return lidInput;
|
|
638
|
+
|
|
639
|
+
const found = metadata.participants.find(entry => entry.id === lidInput);
|
|
640
|
+
return found ? found.phoneNumber : lidInput;
|
|
641
|
+
} else {
|
|
642
|
+
const {
|
|
643
|
+
remoteJid,
|
|
644
|
+
remoteJidAlt
|
|
645
|
+
} = m.key
|
|
646
|
+
if (remoteJid === lidInput && remoteJidAlt.endsWith("@s.whatsapp.net")) {
|
|
647
|
+
return remoteJidAlt
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
} catch (e) {
|
|
651
|
+
console.error('Gagal ambil group metadata:', e.message);
|
|
652
|
+
return lidInput;
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
getLidFromPN: async (m, jidInput) => {
|
|
657
|
+
if (!jidInput) throw new Error("Misssing jid input");
|
|
658
|
+
try {
|
|
659
|
+
let chat = m.chat;
|
|
660
|
+
if (chat.endsWith('@g.us')) {
|
|
661
|
+
const metadata = await socket.groupMetadata(chat);
|
|
662
|
+
if (!metadata || !metadata.participants) return jidInput;
|
|
663
|
+
|
|
664
|
+
const found = metadata.participants.find(entry => entry.phoneNumber === jidInput);
|
|
665
|
+
return found ? found.id : jidInput;
|
|
666
|
+
} else {
|
|
667
|
+
const {
|
|
668
|
+
remoteJid,
|
|
669
|
+
remoteJidAlt
|
|
670
|
+
} = m.key
|
|
671
|
+
if (!remoteJid || !remoteJidAlt) return null
|
|
672
|
+
if (remoteJidAlt === jidInput && remoteJid.endsWith("@lid")) {
|
|
673
|
+
return remoteJid
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
} catch (e) {
|
|
677
|
+
console.error('Gagal ambil group metadata:', e.message);
|
|
678
|
+
return jidInput;
|
|
679
|
+
}
|
|
595
680
|
},
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const msg = proto.Message.create({
|
|
599
|
-
orderMessage,
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
const message = generateWAMessageFromContent(jid, msg, {
|
|
603
|
-
userJid: socket.user.id,
|
|
604
|
-
timestamp: options.timestamp || new Date(),
|
|
605
|
-
quoted: options.quoted || null,
|
|
606
|
-
ephemeralExpiration: options.ephemeralExpiration || 0,
|
|
607
|
-
messageId: options.messageId || null,
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
return await socket.relayMessage(message.key.remoteJid, message.message, {
|
|
611
|
-
messageId: message.key.id,
|
|
612
|
-
});
|
|
613
|
-
},
|
|
614
|
-
|
|
615
|
-
getPNFromLid: async (m, lidInput) => {
|
|
616
|
-
if (!lidInput) throw new Error("Misssing input");
|
|
617
|
-
try {
|
|
618
|
-
let chat = m.chat
|
|
619
|
-
if (chat.endsWith('@g.us')) {
|
|
620
|
-
|
|
621
|
-
const metadata = await socket.groupMetadata(chat);
|
|
622
|
-
if (!metadata || !metadata.participants) return lidInput;
|
|
623
|
-
|
|
624
|
-
const found = metadata.participants.find(entry => entry.id === lidInput);
|
|
625
|
-
return found ? found.phoneNumber : lidInput;
|
|
626
|
-
} else {
|
|
627
|
-
const { remoteJid, remoteJidAlt } = m.key
|
|
628
|
-
if (remoteJid === lidInput && remoteJidAlt.endsWith("@s.whatsapp.net")) {
|
|
629
|
-
return remoteJidAlt
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
} catch (e) {
|
|
633
|
-
console.error('Gagal ambil group metadata:', e.message);
|
|
634
|
-
return lidInput;
|
|
635
|
-
}
|
|
636
|
-
},
|
|
637
|
-
|
|
638
|
-
getLidFromPN: async (m, jidInput) => {
|
|
639
|
-
if (!jidInput) throw new Error("Misssing jid input");
|
|
640
|
-
try {
|
|
641
|
-
let chat = m.chat;
|
|
642
|
-
if (chat.endsWith('@g.us')) {
|
|
643
|
-
const metadata = await socket.groupMetadata(chat);
|
|
644
|
-
if (!metadata || !metadata.participants) return jidInput;
|
|
645
|
-
|
|
646
|
-
const found = metadata.participants.find(entry => entry.phoneNumber === jidInput);
|
|
647
|
-
return found ? found.id : jidInput;
|
|
648
|
-
} else {
|
|
649
|
-
const { remoteJid, remoteJidAlt } = m.key
|
|
650
|
-
if (!remoteJid || !remoteJidAlt) return null
|
|
651
|
-
if (remoteJidAlt === jidInput && remoteJid.endsWith("@lid")) {
|
|
652
|
-
return remoteJid
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
} catch (e) {
|
|
656
|
-
console.error('Gagal ambil group metadata:', e.message);
|
|
657
|
-
return jidInput;
|
|
658
|
-
}
|
|
659
|
-
},
|
|
660
|
-
});
|
|
661
|
-
};
|
|
681
|
+
});
|
|
682
|
+
};
|