@awangxcode/qiro-baileys 7.0.0-rc20 → 7.0.0-rc22

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.
@@ -0,0 +1,275 @@
1
+ /*
2
+ ⌬═════════════════════⌬
3
+ ┇
4
+ ┇ ▬▬▬▬▬▬▬▬ ஐஐ ▬▬▬▬▬▬▬▬
5
+ ┇ ----- 🥳 𝗪𝗘𝗟𝗖𝗢𝗠𝗘 𝗕𝗥𝗢𝗞 🙌 -----
6
+ ┇ ▬▬▬▬▬▬▬▬ ஐஐ ▬▬▬▬▬▬▬▬
7
+ ┇
8
+ ┇
9
+ ┇ █▀█ █ █▀█ █▀█ ▄▀█ █
10
+ ┇ █ █ █ █▀▄ █▄█ █▀█ █
11
+ ┇ ▀█ --𝗤--𝗜--𝗥--𝗢------𝗔--𝗜----
12
+ ┇
13
+ ┇ ❏ ───────────────── ❏
14
+ ┇ ✧・゚ 💬 𝗜𝗡𝗙𝗢𝗥𝗠𝗔𝗧𝗜𝗢𝗡 💬 ゚・✧
15
+ ┇ ❏ ───────────────── ❏
16
+ ┇ › ୨୧ Developer : AXCODE iD - AwangXcode
17
+ ┇ › ୨୧ Website : awangofc.my.id
18
+ ┇ › ୨୧ WhatsApp : wa.me/556184127506
19
+ ┇
20
+ ┇ ✦ ───────────────── ✦
21
+ ┇ ✧・゚ ⛔ 𝗗𝗜𝗟𝗔𝗥𝗔𝗡𝗚 𝗞𝗘𝗥𝗔𝗦 ⛔ ゚・✧
22
+ ┇ ✦ ───────────────── ✦
23
+ ┇ › ✎ Dilarang Hapus Creadit SC
24
+ ┇ › ✎ Dilarang Jual-Beli Script Ini
25
+ ┇ › ✎ Dilarang Ngaku Sebagai Dev Qiro
26
+ ┇ › ✎ Jangan Ganti Baileys ya Brok!!
27
+ ┇
28
+ ┇ ♡ ───────────────── ♡
29
+ ┇ ✧・゚ 🌸 𝗜𝗭𝗜𝗡 & 𝗦𝗬𝗔𝗥𝗔𝗧 🌸 ゚・✧
30
+ ┇ ♡ ───────────────── ♡
31
+ ┇ › ○ Bebas Kembangin dan Recode SC
32
+ ┇ › ○ Bebas Modif dan Tambah Fitur
33
+ ┇ › ○ Bebas Share Ke Teman / Group
34
+ ┇ › ○ Wajib Izin & Cantumin Creadit
35
+ ┇ › ○ Hargai Karya Orang Anjing!!!!
36
+ ┇
37
+ ┇ ⚠ ───────────────── ⚠
38
+ ┇ ✧・゚ 📢 𝗖𝗔𝗧𝗔𝗧𝗔𝗡 & 𝗟𝗔𝗣𝗢𝗥𝗔𝗡 📢 ゚・✧
39
+ ┇ ⚠ ───────────────── ⚠
40
+ ┇ › Jika menemukan yang melanggar
41
+ ┇ › aturan di atas, segera laporkan
42
+ ┇ › via WhatsApp yang tertera
43
+ ┇
44
+ ┇ › sertakan bukti Screenshot / Link
45
+ ┇ › agar cepat kami tindak lanjuti!!
46
+ ┇ ╺╺╺╺╺╺╺╺╺╺╺╺╺╺╺✧˖°.
47
+ ┇
48
+ ┇ ║▌│█║▌│ █║▌│█│║▌
49
+ ┇ ♡ 𝗤𝗜𝗥𝗢 - 𝗔𝗜 | 𝟮𝟬𝟮𝟲 ♡
50
+ ┇
51
+ ⌬═════════════════════⌬
52
+ */
53
+
54
+ import axios from 'axios'
55
+ import { generateWAMessageFromContent, prepareWAMessageMedia, proto } from '@awangxcode/qiro-baileys'
56
+
57
+ function buildCarouselButton(button = {}) {
58
+ const type = String(button.type || 'quick_reply').toLowerCase()
59
+
60
+ if (type === 'cta_url') {
61
+ return {
62
+ name: 'cta_url',
63
+ buttonParamsJson: JSON.stringify({
64
+ display_text: button.text || '🌐 Buka Link',
65
+ url: button.url || '',
66
+ merchant_url: button.merchantUrl || button.url || ''
67
+ })
68
+ }
69
+ }
70
+
71
+ if (type === 'cta_copy') {
72
+ return {
73
+ name: 'cta_copy',
74
+ buttonParamsJson: JSON.stringify({
75
+ display_text: button.text || '📋 Salin',
76
+ id: button.id || 'copy_code',
77
+ copy_code: String(button.copyCode || '')
78
+ })
79
+ }
80
+ }
81
+
82
+ return {
83
+ name: 'quick_reply',
84
+ buttonParamsJson: JSON.stringify({
85
+ display_text: button.text || 'Pilih',
86
+ id: button.id || ''
87
+ })
88
+ }
89
+ }
90
+
91
+ async function prepareCarouselMedia(conn, imageSource) {
92
+ if (!imageSource) throw new Error('Setiap card carousel wajib memiliki image')
93
+
94
+ let image
95
+
96
+ if (Buffer.isBuffer(imageSource)) {
97
+ image = imageSource
98
+ } else if (typeof imageSource === 'string') {
99
+ const { data } = await axios.get(imageSource, {
100
+ responseType: 'arraybuffer',
101
+ timeout: 15000,
102
+ maxContentLength: 12 * 1024 * 1024,
103
+ maxBodyLength: 12 * 1024 * 1024,
104
+ maxRedirects: 5,
105
+ headers: {
106
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/133.0.0.0 Safari/537.36',
107
+ Accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/jpeg,image/png,*/*;q=0.8',
108
+ Referer: 'https://www.pinterest.com/'
109
+ },
110
+ validateStatus: status => status >= 200 && status < 400
111
+ })
112
+ image = Buffer.from(data)
113
+ } else if (imageSource && typeof imageSource.url === 'string') {
114
+ const { data } = await axios.get(imageSource.url, {
115
+ responseType: 'arraybuffer',
116
+ timeout: 15000,
117
+ maxContentLength: 12 * 1024 * 1024,
118
+ maxBodyLength: 12 * 1024 * 1024,
119
+ maxRedirects: 5,
120
+ headers: {
121
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/133.0.0.0 Safari/537.36',
122
+ Accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/jpeg,image/png,*/*;q=0.8',
123
+ Referer: 'https://www.pinterest.com/'
124
+ },
125
+ validateStatus: status => status >= 200 && status < 400
126
+ })
127
+ image = Buffer.from(data)
128
+ } else {
129
+ throw new Error('image carousel harus Buffer, URL, atau { url }')
130
+ }
131
+
132
+ if (!image?.length) throw new Error('Gambar carousel kosong')
133
+
134
+ return prepareWAMessageMedia(
135
+ { image },
136
+ { upload: conn.waUploadToServer }
137
+ )
138
+ }
139
+
140
+ function buildContextInfo(quoted, extra = {}) {
141
+ const contextInfo = { ...extra }
142
+
143
+ if (quoted?.key && quoted?.message) {
144
+ contextInfo.stanzaId = quoted.key.id
145
+ contextInfo.participant = quoted.key.participant || quoted.key.remoteJid
146
+ contextInfo.quotedMessage = quoted.message
147
+ contextInfo.remoteJid = quoted.key.remoteJid
148
+ contextInfo.fromMe = Boolean(quoted.key.fromMe)
149
+ }
150
+
151
+ return contextInfo
152
+ }
153
+
154
+ function buildAdditionalNodes(jid) {
155
+ const nodes = []
156
+ if (!String(jid || '').endsWith('@g.us')) {
157
+ nodes.push({
158
+ tag: 'bot',
159
+ attrs: { biz_bot: '1' }
160
+ })
161
+ }
162
+ nodes.push({
163
+ tag: 'biz',
164
+ attrs: {},
165
+ content: [
166
+ {
167
+ tag: 'interactive',
168
+ attrs: { type: 'native_flow', v: '1' },
169
+ content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }]
170
+ }
171
+ ]
172
+ })
173
+ return nodes
174
+ }
175
+
176
+ export async function sendCarousel(
177
+ conn,
178
+ jid,
179
+ {
180
+ text = '',
181
+ footer = '',
182
+ cards = [],
183
+ quoted,
184
+ contextInfo: extra = {}
185
+ } = {}
186
+ ) {
187
+ if (!Array.isArray(cards) || cards.length < 2) {
188
+ throw new Error('Carousel minimal membutuhkan 2 card')
189
+ }
190
+
191
+ const prepared = new Array(cards.length)
192
+ let cursor = 0
193
+ const workers = Math.min(4, cards.length)
194
+
195
+ const worker = async () => {
196
+ while (true) {
197
+ const index = cursor++
198
+ if (index >= cards.length) return
199
+ const card = cards[index]
200
+ try {
201
+ const media = await prepareCarouselMedia(conn, card.image)
202
+ const buttons = (card.buttons || []).map(buildCarouselButton)
203
+ if (!buttons.length || !media?.imageMessage) continue
204
+ prepared[index] = proto.Message.InteractiveMessage.fromObject({
205
+ header: proto.Message.InteractiveMessage.Header.fromObject({
206
+ title: card.title || '',
207
+ hasMediaAttachment: true,
208
+ imageMessage: media.imageMessage
209
+ }),
210
+ body: proto.Message.InteractiveMessage.Body.fromObject({
211
+ text: card.body || ''
212
+ }),
213
+ footer: proto.Message.InteractiveMessage.Footer.fromObject({
214
+ text: card.footer || ''
215
+ }),
216
+ nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
217
+ buttons,
218
+ messageParamsJson: '',
219
+ messageVersion: 1
220
+ })
221
+ })
222
+ } catch {}
223
+ }
224
+ }
225
+
226
+ await Promise.all(Array.from({ length: workers }, worker))
227
+ const carouselCards = prepared.filter(Boolean)
228
+
229
+ if (carouselCards.length < 2) {
230
+ throw new Error('Tidak cukup gambar yang dapat diproses untuk carousel')
231
+ }
232
+
233
+ const contextInfo = buildContextInfo(quoted, extra)
234
+ const interactiveMsg = proto.Message.InteractiveMessage.fromObject({
235
+ body: { text },
236
+ footer: { text: footer },
237
+ header: {
238
+ title: '',
239
+ subtitle: '',
240
+ hasMediaAttachment: false
241
+ },
242
+ carouselMessage: proto.Message.InteractiveMessage.CarouselMessage.fromObject({
243
+ cards: carouselCards,
244
+ messageVersion: 1,
245
+ carouselCardType: 1
246
+ }),
247
+ ...(Object.keys(contextInfo).length ? { contextInfo } : {})
248
+ })
249
+
250
+ const generatedMessage = generateWAMessageFromContent(
251
+ jid,
252
+ {
253
+ viewOnceMessage: {
254
+ message: {
255
+ messageContextInfo: {
256
+ deviceListMetadata: {},
257
+ deviceListMetadataVersion: 2
258
+ },
259
+ interactiveMessage: interactiveMsg
260
+ }
261
+ }
262
+ },
263
+ {
264
+ quoted,
265
+ userJid: conn.user?.id || jid
266
+ }
267
+ )
268
+
269
+ return conn.relayMessage(jid, generatedMessage.message, {
270
+ messageId: generatedMessage.key.id,
271
+ additionalNodes: buildAdditionalNodes(jid)
272
+ })
273
+ }
274
+
275
+ export default { sendCarousel }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@awangxcode/qiro-baileys",
3
3
  "type": "module",
