@pontalabs/baileys 1.2.3 → 1.2.4
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/README.md +103 -1
- package/lib/Socket/messages-send.js +57 -8
- package/lib/Utils/mbuilder.d.ts +9 -3
- package/lib/Utils/mbuilder.js +25 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -621,7 +621,7 @@ await sock.sendMessage(jid, {
|
|
|
621
621
|
|
|
622
622
|
Urutannya menjadi `Build 1 → tunggu 1 detik → Build 2 → tunggu 1 detik → Build 3`.
|
|
623
623
|
|
|
624
|
-
Tanpa `buildDelay`,
|
|
624
|
+
Tanpa `buildDelay`, item Rich AI tetap digabung menjadi **satu Rich AI message**. Jika `items` berisi `build.button()`, `build.buttonV2()`, atau `build.carousel()`, item interactive dikirim sebagai message native-flow tersendiri karena bukan Rich AI primitive.
|
|
625
625
|
|
|
626
626
|
> `buildDelay` hanya berlaku untuk `items`. Nilai dalam milidetik harus lebih besar dari `0`.
|
|
627
627
|
|
|
@@ -629,6 +629,9 @@ Tanpa `buildDelay`, perilaku `items` lama tetap dipakai: semua item digabung men
|
|
|
629
629
|
|
|
630
630
|
| Factory | Contoh | Hasil |
|
|
631
631
|
| --- | --- | --- |
|
|
632
|
+
| `build.button()` | `build.button().addReply('OK', 'ok')` | Native Flow buttons |
|
|
633
|
+
| `build.buttonV2()` | `build.buttonV2().addButton('OK')` | Buttons V2 |
|
|
634
|
+
| `build.carousel()` | `build.carousel().addCard(card)` | Interactive carousel |
|
|
632
635
|
| `build.richText(text)` | `build.richText('Halo')` | Text |
|
|
633
636
|
| `build.richFOAText(text)` | `build.richFOAText('Halo')` | FOA text |
|
|
634
637
|
| `build.richHtml(html)` | `build.richHtml('<html>...</html>')` | HTML WebView |
|
|
@@ -646,6 +649,105 @@ Tanpa `buildDelay`, perilaku `items` lama tetap dipakai: semua item digabung men
|
|
|
646
649
|
| `build.richFooterAction(data)` | `build.richFooterAction({...})` | Footer action |
|
|
647
650
|
| `build.richSuggest(value)` | `build.richSuggest('Lanjutkan')` | Suggestion |
|
|
648
651
|
|
|
652
|
+
#### 🧩 Interactive Builder — Button, ButtonV2 & Carousel
|
|
653
|
+
|
|
654
|
+
Builder interactive dari `mbuilder.js` juga tersedia langsung di namespace `build` dan **tidak membutuhkan `sock` saat dibuat**. Pesannya tetap dikirim melalui `sock.sendMessage()`.
|
|
655
|
+
|
|
656
|
+
##### Native Flow — `build.button()`
|
|
657
|
+
|
|
658
|
+
```js
|
|
659
|
+
const button = build.button()
|
|
660
|
+
.setTitle('Menu')
|
|
661
|
+
.setBody('Pilih salah satu')
|
|
662
|
+
.setFooter('PontaLabs')
|
|
663
|
+
.addReply('Halo', 'hello')
|
|
664
|
+
.addUrl('Website', 'https://example.com')
|
|
665
|
+
.addCopy('Copy ID', 'ABC123')
|
|
666
|
+
|
|
667
|
+
await sock.sendMessage(jid, {
|
|
668
|
+
items: [button]
|
|
669
|
+
})
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
Semua method `Button` dari builder asli tetap tersedia, termasuk:
|
|
673
|
+
|
|
674
|
+
- `setTitle()` / `setSubtitle()` / `setBody()` / `setFooter()`
|
|
675
|
+
- `setContextInfo()` / `addPayload()`
|
|
676
|
+
- `setImage()` / `setDocument()` / `setMedia()`
|
|
677
|
+
- `clearButtons()` / `setParams()` / `addButton()`
|
|
678
|
+
- `addSelection()` / `makeSection()` / `makeRow()`
|
|
679
|
+
- `addReply()` / `addCall()` / `addReminder()` / `addCancelReminder()`
|
|
680
|
+
- `addAddress()` / `addLocation()` / `addUrl()` / `addCopy()`
|
|
681
|
+
|
|
682
|
+
##### ButtonV2 — `build.buttonV2()`
|
|
683
|
+
|
|
684
|
+
```js
|
|
685
|
+
const buttons = build.buttonV2()
|
|
686
|
+
.setBody('Pilih aksi')
|
|
687
|
+
.setFooter('PontaLabs')
|
|
688
|
+
.addButton('Yes')
|
|
689
|
+
.addButton('No')
|
|
690
|
+
|
|
691
|
+
await sock.sendMessage(jid, {
|
|
692
|
+
items: [buttons]
|
|
693
|
+
})
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
Method yang tersedia dari `ButtonV2` antara lain `addButton()`, `addRawButton()`, `setRawThumbnail()`, `setThumbnail()`, `setMedia()`, serta semua setter dari `BaseBuilder`.
|
|
697
|
+
|
|
698
|
+
##### Carousel — `build.carousel()`
|
|
699
|
+
|
|
700
|
+
```js
|
|
701
|
+
const carousel = build.carousel()
|
|
702
|
+
.setBody('Pilih produk')
|
|
703
|
+
.setFooter('PontaLabs')
|
|
704
|
+
.addCard({
|
|
705
|
+
header: {
|
|
706
|
+
hasMediaAttachment: true,
|
|
707
|
+
imageMessage: imageMessage
|
|
708
|
+
},
|
|
709
|
+
body: { text: 'Produk A' },
|
|
710
|
+
footer: { text: 'Rp 10.000' },
|
|
711
|
+
nativeFlowMessage: {
|
|
712
|
+
messageParamsJson: '{}',
|
|
713
|
+
buttons: [{
|
|
714
|
+
name: 'quick_reply',
|
|
715
|
+
buttonParamsJson: JSON.stringify({
|
|
716
|
+
display_text: 'Pilih',
|
|
717
|
+
id: 'product_a'
|
|
718
|
+
})
|
|
719
|
+
}]
|
|
720
|
+
}
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
await sock.sendMessage(jid, {
|
|
724
|
+
items: [carousel]
|
|
725
|
+
})
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
`addCard()` menerima satu card atau array card. Card harus memiliki `header.hasMediaAttachment = true`, sama seperti builder aslinya.
|
|
729
|
+
|
|
730
|
+
##### ⏱️ Interactive + `buildDelay`
|
|
731
|
+
|
|
732
|
+
Semua builder dapat dicampur. Jika `buildDelay` dipasang, setiap item dikirim sebagai pesan terpisah dengan jeda yang sama, termasuk Button, ButtonV2, Carousel, dan Rich AI:
|
|
733
|
+
|
|
734
|
+
```js
|
|
735
|
+
await sock.sendMessage(jid, {
|
|
736
|
+
items: [
|
|
737
|
+
build.richText('Halo 👋'),
|
|
738
|
+
build.button().addReply('Lanjut', 'next'),
|
|
739
|
+
build.richHtml('<h1>WebView</h1>'),
|
|
740
|
+
build.buttonV2().addButton('OK'),
|
|
741
|
+
build.carousel().addCard(card)
|
|
742
|
+
],
|
|
743
|
+
buildDelay: 5000
|
|
744
|
+
})
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
Hasilnya: `Text → 5 detik → Button → 5 detik → WebView → 5 detik → ButtonV2 → 5 detik → Carousel`.
|
|
748
|
+
|
|
749
|
+
> `build.button()`, `build.buttonV2()`, dan `build.carousel()` adalah payload builders. Tidak perlu `send()` dan tidak perlu memasukkan `sock` ke factory. `sock.sendMessage()` tetap menjadi jalur pengiriman utama.
|
|
750
|
+
|
|
649
751
|
#### 🧩 Campur dengan shortcut lama
|
|
650
752
|
|
|
651
753
|
API lama **tetap dipertahankan**. Builder bisa dicampur dengan object Rich AI biasa di `items`.
|
|
@@ -14,6 +14,7 @@ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
|
14
14
|
import { makeNewsletterSocket } from './newsletter.js';
|
|
15
15
|
import kikyy from './dugong.js';
|
|
16
16
|
import { generateTableContent, generateTableContentV2, generateListContent, generateCodeBlockContent, generateCodeBlockContentV2, generateLinkContent, generateLinkContentV2, generateRichMessageContent, generateUnifiedResponseContent, captureUnifiedResponse, generateLatexContent, generateLatexImageContent, generateLatexInlineImageContent } from '../Utils/rich-message-utils.js';
|
|
17
|
+
import { Button, ButtonV2, Carousel } from '../Utils/mbuilder.js';
|
|
17
18
|
export const makeMessagesSocket = (config) => {
|
|
18
19
|
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount } = config;
|
|
19
20
|
const sock = makeNewsletterSocket(config);
|
|
@@ -1132,18 +1133,66 @@ export const makeMessagesSocket = (config) => {
|
|
|
1132
1133
|
sendMessage: sendMessageImpl = async (jid, content, options = {}) => {
|
|
1133
1134
|
const userJid = authState.creds.me.id;
|
|
1134
1135
|
|
|
1135
|
-
// `
|
|
1136
|
-
//
|
|
1137
|
-
//
|
|
1138
|
-
|
|
1136
|
+
// `items` may contain Rich AI build descriptors as well as the
|
|
1137
|
+
// interactive builders exported by mbuilder.js. Rich AI items can
|
|
1138
|
+
// stay grouped when no delay is requested; interactive builders
|
|
1139
|
+
// are always sent as their own native-flow message because they
|
|
1140
|
+
// are not valid Rich AI primitives.
|
|
1141
|
+
if (content && !Array.isArray(jid) && Array.isArray(content.items) && content.items.length > 0) {
|
|
1142
|
+
const items = content.items;
|
|
1139
1143
|
const buildDelay = Number(options.buildDelay ?? content.buildDelay ?? 0);
|
|
1140
|
-
|
|
1144
|
+
const hasDelay = Number.isFinite(buildDelay) && buildDelay > 0;
|
|
1145
|
+
const isInteractiveBuilder = (item) => item instanceof Button || item instanceof ButtonV2 || item instanceof Carousel;
|
|
1146
|
+
const hasInteractiveBuilder = items.some(isInteractiveBuilder);
|
|
1147
|
+
|
|
1148
|
+
if (hasDelay || hasInteractiveBuilder) {
|
|
1141
1149
|
const sendOptions = { ...options };
|
|
1142
1150
|
delete sendOptions.buildDelay;
|
|
1151
|
+
delete sendOptions.additionalNodes;
|
|
1143
1152
|
const results = [];
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1153
|
+
|
|
1154
|
+
const sendInteractiveBuilder = async (builder) => {
|
|
1155
|
+
// Builder instances are intentionally socket-less when
|
|
1156
|
+
// created through build.button()/buttonV2()/carousel().
|
|
1157
|
+
// Bind only the upload capability needed while building
|
|
1158
|
+
// media; the actual send still uses this socket's
|
|
1159
|
+
// relayMessage path, exactly like the native sendMessage
|
|
1160
|
+
// implementation.
|
|
1161
|
+
builder.setClient({ waUploadToServer });
|
|
1162
|
+
const msg = await builder.build(jid, sendOptions);
|
|
1163
|
+
await relayMessage(msg.key.remoteJid, msg.message, {
|
|
1164
|
+
messageId: msg.key.id,
|
|
1165
|
+
additionalNodes: [
|
|
1166
|
+
{
|
|
1167
|
+
tag: 'biz',
|
|
1168
|
+
attrs: {},
|
|
1169
|
+
content: [
|
|
1170
|
+
{
|
|
1171
|
+
tag: 'interactive',
|
|
1172
|
+
attrs: { type: 'native_flow', v: '1' },
|
|
1173
|
+
content: [{ tag: 'native_flow', attrs: { v: '9', name: 'mixed' } }],
|
|
1174
|
+
},
|
|
1175
|
+
],
|
|
1176
|
+
},
|
|
1177
|
+
...(options.additionalNodes || []),
|
|
1178
|
+
],
|
|
1179
|
+
...sendOptions,
|
|
1180
|
+
});
|
|
1181
|
+
return msg;
|
|
1182
|
+
};
|
|
1183
|
+
|
|
1184
|
+
for (let index = 0; index < items.length; index++) {
|
|
1185
|
+
if (index > 0 && hasDelay) await delay(buildDelay);
|
|
1186
|
+
|
|
1187
|
+
const item = items[index];
|
|
1188
|
+
if (isInteractiveBuilder(item)) {
|
|
1189
|
+
results.push(await sendInteractiveBuilder(item));
|
|
1190
|
+
} else {
|
|
1191
|
+
// Keep the same Rich AI normalization path used by
|
|
1192
|
+
// the regular shortcut, preventing build descriptors
|
|
1193
|
+
// from reaching prepareWAMessageMedia().
|
|
1194
|
+
results.push(await sendMessageImpl(jid, { items: [item] }, sendOptions));
|
|
1195
|
+
}
|
|
1147
1196
|
}
|
|
1148
1197
|
return results;
|
|
1149
1198
|
}
|
package/lib/Utils/mbuilder.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const VERSION: string;
|
|
2
|
-
export declare class Button { constructor(client
|
|
3
|
-
export declare class ButtonV2 { constructor(client
|
|
4
|
-
export declare class Carousel { constructor(client
|
|
2
|
+
export declare class Button { constructor(client?: any, options?: any); loadFrom(data: any): this; build(jid: string, options?: any): any; send(jid: string, options?: any): Promise<any>; [key: string]: any; }
|
|
3
|
+
export declare class ButtonV2 { constructor(client?: any, options?: any); loadFrom(data: any): this; build(jid: string, options?: any): any; send(jid: string, options?: any): Promise<any>; [key: string]: any; }
|
|
4
|
+
export declare class Carousel { constructor(client?: any, options?: any); loadFrom(data: any): this; build(jid: string, options?: any): any; send(jid: string, options?: any): Promise<any>; [key: string]: any; }
|
|
5
5
|
export declare class AIRich {
|
|
6
6
|
constructor(client: any, options?: { dynamic?: boolean; unsupportedTypeAlert?: boolean });
|
|
7
7
|
loadFrom(msg: any): this;
|
|
@@ -38,6 +38,12 @@ export declare class AIRich {
|
|
|
38
38
|
export declare class Toolkit { [key: string]: any; }
|
|
39
39
|
export declare const build: {
|
|
40
40
|
AIRich: (client: any, options?: any) => AIRich;
|
|
41
|
+
button: (client?: any) => Button;
|
|
42
|
+
buttonV2: (client?: any) => ButtonV2;
|
|
43
|
+
carousel: (client?: any) => Carousel;
|
|
44
|
+
Button: (client?: any) => Button;
|
|
45
|
+
ButtonV2: (client?: any) => ButtonV2;
|
|
46
|
+
Carousel: (client?: any) => Carousel;
|
|
41
47
|
richText: (text: string) => any;
|
|
42
48
|
richFOAText: (text: string) => any;
|
|
43
49
|
richHtml: (html: string) => any;
|
package/lib/Utils/mbuilder.js
CHANGED
|
@@ -557,11 +557,8 @@ class BaseBuilder {
|
|
|
557
557
|
class Button extends BaseBuilder {
|
|
558
558
|
#client;
|
|
559
559
|
|
|
560
|
-
constructor(client) {
|
|
560
|
+
constructor(client = null) {
|
|
561
561
|
super();
|
|
562
|
-
if (!client) {
|
|
563
|
-
throw new Error('Socket is required');
|
|
564
|
-
}
|
|
565
562
|
this.#client = client;
|
|
566
563
|
|
|
567
564
|
this._buttons = [];
|
|
@@ -571,6 +568,11 @@ class Button extends BaseBuilder {
|
|
|
571
568
|
this._params = {};
|
|
572
569
|
}
|
|
573
570
|
|
|
571
|
+
setClient(client) {
|
|
572
|
+
this.#client = client;
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
|
|
574
576
|
loadFrom(msg) {
|
|
575
577
|
if (!msg) throw new Error('interactiveMessage needed');
|
|
576
578
|
if (!msg.interactiveMessage) throw new Error('interactiveMessage not found');
|
|
@@ -891,18 +893,19 @@ class Button extends BaseBuilder {
|
|
|
891
893
|
class ButtonV2 extends BaseBuilder {
|
|
892
894
|
#client;
|
|
893
895
|
|
|
894
|
-
constructor(client) {
|
|
896
|
+
constructor(client = null) {
|
|
895
897
|
super();
|
|
896
|
-
if (!client) {
|
|
897
|
-
throw new Error('Socket is required');
|
|
898
|
-
}
|
|
899
|
-
|
|
900
898
|
this.#client = client;
|
|
901
899
|
this._image;
|
|
902
900
|
this._data;
|
|
903
901
|
this._buttons = [];
|
|
904
902
|
}
|
|
905
903
|
|
|
904
|
+
setClient(client) {
|
|
905
|
+
this.#client = client;
|
|
906
|
+
return this;
|
|
907
|
+
}
|
|
908
|
+
|
|
906
909
|
loadFrom(msg) {
|
|
907
910
|
if (!msg) throw new Error('buttonsMessage needed');
|
|
908
911
|
if (!msg.buttonsMessage) throw new Error('buttonsMessage not found');
|
|
@@ -1059,16 +1062,17 @@ class ButtonV2 extends BaseBuilder {
|
|
|
1059
1062
|
class Carousel extends BaseBuilder {
|
|
1060
1063
|
#client;
|
|
1061
1064
|
|
|
1062
|
-
constructor(client) {
|
|
1065
|
+
constructor(client = null) {
|
|
1063
1066
|
super();
|
|
1064
|
-
if (!client) {
|
|
1065
|
-
throw new Error('Socket is required');
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
1067
|
this.#client = client;
|
|
1069
1068
|
this._cards = [];
|
|
1070
1069
|
}
|
|
1071
1070
|
|
|
1071
|
+
setClient(client) {
|
|
1072
|
+
this.#client = client;
|
|
1073
|
+
return this;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1072
1076
|
loadFrom(msg) {
|
|
1073
1077
|
if (!msg) throw new Error('interactiveMessage needed');
|
|
1074
1078
|
if (!msg.interactiveMessage) throw new Error('interactiveMessage not found');
|
|
@@ -3201,6 +3205,13 @@ class AIRich extends BaseBuilder {
|
|
|
3201
3205
|
*/
|
|
3202
3206
|
const build = {
|
|
3203
3207
|
AIRich: (client, options) => new AIRich(client, options),
|
|
3208
|
+
button: (client = null) => new Button(client),
|
|
3209
|
+
buttonV2: (client = null) => new ButtonV2(client),
|
|
3210
|
+
carousel: (client = null) => new Carousel(client),
|
|
3211
|
+
// Class aliases for developers who prefer constructor-style naming.
|
|
3212
|
+
Button: (client = null) => new Button(client),
|
|
3213
|
+
ButtonV2: (client = null) => new ButtonV2(client),
|
|
3214
|
+
Carousel: (client = null) => new Carousel(client),
|
|
3204
3215
|
richText: (text) => ({ richText: text }),
|
|
3205
3216
|
richFOAText: (text) => ({ richFOAText: text }),
|
|
3206
3217
|
richCode: (code, language = 'javascript') => ({ richCode: code, language }),
|
package/package.json
CHANGED