@nuiisweety/baileys 0.1.11 โ 0.1.12
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 +232 -24
- package/README.md.bak +231 -23
- package/lib/Utils/messages.js +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*Fork dari [`@whiskeysockets/baileys`](https://github.com/WhiskeySockets/Baileys) v7.0.0-rc11*
|
|
8
8
|
*dikembangkan dengan sepenuh hati oleh **NuiiS4TORU***
|
|
9
9
|
|
|
10
|
-
[](https://www.npmjs.com/package/@nuiisweety/baileys)
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
[](https://github.com/WhiskeySockets/Baileys)
|
|
13
13
|
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
[Secure Meta Label](#secure-meta-service-label)
|
|
73
73
|
|
|
74
74
|
๐๏ธ **Interactive** โ
|
|
75
|
+
[Buttons Location Header](#buttons-dengan-location-header-buttonsmessage-langsung) ยท
|
|
75
76
|
[Buttons](#buttons) ยท
|
|
76
77
|
[List Message](#list-message) ยท
|
|
77
78
|
[Template Buttons](#template-buttons) ยท
|
|
@@ -927,11 +928,85 @@ await sock.sendMessage(jid, {
|
|
|
927
928
|
|
|
928
929
|
---
|
|
929
930
|
|
|
931
|
+
<details>
|
|
932
|
+
<summary>๐ Buttons dengan Location Header (buttonsMessage langsung)</summary>
|
|
933
|
+
|
|
934
|
+
Kirim tombol menggunakan `buttonsMessage` secara langsung โ berguna untuk header tipe **Location** (`headerType: 6`) yang tidak bisa dibuat lewat shorthand `buttons`.
|
|
935
|
+
|
|
936
|
+
```js
|
|
937
|
+
// Tombol dengan header lokasi (headerType 6)
|
|
938
|
+
await sock.sendMessage(jid, {
|
|
939
|
+
buttonsMessage: {
|
|
940
|
+
locationMessage: {
|
|
941
|
+
degreesLatitude: 0,
|
|
942
|
+
degreesLongitude: 0,
|
|
943
|
+
name: 'NuiiSweety',
|
|
944
|
+
address: 'NuiiSweety Bot',
|
|
945
|
+
jpegThumbnail: './src/img/menu.jpg' // path file, URL, atau Buffer
|
|
946
|
+
},
|
|
947
|
+
contentText: 'Pilih menu di bawah ini',
|
|
948
|
+
footerText: 'Powered by @nuiisweety/baileys',
|
|
949
|
+
buttons: [
|
|
950
|
+
{ buttonId: 'allmenu', buttonText: { displayText: 'All Menu' }, type: 1 }
|
|
951
|
+
],
|
|
952
|
+
headerType: 6
|
|
953
|
+
}
|
|
954
|
+
})
|
|
955
|
+
|
|
956
|
+
// Dengan quoted (reply ke pesan tertentu)
|
|
957
|
+
await sock.sendMessage(jid, {
|
|
958
|
+
buttonsMessage: {
|
|
959
|
+
locationMessage: {
|
|
960
|
+
degreesLatitude: -6.2,
|
|
961
|
+
degreesLongitude: 106.8,
|
|
962
|
+
name: 'Menu Bot',
|
|
963
|
+
address: 'NuiiSweety',
|
|
964
|
+
jpegThumbnail: './src/img/menu.jpg'
|
|
965
|
+
},
|
|
966
|
+
contentText: 'Halo! Ini menu utama bot',
|
|
967
|
+
footerText: 'NuiiSweety Bot',
|
|
968
|
+
buttons: [
|
|
969
|
+
{ buttonId: 'menu1', buttonText: { displayText: '๐ฑ Menu Utama' }, type: 1 },
|
|
970
|
+
{ buttonId: 'help', buttonText: { displayText: 'โ Bantuan' }, type: 1 }
|
|
971
|
+
],
|
|
972
|
+
headerType: 6
|
|
973
|
+
}
|
|
974
|
+
}, { quoted: m })
|
|
975
|
+
|
|
976
|
+
// Header kosong (teks saja, tanpa media/lokasi) โ headerType 1
|
|
977
|
+
await sock.sendMessage(jid, {
|
|
978
|
+
buttonsMessage: {
|
|
979
|
+
contentText: 'Pilih opsi',
|
|
980
|
+
footerText: 'Bot Footer',
|
|
981
|
+
buttons: [
|
|
982
|
+
{ buttonId: 'yes', buttonText: { displayText: 'Ya' }, type: 1 },
|
|
983
|
+
{ buttonId: 'no', buttonText: { displayText: 'Tidak' }, type: 1 }
|
|
984
|
+
],
|
|
985
|
+
headerType: 1
|
|
986
|
+
}
|
|
987
|
+
})
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
> **Catatan `headerType`:**
|
|
991
|
+
> | Nilai | Tipe Header |
|
|
992
|
+
> |-------|-------------|
|
|
993
|
+
> | `1` | Teks (`contentText`) |
|
|
994
|
+
> | `2` | Gambar (`imageMessage`) |
|
|
995
|
+
> | `3` | Video (`videoMessage`) |
|
|
996
|
+
> | `4` | Dokumen (`documentMessage`) |
|
|
997
|
+
> | `6` | Lokasi (`locationMessage`) |
|
|
998
|
+
>
|
|
999
|
+
> `jpegThumbnail` pada `locationMessage` bisa berupa **path file lokal**, **URL**, atau **Buffer** โ otomatis diproses oleh Baileys.
|
|
1000
|
+
|
|
1001
|
+
</details>
|
|
1002
|
+
|
|
1003
|
+
---
|
|
1004
|
+
|
|
930
1005
|
<details>
|
|
931
1006
|
<summary>๐๏ธ Buttons</summary>
|
|
932
1007
|
|
|
933
1008
|
```js
|
|
934
|
-
// Teks dengan tombol
|
|
1009
|
+
// Teks dengan tombol (quick reply)
|
|
935
1010
|
await sock.sendMessage(jid, {
|
|
936
1011
|
text: 'Pilih salah satu',
|
|
937
1012
|
footer: 'Footer pesan',
|
|
@@ -953,7 +1028,28 @@ await sock.sendMessage(jid, {
|
|
|
953
1028
|
]
|
|
954
1029
|
})
|
|
955
1030
|
|
|
956
|
-
// Native flow button
|
|
1031
|
+
// Native flow button dalam buttons โ pakai name + paramsJson
|
|
1032
|
+
await sock.sendMessage(jid, {
|
|
1033
|
+
text: 'Pilih menu',
|
|
1034
|
+
buttons: [
|
|
1035
|
+
{
|
|
1036
|
+
name: 'single_select',
|
|
1037
|
+
text: 'Buka Menu',
|
|
1038
|
+
paramsJson: JSON.stringify({
|
|
1039
|
+
title: 'Buka Menu',
|
|
1040
|
+
sections: [{
|
|
1041
|
+
title: 'Kategori A',
|
|
1042
|
+
rows: [
|
|
1043
|
+
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
|
|
1044
|
+
{ id: 'row2', title: 'Item 2' }
|
|
1045
|
+
]
|
|
1046
|
+
}]
|
|
1047
|
+
})
|
|
1048
|
+
}
|
|
1049
|
+
]
|
|
1050
|
+
})
|
|
1051
|
+
|
|
1052
|
+
// Shorthand: sections langsung di button (otomatis jadi single_select)
|
|
957
1053
|
await sock.sendMessage(jid, {
|
|
958
1054
|
text: 'Pilih menu',
|
|
959
1055
|
buttons: [{
|
|
@@ -969,6 +1065,8 @@ await sock.sendMessage(jid, {
|
|
|
969
1065
|
})
|
|
970
1066
|
```
|
|
971
1067
|
|
|
1068
|
+
> **Field tombol:** gunakan `text` atau `buttonText` untuk label. Untuk quick reply gunakan `id`/`buttonId`. Untuk native flow gunakan `name` + `paramsJson`.
|
|
1069
|
+
|
|
972
1070
|
</details>
|
|
973
1071
|
|
|
974
1072
|
---
|
|
@@ -978,10 +1076,10 @@ await sock.sendMessage(jid, {
|
|
|
978
1076
|
|
|
979
1077
|
```js
|
|
980
1078
|
await sock.sendMessage(jid, {
|
|
981
|
-
text: 'Silakan pilih',
|
|
982
|
-
title: 'Judul List',
|
|
983
|
-
buttonText: 'Buka Daftar',
|
|
984
|
-
footer: 'Footer pesan',
|
|
1079
|
+
text: 'Silakan pilih', // โ description (isi pesan)
|
|
1080
|
+
title: 'Judul List', // โ title (judul di atas list)
|
|
1081
|
+
buttonText: 'Buka Daftar', // โ teks tombol pembuka
|
|
1082
|
+
footer: 'Footer pesan', // โ footerText
|
|
985
1083
|
sections: [
|
|
986
1084
|
{
|
|
987
1085
|
title: 'Bagian 1',
|
|
@@ -1000,6 +1098,8 @@ await sock.sendMessage(jid, {
|
|
|
1000
1098
|
})
|
|
1001
1099
|
```
|
|
1002
1100
|
|
|
1101
|
+
> **Trigger key:** `sections` (bukan `listMessage`). `listType` otomatis di-set ke `SINGLE_SELECT`. Field `text` di-map ke `description` (isi pesan), bukan judul โ gunakan `title` untuk judul list.
|
|
1102
|
+
|
|
1003
1103
|
</details>
|
|
1004
1104
|
|
|
1005
1105
|
---
|
|
@@ -1010,9 +1110,9 @@ await sock.sendMessage(jid, {
|
|
|
1010
1110
|
```js
|
|
1011
1111
|
// Teks
|
|
1012
1112
|
await sock.sendMessage(jid, {
|
|
1013
|
-
text: 'Pesan template',
|
|
1014
|
-
footer: 'Footer',
|
|
1015
|
-
id: 'template-unik',
|
|
1113
|
+
text: 'Pesan template', // โ hydratedContentText
|
|
1114
|
+
footer: 'Footer', // โ hydratedFooterText
|
|
1115
|
+
id: 'template-unik', // โ templateId (opsional, auto-generate jika tidak diisi)
|
|
1016
1116
|
templateButtons: [
|
|
1017
1117
|
{ id: 'btn1', text: 'Quick Reply' },
|
|
1018
1118
|
{ url: 'https://example.com', text: 'Kunjungi Website' },
|
|
@@ -1023,8 +1123,8 @@ await sock.sendMessage(jid, {
|
|
|
1023
1123
|
// Gambar sebagai header
|
|
1024
1124
|
await sock.sendMessage(jid, {
|
|
1025
1125
|
image: { url: 'https://example.com/img.jpg' },
|
|
1026
|
-
caption: 'Isi pesan',
|
|
1027
|
-
title: 'Judul',
|
|
1126
|
+
caption: 'Isi pesan', // โ hydratedContentText
|
|
1127
|
+
title: 'Judul', // โ hydratedTitleText (hanya aktif jika ada caption)
|
|
1028
1128
|
footer: 'Footer',
|
|
1029
1129
|
templateButtons: [
|
|
1030
1130
|
{ id: 'btn1', text: 'Klik Sini' },
|
|
@@ -1033,6 +1133,8 @@ await sock.sendMessage(jid, {
|
|
|
1033
1133
|
})
|
|
1034
1134
|
```
|
|
1035
1135
|
|
|
1136
|
+
> **Tipe tombol:** `{ id, text }` โ quick reply ยท `{ url, text }` โ URL button ยท `{ call, text }` โ call button. `text` atau `buttonText` keduanya diterima. Jika `id` tidak diisi, otomatis `template-<timestamp>`.
|
|
1137
|
+
|
|
1036
1138
|
</details>
|
|
1037
1139
|
|
|
1038
1140
|
---
|
|
@@ -1041,34 +1143,108 @@ await sock.sendMessage(jid, {
|
|
|
1041
1143
|
<summary>๐ Native Flow</summary>
|
|
1042
1144
|
|
|
1043
1145
|
```js
|
|
1044
|
-
//
|
|
1146
|
+
// Quick reply
|
|
1045
1147
|
await sock.sendMessage(jid, {
|
|
1046
1148
|
text: 'Pilih aksi',
|
|
1047
1149
|
footer: 'Footer pesan',
|
|
1048
1150
|
nativeFlow: [
|
|
1049
|
-
{
|
|
1050
|
-
{
|
|
1151
|
+
{ id: '1', text: 'Opsi 1' }, // id โ quick_reply
|
|
1152
|
+
{ id: '2', text: 'Opsi 2' }
|
|
1051
1153
|
]
|
|
1052
1154
|
})
|
|
1053
1155
|
|
|
1054
|
-
//
|
|
1156
|
+
// URL button
|
|
1157
|
+
await sock.sendMessage(jid, {
|
|
1158
|
+
text: 'Kunjungi kami',
|
|
1159
|
+
nativeFlow: [
|
|
1160
|
+
{ url: 'https://example.com', text: 'Buka Website' }
|
|
1161
|
+
]
|
|
1162
|
+
})
|
|
1163
|
+
|
|
1164
|
+
// Copy code button
|
|
1165
|
+
await sock.sendMessage(jid, {
|
|
1166
|
+
text: 'Kode promo kamu',
|
|
1167
|
+
nativeFlow: [
|
|
1168
|
+
{ copy: 'PROMO2025', text: 'Salin Kode' }
|
|
1169
|
+
]
|
|
1170
|
+
})
|
|
1171
|
+
|
|
1172
|
+
// Call button
|
|
1173
|
+
await sock.sendMessage(jid, {
|
|
1174
|
+
text: 'Hubungi kami',
|
|
1175
|
+
nativeFlow: [
|
|
1176
|
+
{ call: '+62812345678', text: 'Telepon Sekarang' }
|
|
1177
|
+
]
|
|
1178
|
+
})
|
|
1179
|
+
|
|
1180
|
+
// Single select (list dalam button)
|
|
1181
|
+
await sock.sendMessage(jid, {
|
|
1182
|
+
text: 'Pilih menu',
|
|
1183
|
+
nativeFlow: [
|
|
1184
|
+
{
|
|
1185
|
+
sections: [{
|
|
1186
|
+
title: 'Kategori A',
|
|
1187
|
+
rows: [
|
|
1188
|
+
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
|
|
1189
|
+
{ id: 'row2', title: 'Item 2' }
|
|
1190
|
+
]
|
|
1191
|
+
}],
|
|
1192
|
+
text: 'Buka Daftar'
|
|
1193
|
+
}
|
|
1194
|
+
]
|
|
1195
|
+
})
|
|
1196
|
+
|
|
1197
|
+
// Dengan icon pada tombol
|
|
1198
|
+
await sock.sendMessage(jid, {
|
|
1199
|
+
text: 'Pilih aksi',
|
|
1200
|
+
nativeFlow: [
|
|
1201
|
+
{ id: '1', text: 'Konfirmasi', icon: 'CHECK' },
|
|
1202
|
+
{ url: 'https://example.com', text: 'Buka', icon: 'LINK' }
|
|
1203
|
+
]
|
|
1204
|
+
})
|
|
1205
|
+
|
|
1206
|
+
// Gambar sebagai header โ WAJIB pakai image/video/document/location/product
|
|
1207
|
+
// jika tidak ada media valid โ throw Error: Invalid media type
|
|
1055
1208
|
await sock.sendMessage(jid, {
|
|
1056
1209
|
image: { url: 'https://example.com/img.jpg' },
|
|
1057
|
-
caption: 'Isi pesan',
|
|
1058
|
-
title: 'Judul',
|
|
1059
|
-
subtitle: 'Subjudul',
|
|
1210
|
+
caption: 'Isi pesan', // โ body.text
|
|
1211
|
+
title: 'Judul', // โ header.title
|
|
1212
|
+
subtitle: 'Subjudul', // โ header.subtitle
|
|
1060
1213
|
footer: 'Footer',
|
|
1061
1214
|
nativeFlow: [
|
|
1062
|
-
{
|
|
1215
|
+
{ id: '1', text: 'Tombol 1' }
|
|
1063
1216
|
]
|
|
1064
1217
|
})
|
|
1065
1218
|
|
|
1066
|
-
// Dengan audio footer
|
|
1219
|
+
// Dengan audio footer (menggantikan footer teks)
|
|
1067
1220
|
await sock.sendMessage(jid, {
|
|
1068
1221
|
text: 'Pesan dengan audio footer',
|
|
1069
1222
|
audioFooter: fs.readFileSync('audio.ogg'),
|
|
1070
1223
|
nativeFlow: [
|
|
1071
|
-
{
|
|
1224
|
+
{ id: '1', text: 'OK' }
|
|
1225
|
+
]
|
|
1226
|
+
})
|
|
1227
|
+
|
|
1228
|
+
// offerText โ tampil sebagai limited time offer banner
|
|
1229
|
+
await sock.sendMessage(jid, {
|
|
1230
|
+
text: 'Penawaran terbatas!',
|
|
1231
|
+
offerText: 'Diskon 50%',
|
|
1232
|
+
offerUrl: 'https://example.com/promo',
|
|
1233
|
+
offerCode: 'DISKON50',
|
|
1234
|
+
offerExpiration: 1800000000,
|
|
1235
|
+
nativeFlow: [
|
|
1236
|
+
{ id: 'claim', text: 'Klaim Sekarang' }
|
|
1237
|
+
]
|
|
1238
|
+
})
|
|
1239
|
+
|
|
1240
|
+
// optionText โ tombol-tombol masuk ke bottom sheet
|
|
1241
|
+
await sock.sendMessage(jid, {
|
|
1242
|
+
text: 'Pilih opsi',
|
|
1243
|
+
optionText: 'Lihat Semua Opsi',
|
|
1244
|
+
optionTitle: 'Daftar Pilihan',
|
|
1245
|
+
nativeFlow: [
|
|
1246
|
+
{ id: '1', text: 'Opsi A' },
|
|
1247
|
+
{ id: '2', text: 'Opsi B' }
|
|
1072
1248
|
]
|
|
1073
1249
|
})
|
|
1074
1250
|
|
|
@@ -1076,13 +1252,15 @@ await sock.sendMessage(jid, {
|
|
|
1076
1252
|
await sock.sendMessage(jid, {
|
|
1077
1253
|
text: 'Template interaktif',
|
|
1078
1254
|
nativeFlow: [
|
|
1079
|
-
{
|
|
1255
|
+
{ id: '1', text: 'Tombol' }
|
|
1080
1256
|
],
|
|
1081
1257
|
interactiveAsTemplate: true,
|
|
1082
1258
|
id: 'template-id-unik'
|
|
1083
1259
|
})
|
|
1084
1260
|
```
|
|
1085
1261
|
|
|
1262
|
+
> **Tipe tombol ditentukan otomatis** dari field yang ada: `id` โ quick_reply ยท `url` โ cta_url ยท `copy` โ cta_copy ยท `call` โ cta_call ยท `sections` โ single_select. Bisa juga pakai `name` + `paramsJson` langsung untuk kontrol penuh. `text` atau `buttonText` keduanya diterima. Field `icon` opsional (string uppercase, e.g. `'CHECK'`, `'LINK'`).
|
|
1263
|
+
|
|
1086
1264
|
</details>
|
|
1087
1265
|
|
|
1088
1266
|
---
|
|
@@ -1148,16 +1326,46 @@ await sock.sendMessage(['628xxx@s.whatsapp.net'], {
|
|
|
1148
1326
|
|
|
1149
1327
|
> Rich message menggunakan format `AIRichResponseMessage` yang tampil seperti respons AI di WhatsApp. Semua tipe di bawah bisa dipakai secara flat (field langsung) atau dikombinasikan via `richResponse: [...]`.
|
|
1150
1328
|
|
|
1329
|
+
> โ ๏ธ **Penting:** `contentText`, `headerText`, `footerText`, dan `disclaimerText` **bukan** trigger key โ artinya jika hanya field itu yang dikirim, pesan **tidak akan** diproses sebagai rich message dan akan menghasilkan **Error: Invalid media type**. Gunakan selalu minimal satu trigger key (`code`, `table`, `richImage`, `richVideo`, `richResponse`, dll), lalu kombinasikan dengan field teks di atas sebagai pelengkap.
|
|
1330
|
+
|
|
1151
1331
|
### โ๏ธ addText
|
|
1152
1332
|
|
|
1153
1333
|
Kirim teks markdown sebagai AI Rich Response. Mendukung hyperlink, citation, dan LaTeX inline.
|
|
1154
1334
|
|
|
1335
|
+
Karena `contentText` bukan trigger key, gunakan `richResponse: [{ text }]` untuk pesan teks murni:
|
|
1336
|
+
|
|
1337
|
+
```js
|
|
1338
|
+
// โ
Cara benar โ pakai richResponse array
|
|
1339
|
+
await sock.sendMessage(jid, {
|
|
1340
|
+
richResponse: [
|
|
1341
|
+
{ text: 'Ini teks dari AI dengan *markdown* dan **bold**.' }
|
|
1342
|
+
],
|
|
1343
|
+
headerText: 'Judul',
|
|
1344
|
+
footerText: 'Footer',
|
|
1345
|
+
disclaimerText: 'Generated by AI'
|
|
1346
|
+
})
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
```js
|
|
1350
|
+
// โ
Alternatif โ contentText sebagai pelengkap dari trigger key lain
|
|
1351
|
+
await sock.sendMessage(jid, {
|
|
1352
|
+
code: 'console.log("Hello")',
|
|
1353
|
+
language: 'javascript',
|
|
1354
|
+
contentText: 'Penjelasan tambahan di sini.',
|
|
1355
|
+
headerText: 'Judul',
|
|
1356
|
+
footerText: 'Footer',
|
|
1357
|
+
disclaimerText: 'Generated by AI'
|
|
1358
|
+
})
|
|
1359
|
+
```
|
|
1360
|
+
|
|
1155
1361
|
```js
|
|
1362
|
+
// โ SALAH โ contentText saja tidak akan trigger rich message
|
|
1156
1363
|
await sock.sendMessage(jid, {
|
|
1157
|
-
contentText: '
|
|
1364
|
+
contentText: 'halooo',
|
|
1158
1365
|
headerText: 'Judul',
|
|
1159
1366
|
footerText: 'Footer',
|
|
1160
1367
|
disclaimerText: 'Generated by AI'
|
|
1368
|
+
// โ Error: Invalid media type
|
|
1161
1369
|
})
|
|
1162
1370
|
```
|
|
1163
1371
|
|
package/README.md.bak
CHANGED
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
[Secure Meta Label](#secure-meta-service-label)
|
|
73
73
|
|
|
74
74
|
๐๏ธ **Interactive** โ
|
|
75
|
+
[Buttons Location Header](#buttons-dengan-location-header-buttonsmessage-langsung) ยท
|
|
75
76
|
[Buttons](#buttons) ยท
|
|
76
77
|
[List Message](#list-message) ยท
|
|
77
78
|
[Template Buttons](#template-buttons) ยท
|
|
@@ -927,11 +928,85 @@ await sock.sendMessage(jid, {
|
|
|
927
928
|
|
|
928
929
|
---
|
|
929
930
|
|
|
931
|
+
<details>
|
|
932
|
+
<summary>๐ Buttons dengan Location Header (buttonsMessage langsung)</summary>
|
|
933
|
+
|
|
934
|
+
Kirim tombol menggunakan `buttonsMessage` secara langsung โ berguna untuk header tipe **Location** (`headerType: 6`) yang tidak bisa dibuat lewat shorthand `buttons`.
|
|
935
|
+
|
|
936
|
+
```js
|
|
937
|
+
// Tombol dengan header lokasi (headerType 6)
|
|
938
|
+
await sock.sendMessage(jid, {
|
|
939
|
+
buttonsMessage: {
|
|
940
|
+
locationMessage: {
|
|
941
|
+
degreesLatitude: 0,
|
|
942
|
+
degreesLongitude: 0,
|
|
943
|
+
name: 'NuiiSweety',
|
|
944
|
+
address: 'NuiiSweety Bot',
|
|
945
|
+
jpegThumbnail: './src/img/menu.jpg' // path file, URL, atau Buffer
|
|
946
|
+
},
|
|
947
|
+
contentText: 'Pilih menu di bawah ini',
|
|
948
|
+
footerText: 'Powered by @nuiisweety/baileys',
|
|
949
|
+
buttons: [
|
|
950
|
+
{ buttonId: 'allmenu', buttonText: { displayText: 'All Menu' }, type: 1 }
|
|
951
|
+
],
|
|
952
|
+
headerType: 6
|
|
953
|
+
}
|
|
954
|
+
})
|
|
955
|
+
|
|
956
|
+
// Dengan quoted (reply ke pesan tertentu)
|
|
957
|
+
await sock.sendMessage(jid, {
|
|
958
|
+
buttonsMessage: {
|
|
959
|
+
locationMessage: {
|
|
960
|
+
degreesLatitude: -6.2,
|
|
961
|
+
degreesLongitude: 106.8,
|
|
962
|
+
name: 'Menu Bot',
|
|
963
|
+
address: 'NuiiSweety',
|
|
964
|
+
jpegThumbnail: './src/img/menu.jpg'
|
|
965
|
+
},
|
|
966
|
+
contentText: 'Halo! Ini menu utama bot',
|
|
967
|
+
footerText: 'NuiiSweety Bot',
|
|
968
|
+
buttons: [
|
|
969
|
+
{ buttonId: 'menu1', buttonText: { displayText: '๐ฑ Menu Utama' }, type: 1 },
|
|
970
|
+
{ buttonId: 'help', buttonText: { displayText: 'โ Bantuan' }, type: 1 }
|
|
971
|
+
],
|
|
972
|
+
headerType: 6
|
|
973
|
+
}
|
|
974
|
+
}, { quoted: m })
|
|
975
|
+
|
|
976
|
+
// Header kosong (teks saja, tanpa media/lokasi) โ headerType 1
|
|
977
|
+
await sock.sendMessage(jid, {
|
|
978
|
+
buttonsMessage: {
|
|
979
|
+
contentText: 'Pilih opsi',
|
|
980
|
+
footerText: 'Bot Footer',
|
|
981
|
+
buttons: [
|
|
982
|
+
{ buttonId: 'yes', buttonText: { displayText: 'Ya' }, type: 1 },
|
|
983
|
+
{ buttonId: 'no', buttonText: { displayText: 'Tidak' }, type: 1 }
|
|
984
|
+
],
|
|
985
|
+
headerType: 1
|
|
986
|
+
}
|
|
987
|
+
})
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
> **Catatan `headerType`:**
|
|
991
|
+
> | Nilai | Tipe Header |
|
|
992
|
+
> |-------|-------------|
|
|
993
|
+
> | `1` | Teks (`contentText`) |
|
|
994
|
+
> | `2` | Gambar (`imageMessage`) |
|
|
995
|
+
> | `3` | Video (`videoMessage`) |
|
|
996
|
+
> | `4` | Dokumen (`documentMessage`) |
|
|
997
|
+
> | `6` | Lokasi (`locationMessage`) |
|
|
998
|
+
>
|
|
999
|
+
> `jpegThumbnail` pada `locationMessage` bisa berupa **path file lokal**, **URL**, atau **Buffer** โ otomatis diproses oleh Baileys.
|
|
1000
|
+
|
|
1001
|
+
</details>
|
|
1002
|
+
|
|
1003
|
+
---
|
|
1004
|
+
|
|
930
1005
|
<details>
|
|
931
1006
|
<summary>๐๏ธ Buttons</summary>
|
|
932
1007
|
|
|
933
1008
|
```js
|
|
934
|
-
// Teks dengan tombol
|
|
1009
|
+
// Teks dengan tombol (quick reply)
|
|
935
1010
|
await sock.sendMessage(jid, {
|
|
936
1011
|
text: 'Pilih salah satu',
|
|
937
1012
|
footer: 'Footer pesan',
|
|
@@ -953,7 +1028,28 @@ await sock.sendMessage(jid, {
|
|
|
953
1028
|
]
|
|
954
1029
|
})
|
|
955
1030
|
|
|
956
|
-
// Native flow button
|
|
1031
|
+
// Native flow button dalam buttons โ pakai name + paramsJson
|
|
1032
|
+
await sock.sendMessage(jid, {
|
|
1033
|
+
text: 'Pilih menu',
|
|
1034
|
+
buttons: [
|
|
1035
|
+
{
|
|
1036
|
+
name: 'single_select',
|
|
1037
|
+
text: 'Buka Menu',
|
|
1038
|
+
paramsJson: JSON.stringify({
|
|
1039
|
+
title: 'Buka Menu',
|
|
1040
|
+
sections: [{
|
|
1041
|
+
title: 'Kategori A',
|
|
1042
|
+
rows: [
|
|
1043
|
+
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
|
|
1044
|
+
{ id: 'row2', title: 'Item 2' }
|
|
1045
|
+
]
|
|
1046
|
+
}]
|
|
1047
|
+
})
|
|
1048
|
+
}
|
|
1049
|
+
]
|
|
1050
|
+
})
|
|
1051
|
+
|
|
1052
|
+
// Shorthand: sections langsung di button (otomatis jadi single_select)
|
|
957
1053
|
await sock.sendMessage(jid, {
|
|
958
1054
|
text: 'Pilih menu',
|
|
959
1055
|
buttons: [{
|
|
@@ -969,6 +1065,8 @@ await sock.sendMessage(jid, {
|
|
|
969
1065
|
})
|
|
970
1066
|
```
|
|
971
1067
|
|
|
1068
|
+
> **Field tombol:** gunakan `text` atau `buttonText` untuk label. Untuk quick reply gunakan `id`/`buttonId`. Untuk native flow gunakan `name` + `paramsJson`.
|
|
1069
|
+
|
|
972
1070
|
</details>
|
|
973
1071
|
|
|
974
1072
|
---
|
|
@@ -978,10 +1076,10 @@ await sock.sendMessage(jid, {
|
|
|
978
1076
|
|
|
979
1077
|
```js
|
|
980
1078
|
await sock.sendMessage(jid, {
|
|
981
|
-
text: 'Silakan pilih',
|
|
982
|
-
title: 'Judul List',
|
|
983
|
-
buttonText: 'Buka Daftar',
|
|
984
|
-
footer: 'Footer pesan',
|
|
1079
|
+
text: 'Silakan pilih', // โ description (isi pesan)
|
|
1080
|
+
title: 'Judul List', // โ title (judul di atas list)
|
|
1081
|
+
buttonText: 'Buka Daftar', // โ teks tombol pembuka
|
|
1082
|
+
footer: 'Footer pesan', // โ footerText
|
|
985
1083
|
sections: [
|
|
986
1084
|
{
|
|
987
1085
|
title: 'Bagian 1',
|
|
@@ -1000,6 +1098,8 @@ await sock.sendMessage(jid, {
|
|
|
1000
1098
|
})
|
|
1001
1099
|
```
|
|
1002
1100
|
|
|
1101
|
+
> **Trigger key:** `sections` (bukan `listMessage`). `listType` otomatis di-set ke `SINGLE_SELECT`. Field `text` di-map ke `description` (isi pesan), bukan judul โ gunakan `title` untuk judul list.
|
|
1102
|
+
|
|
1003
1103
|
</details>
|
|
1004
1104
|
|
|
1005
1105
|
---
|
|
@@ -1010,9 +1110,9 @@ await sock.sendMessage(jid, {
|
|
|
1010
1110
|
```js
|
|
1011
1111
|
// Teks
|
|
1012
1112
|
await sock.sendMessage(jid, {
|
|
1013
|
-
text: 'Pesan template',
|
|
1014
|
-
footer: 'Footer',
|
|
1015
|
-
id: 'template-unik',
|
|
1113
|
+
text: 'Pesan template', // โ hydratedContentText
|
|
1114
|
+
footer: 'Footer', // โ hydratedFooterText
|
|
1115
|
+
id: 'template-unik', // โ templateId (opsional, auto-generate jika tidak diisi)
|
|
1016
1116
|
templateButtons: [
|
|
1017
1117
|
{ id: 'btn1', text: 'Quick Reply' },
|
|
1018
1118
|
{ url: 'https://example.com', text: 'Kunjungi Website' },
|
|
@@ -1023,8 +1123,8 @@ await sock.sendMessage(jid, {
|
|
|
1023
1123
|
// Gambar sebagai header
|
|
1024
1124
|
await sock.sendMessage(jid, {
|
|
1025
1125
|
image: { url: 'https://example.com/img.jpg' },
|
|
1026
|
-
caption: 'Isi pesan',
|
|
1027
|
-
title: 'Judul',
|
|
1126
|
+
caption: 'Isi pesan', // โ hydratedContentText
|
|
1127
|
+
title: 'Judul', // โ hydratedTitleText (hanya aktif jika ada caption)
|
|
1028
1128
|
footer: 'Footer',
|
|
1029
1129
|
templateButtons: [
|
|
1030
1130
|
{ id: 'btn1', text: 'Klik Sini' },
|
|
@@ -1033,6 +1133,8 @@ await sock.sendMessage(jid, {
|
|
|
1033
1133
|
})
|
|
1034
1134
|
```
|
|
1035
1135
|
|
|
1136
|
+
> **Tipe tombol:** `{ id, text }` โ quick reply ยท `{ url, text }` โ URL button ยท `{ call, text }` โ call button. `text` atau `buttonText` keduanya diterima. Jika `id` tidak diisi, otomatis `template-<timestamp>`.
|
|
1137
|
+
|
|
1036
1138
|
</details>
|
|
1037
1139
|
|
|
1038
1140
|
---
|
|
@@ -1041,34 +1143,108 @@ await sock.sendMessage(jid, {
|
|
|
1041
1143
|
<summary>๐ Native Flow</summary>
|
|
1042
1144
|
|
|
1043
1145
|
```js
|
|
1044
|
-
//
|
|
1146
|
+
// Quick reply
|
|
1045
1147
|
await sock.sendMessage(jid, {
|
|
1046
1148
|
text: 'Pilih aksi',
|
|
1047
1149
|
footer: 'Footer pesan',
|
|
1048
1150
|
nativeFlow: [
|
|
1049
|
-
{
|
|
1050
|
-
{
|
|
1151
|
+
{ id: '1', text: 'Opsi 1' }, // id โ quick_reply
|
|
1152
|
+
{ id: '2', text: 'Opsi 2' }
|
|
1051
1153
|
]
|
|
1052
1154
|
})
|
|
1053
1155
|
|
|
1054
|
-
//
|
|
1156
|
+
// URL button
|
|
1157
|
+
await sock.sendMessage(jid, {
|
|
1158
|
+
text: 'Kunjungi kami',
|
|
1159
|
+
nativeFlow: [
|
|
1160
|
+
{ url: 'https://example.com', text: 'Buka Website' }
|
|
1161
|
+
]
|
|
1162
|
+
})
|
|
1163
|
+
|
|
1164
|
+
// Copy code button
|
|
1165
|
+
await sock.sendMessage(jid, {
|
|
1166
|
+
text: 'Kode promo kamu',
|
|
1167
|
+
nativeFlow: [
|
|
1168
|
+
{ copy: 'PROMO2025', text: 'Salin Kode' }
|
|
1169
|
+
]
|
|
1170
|
+
})
|
|
1171
|
+
|
|
1172
|
+
// Call button
|
|
1173
|
+
await sock.sendMessage(jid, {
|
|
1174
|
+
text: 'Hubungi kami',
|
|
1175
|
+
nativeFlow: [
|
|
1176
|
+
{ call: '+62812345678', text: 'Telepon Sekarang' }
|
|
1177
|
+
]
|
|
1178
|
+
})
|
|
1179
|
+
|
|
1180
|
+
// Single select (list dalam button)
|
|
1181
|
+
await sock.sendMessage(jid, {
|
|
1182
|
+
text: 'Pilih menu',
|
|
1183
|
+
nativeFlow: [
|
|
1184
|
+
{
|
|
1185
|
+
sections: [{
|
|
1186
|
+
title: 'Kategori A',
|
|
1187
|
+
rows: [
|
|
1188
|
+
{ id: 'row1', title: 'Item 1', description: 'Deskripsi' },
|
|
1189
|
+
{ id: 'row2', title: 'Item 2' }
|
|
1190
|
+
]
|
|
1191
|
+
}],
|
|
1192
|
+
text: 'Buka Daftar'
|
|
1193
|
+
}
|
|
1194
|
+
]
|
|
1195
|
+
})
|
|
1196
|
+
|
|
1197
|
+
// Dengan icon pada tombol
|
|
1198
|
+
await sock.sendMessage(jid, {
|
|
1199
|
+
text: 'Pilih aksi',
|
|
1200
|
+
nativeFlow: [
|
|
1201
|
+
{ id: '1', text: 'Konfirmasi', icon: 'CHECK' },
|
|
1202
|
+
{ url: 'https://example.com', text: 'Buka', icon: 'LINK' }
|
|
1203
|
+
]
|
|
1204
|
+
})
|
|
1205
|
+
|
|
1206
|
+
// Gambar sebagai header โ WAJIB pakai image/video/document/location/product
|
|
1207
|
+
// jika tidak ada media valid โ throw Error: Invalid media type
|
|
1055
1208
|
await sock.sendMessage(jid, {
|
|
1056
1209
|
image: { url: 'https://example.com/img.jpg' },
|
|
1057
|
-
caption: 'Isi pesan',
|
|
1058
|
-
title: 'Judul',
|
|
1059
|
-
subtitle: 'Subjudul',
|
|
1210
|
+
caption: 'Isi pesan', // โ body.text
|
|
1211
|
+
title: 'Judul', // โ header.title
|
|
1212
|
+
subtitle: 'Subjudul', // โ header.subtitle
|
|
1060
1213
|
footer: 'Footer',
|
|
1061
1214
|
nativeFlow: [
|
|
1062
|
-
{
|
|
1215
|
+
{ id: '1', text: 'Tombol 1' }
|
|
1063
1216
|
]
|
|
1064
1217
|
})
|
|
1065
1218
|
|
|
1066
|
-
// Dengan audio footer
|
|
1219
|
+
// Dengan audio footer (menggantikan footer teks)
|
|
1067
1220
|
await sock.sendMessage(jid, {
|
|
1068
1221
|
text: 'Pesan dengan audio footer',
|
|
1069
1222
|
audioFooter: fs.readFileSync('audio.ogg'),
|
|
1070
1223
|
nativeFlow: [
|
|
1071
|
-
{
|
|
1224
|
+
{ id: '1', text: 'OK' }
|
|
1225
|
+
]
|
|
1226
|
+
})
|
|
1227
|
+
|
|
1228
|
+
// offerText โ tampil sebagai limited time offer banner
|
|
1229
|
+
await sock.sendMessage(jid, {
|
|
1230
|
+
text: 'Penawaran terbatas!',
|
|
1231
|
+
offerText: 'Diskon 50%',
|
|
1232
|
+
offerUrl: 'https://example.com/promo',
|
|
1233
|
+
offerCode: 'DISKON50',
|
|
1234
|
+
offerExpiration: 1800000000,
|
|
1235
|
+
nativeFlow: [
|
|
1236
|
+
{ id: 'claim', text: 'Klaim Sekarang' }
|
|
1237
|
+
]
|
|
1238
|
+
})
|
|
1239
|
+
|
|
1240
|
+
// optionText โ tombol-tombol masuk ke bottom sheet
|
|
1241
|
+
await sock.sendMessage(jid, {
|
|
1242
|
+
text: 'Pilih opsi',
|
|
1243
|
+
optionText: 'Lihat Semua Opsi',
|
|
1244
|
+
optionTitle: 'Daftar Pilihan',
|
|
1245
|
+
nativeFlow: [
|
|
1246
|
+
{ id: '1', text: 'Opsi A' },
|
|
1247
|
+
{ id: '2', text: 'Opsi B' }
|
|
1072
1248
|
]
|
|
1073
1249
|
})
|
|
1074
1250
|
|
|
@@ -1076,13 +1252,15 @@ await sock.sendMessage(jid, {
|
|
|
1076
1252
|
await sock.sendMessage(jid, {
|
|
1077
1253
|
text: 'Template interaktif',
|
|
1078
1254
|
nativeFlow: [
|
|
1079
|
-
{
|
|
1255
|
+
{ id: '1', text: 'Tombol' }
|
|
1080
1256
|
],
|
|
1081
1257
|
interactiveAsTemplate: true,
|
|
1082
1258
|
id: 'template-id-unik'
|
|
1083
1259
|
})
|
|
1084
1260
|
```
|
|
1085
1261
|
|
|
1262
|
+
> **Tipe tombol ditentukan otomatis** dari field yang ada: `id` โ quick_reply ยท `url` โ cta_url ยท `copy` โ cta_copy ยท `call` โ cta_call ยท `sections` โ single_select. Bisa juga pakai `name` + `paramsJson` langsung untuk kontrol penuh. `text` atau `buttonText` keduanya diterima. Field `icon` opsional (string uppercase, e.g. `'CHECK'`, `'LINK'`).
|
|
1263
|
+
|
|
1086
1264
|
</details>
|
|
1087
1265
|
|
|
1088
1266
|
---
|
|
@@ -1148,16 +1326,46 @@ await sock.sendMessage(['628xxx@s.whatsapp.net'], {
|
|
|
1148
1326
|
|
|
1149
1327
|
> Rich message menggunakan format `AIRichResponseMessage` yang tampil seperti respons AI di WhatsApp. Semua tipe di bawah bisa dipakai secara flat (field langsung) atau dikombinasikan via `richResponse: [...]`.
|
|
1150
1328
|
|
|
1329
|
+
> โ ๏ธ **Penting:** `contentText`, `headerText`, `footerText`, dan `disclaimerText` **bukan** trigger key โ artinya jika hanya field itu yang dikirim, pesan **tidak akan** diproses sebagai rich message dan akan menghasilkan **Error: Invalid media type**. Gunakan selalu minimal satu trigger key (`code`, `table`, `richImage`, `richVideo`, `richResponse`, dll), lalu kombinasikan dengan field teks di atas sebagai pelengkap.
|
|
1330
|
+
|
|
1151
1331
|
### โ๏ธ addText
|
|
1152
1332
|
|
|
1153
1333
|
Kirim teks markdown sebagai AI Rich Response. Mendukung hyperlink, citation, dan LaTeX inline.
|
|
1154
1334
|
|
|
1335
|
+
Karena `contentText` bukan trigger key, gunakan `richResponse: [{ text }]` untuk pesan teks murni:
|
|
1336
|
+
|
|
1337
|
+
```js
|
|
1338
|
+
// โ
Cara benar โ pakai richResponse array
|
|
1339
|
+
await sock.sendMessage(jid, {
|
|
1340
|
+
richResponse: [
|
|
1341
|
+
{ text: 'Ini teks dari AI dengan *markdown* dan **bold**.' }
|
|
1342
|
+
],
|
|
1343
|
+
headerText: 'Judul',
|
|
1344
|
+
footerText: 'Footer',
|
|
1345
|
+
disclaimerText: 'Generated by AI'
|
|
1346
|
+
})
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
```js
|
|
1350
|
+
// โ
Alternatif โ contentText sebagai pelengkap dari trigger key lain
|
|
1351
|
+
await sock.sendMessage(jid, {
|
|
1352
|
+
code: 'console.log("Hello")',
|
|
1353
|
+
language: 'javascript',
|
|
1354
|
+
contentText: 'Penjelasan tambahan di sini.',
|
|
1355
|
+
headerText: 'Judul',
|
|
1356
|
+
footerText: 'Footer',
|
|
1357
|
+
disclaimerText: 'Generated by AI'
|
|
1358
|
+
})
|
|
1359
|
+
```
|
|
1360
|
+
|
|
1155
1361
|
```js
|
|
1362
|
+
// โ SALAH โ contentText saja tidak akan trigger rich message
|
|
1156
1363
|
await sock.sendMessage(jid, {
|
|
1157
|
-
contentText: '
|
|
1364
|
+
contentText: 'halooo',
|
|
1158
1365
|
headerText: 'Judul',
|
|
1159
1366
|
footerText: 'Footer',
|
|
1160
1367
|
disclaimerText: 'Generated by AI'
|
|
1368
|
+
// โ Error: Invalid media type
|
|
1161
1369
|
})
|
|
1162
1370
|
```
|
|
1163
1371
|
|
package/lib/Utils/messages.js
CHANGED
|
@@ -919,6 +919,24 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
919
919
|
}
|
|
920
920
|
};
|
|
921
921
|
}
|
|
922
|
+
else if (hasNonNullishProperty(message, 'buttonsMessage')) {
|
|
923
|
+
// Direct buttonsMessage passthrough โ supports headerType 6 (locationMessage), etc.
|
|
924
|
+
const btnMsg = { ...message.buttonsMessage };
|
|
925
|
+
if (btnMsg.locationMessage?.jpegThumbnail && !Buffer.isBuffer(btnMsg.locationMessage.jpegThumbnail)) {
|
|
926
|
+
const lib = await getImageProcessingLibrary();
|
|
927
|
+
const hasSharp = 'sharp' in lib && !!lib.sharp?.default;
|
|
928
|
+
if (hasSharp) {
|
|
929
|
+
const rawBuf = typeof btnMsg.locationMessage.jpegThumbnail === 'string'
|
|
930
|
+
? (await fs.readFile(btnMsg.locationMessage.jpegThumbnail))
|
|
931
|
+
: btnMsg.locationMessage.jpegThumbnail;
|
|
932
|
+
btnMsg.locationMessage.jpegThumbnail = await lib.sharp.default(rawBuf)
|
|
933
|
+
.resize(300, 300, { fit: 'inside', withoutEnlargement: true })
|
|
934
|
+
.jpeg({ quality: 80 })
|
|
935
|
+
.toBuffer();
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
m = { buttonsMessage: btnMsg };
|
|
939
|
+
}
|
|
922
940
|
else {
|
|
923
941
|
m = await prepareWAMessageMedia(message, options);
|
|
924
942
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuiisweety/baileys",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.12",
|
|
5
5
|
"description": "A WebSockets library for interacting with WhatsApp Web โ forked STRICTLY from @whiskeysockets/baileys only, NOT from any other baileys fork. Modified by NuiiSweety.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"whatsapp",
|