4
- "version": "7.0.0-rc20",
4
+ "version": "7.0.0-rc22",
5
5
  "description": "Unofficial package based on WhiskeySockets/Baileys v7.0.0-rc14. Not affiliated with the upstream maintainers.",
6
6
  "keywords": [
7
7
  "whatsapp",
@@ -17,17 +17,12 @@
17
17
  "WAProto/**/*",
18
18
  "engine-requirements.js",
19
19
  "README.md",
20
- "QIRO-BAILEYS-RC16.md",
21
- "QIRO-BAILEYS-RC17.md",
22
- "QIRO-BAILEYS-RC18.md",
23
- "QIRO-BAILEYS-RC19.md",
24
- "THIRD_PARTY_NOTICES.md",
25
- "QIRO-BAILEYS-RC20.md"
20
+ "THIRD_PARTY_NOTICES.md"
26
21
  ],
27
22
  "scripts": {
28
23
  "build:all": "npm run build && npm run build:docs",
29
24
  "build:docs": "typedoc",
30
- "build": "tsc -P tsconfig.build.json && tsc-esm-fix --tsconfig=tsconfig.build.json --ext=.js",
25
+ "build": "tsc -P tsconfig.build.json && tsc-esm-fix --tsconfig=tsconfig.build.json --ext=.js && node ./scripts/copy-qiro-extensions.mjs",
31
26
  "changelog:last": "conventional-changelog -p angular -r 2",
32
27
  "changelog:preview": "conventional-changelog -p angular -u",
33
28
  "changelog:update": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
@@ -48,6 +43,8 @@
48
43
  "@cacheable/node-cache": "^1.4.0",
49
44
  "@hapi/boom": "^9.1.3",
50
45
  "async-mutex": "^0.5.0",
46
+ "axios": "^1.18.1",
47
+ "fluent-ffmpeg": "^2.1.3",
51
48
  "libsignal": "^6.0.0",
52
49
  "long": "^5.0.0",
53
50
  "lru-cache": "^11.1.0",