wa-multi-mongodb 3.8.1 → 3.9.1
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/dist/Messaging/index.d.ts.map +1 -1
- package/dist/Messaging/index.js +373 -152
- package/package.json +2 -2
- package/readme.md +52 -31
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Messaging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,SAAS,CAAC;AAGnD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EAChB,MAAM,UAAU,CAAC;AAOlB,eAAO,MAAM,eAAe,GAAU,4CAMnC,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Messaging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,SAAS,CAAC;AAGnD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EAChB,MAAM,UAAU,CAAC;AAOlB,eAAO,MAAM,eAAe,GAAU,4CAMnC,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CA2H7D,CAAC;AAaF,eAAO,MAAM,SAAS,GAAU,wEAS7B,cAAc,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAgL3D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,6CAMjC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CA2GzE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,6CAM/B,cAAc,KAAG,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,SAAS,CAyG3D,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAU,uCAK9B,eAAe,KAAG,OAAO,CAAC,IAAI,CAuEhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,qBAG/B,aAAa,KAAG,OAAO,CAAC,IAAI,CA6B9B,CAAC"}
|
package/dist/Messaging/index.js
CHANGED
|
@@ -32,153 +32,123 @@ const is_exist_1 = require("../Utils/is-exist");
|
|
|
32
32
|
const mime_1 = __importDefault(require("mime"));
|
|
33
33
|
const Error_1 = require("../Error");
|
|
34
34
|
const sendTextMessage = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
-
var _b;
|
|
36
35
|
var { sessionId, to, text = "", isGroup = false } = _a, props = __rest(_a, ["sessionId", "to", "text", "isGroup"]);
|
|
37
36
|
const session = (0, Socket_1.getSession)(sessionId);
|
|
38
37
|
if (!session)
|
|
39
38
|
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
54
|
-
text: text,
|
|
55
|
-
}, messageOptions), timeoutMs, `Pengiriman pesan ke ${to} melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
39
|
+
// Deteksi otomatis apakah ini adalah grup berdasarkan format JID
|
|
40
|
+
const toStr = to.toString();
|
|
41
|
+
const isGroupChat = toStr.includes('@g.us');
|
|
42
|
+
// Jika sudah dalam format grup, gunakan to langsung
|
|
43
|
+
// Jika tidak, gunakan phoneToJid untuk mengkonversi ke format yang benar
|
|
44
|
+
let jid;
|
|
45
|
+
if (isGroupChat) {
|
|
46
|
+
if (!toStr.endsWith('@g.us')) {
|
|
47
|
+
jid = toStr + '@g.us';
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
jid = toStr;
|
|
51
|
+
}
|
|
56
52
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
else {
|
|
54
|
+
jid = (0, Utils_1.phoneToJid)({ to, isGroup: isGroup || isGroupChat });
|
|
55
|
+
}
|
|
56
|
+
let retryCount = 0;
|
|
57
|
+
const maxRetries = 3;
|
|
58
|
+
const attemptSend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
var _a, _b, _c;
|
|
60
|
+
try {
|
|
61
|
+
// Gunakan flag force untuk mencoba memaksa pengiriman pesan bahkan jika koneksi tidak stabil
|
|
62
|
+
const messageOptions = {
|
|
63
|
+
quoted: props.answering,
|
|
64
|
+
};
|
|
65
|
+
// Konfirmasi sekali lagi apakah ini grup berdasarkan format JID setelah konversi
|
|
66
|
+
const isDestinationGroup = jid.endsWith('@g.us');
|
|
67
|
+
// Gunakan waktu jeda untuk memastikan koneksi siap
|
|
68
|
+
yield (0, create_delay_1.createDelay)(500);
|
|
69
|
+
// Beri timeout yang lebih pendek untuk grup untuk mencegah hanging
|
|
70
|
+
const timeoutMs = isDestinationGroup ? 15000 : 30000;
|
|
71
|
+
// Gunakan withTimeout untuk membatasi waktu operasi
|
|
72
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
73
|
+
text: text,
|
|
74
|
+
}, messageOptions), timeoutMs, `Pengiriman pesan ke ${jid} melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(`Error saat mengirim pesan (percobaan ${retryCount + 1}/${maxRetries}): ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
78
|
+
// Jika error terkait MessageCounterError (grup dengan channel pengumuman)
|
|
79
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('MessageCounterError')) || ((_b = error === null || error === void 0 ? void 0 : error.stack) === null || _b === void 0 ? void 0 : _b.includes('MessageCounterError'))) {
|
|
80
|
+
console.warn('Terdeteksi MessageCounterError, kemungkinan grup dengan channel pengumuman');
|
|
81
|
+
if (retryCount < maxRetries) {
|
|
82
|
+
retryCount++;
|
|
83
|
+
// Tambahkan delay lebih lama antara percobaan
|
|
84
|
+
yield (0, create_delay_1.createDelay)(2000 * retryCount);
|
|
85
|
+
console.log(`Mencoba kembali pengiriman pesan (${retryCount}/${maxRetries})...`);
|
|
86
|
+
return attemptSend();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.error('Batas maksimum percobaan ulang tercapai');
|
|
90
|
+
throw new Error_1.WhatsappError(`Gagal mengirim pesan ke grup dengan channel pengumuman setelah ${maxRetries} kali percobaan`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Jika koneksi tertutup, coba reconnect
|
|
94
|
+
if ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection Closed')) {
|
|
95
|
+
try {
|
|
96
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
97
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
98
|
+
// Coba kirim lagi setelah reconnect
|
|
99
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
100
|
+
text: text,
|
|
101
|
+
}, {
|
|
102
|
+
quoted: props.answering,
|
|
103
|
+
}), 30000, `Pengiriman pesan setelah reconnect melebihi batas waktu`);
|
|
104
|
+
}
|
|
105
|
+
catch (reconnectError) {
|
|
106
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
107
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Jika ada error timeout atau error lain, coba lagi sekali dengan delay lebih lama
|
|
61
111
|
try {
|
|
62
|
-
yield (0,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
112
|
+
yield (0, create_delay_1.createDelay)(2000);
|
|
113
|
+
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
114
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
66
115
|
text: text,
|
|
67
116
|
}, {
|
|
68
117
|
quoted: props.answering,
|
|
69
|
-
}),
|
|
118
|
+
}), 20000, `Percobaan kedua pengiriman pesan melebihi batas waktu`);
|
|
70
119
|
}
|
|
71
|
-
catch (
|
|
72
|
-
console.error(`Gagal
|
|
73
|
-
throw new Error_1.WhatsappError(`
|
|
120
|
+
catch (retryError) {
|
|
121
|
+
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
122
|
+
throw new Error_1.WhatsappError(`Gagal mengirim pesan: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
74
123
|
}
|
|
75
124
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
yield (0, create_delay_1.createDelay)(2000);
|
|
79
|
-
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
80
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, {
|
|
81
|
-
text: text,
|
|
82
|
-
}, {
|
|
83
|
-
quoted: props.answering,
|
|
84
|
-
}), 20000, `Percobaan kedua pengiriman pesan melebihi batas waktu`);
|
|
85
|
-
}
|
|
86
|
-
catch (retryError) {
|
|
87
|
-
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
88
|
-
throw new Error_1.WhatsappError(`Gagal mengirim pesan: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
125
|
+
});
|
|
126
|
+
return attemptSend();
|
|
91
127
|
});
|
|
92
128
|
exports.sendTextMessage = sendTextMessage;
|
|
93
129
|
const sendMedia = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionId, to, media, type, caption = "", fileName, isGroup = false, answering, }) {
|
|
94
|
-
var _b;
|
|
95
130
|
const session = (0, Socket_1.getSession)(sessionId);
|
|
96
131
|
if (!session)
|
|
97
132
|
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// Tunda sejenak untuk memastikan koneksi stabil
|
|
108
|
-
yield (0, create_delay_1.createDelay)(500);
|
|
109
|
-
// Persiapkan media dengan isExist
|
|
110
|
-
const processedMedia = (0, is_exist_1.isExist)(media);
|
|
111
|
-
switch (type) {
|
|
112
|
-
case "image":
|
|
113
|
-
messageContent.image = processedMedia;
|
|
114
|
-
messageContent.caption = caption;
|
|
115
|
-
if (fileName)
|
|
116
|
-
messageContent.fileName = fileName;
|
|
117
|
-
break;
|
|
118
|
-
case "video":
|
|
119
|
-
messageContent.video = processedMedia;
|
|
120
|
-
messageContent.caption = caption;
|
|
121
|
-
if (fileName)
|
|
122
|
-
messageContent.fileName = fileName;
|
|
123
|
-
break;
|
|
124
|
-
case "audio":
|
|
125
|
-
messageContent.audio = processedMedia;
|
|
126
|
-
messageContent.mimetype = mimeType;
|
|
127
|
-
if (fileName)
|
|
128
|
-
messageContent.fileName = fileName;
|
|
129
|
-
break;
|
|
130
|
-
case "pdf":
|
|
131
|
-
case "xls":
|
|
132
|
-
case "xlsx":
|
|
133
|
-
case "doc":
|
|
134
|
-
case "docx":
|
|
135
|
-
case "zip":
|
|
136
|
-
case "mp3":
|
|
137
|
-
messageContent.document = processedMedia;
|
|
138
|
-
messageContent.mimetype = mimeType;
|
|
139
|
-
messageContent.caption = caption;
|
|
140
|
-
if (fileName)
|
|
141
|
-
messageContent.fileName = fileName;
|
|
142
|
-
break;
|
|
143
|
-
default:
|
|
144
|
-
throw new Error("Media type not found! (image, video, audio, pdf)");
|
|
133
|
+
// Deteksi otomatis apakah ini adalah grup berdasarkan format JID
|
|
134
|
+
const toStr = to.toString();
|
|
135
|
+
const isGroupChat = toStr.includes('@g.us');
|
|
136
|
+
// Jika sudah dalam format grup, gunakan to langsung
|
|
137
|
+
// Jika tidak, gunakan phoneToJid untuk mengkonversi ke format yang benar
|
|
138
|
+
let jid;
|
|
139
|
+
if (isGroupChat) {
|
|
140
|
+
if (!toStr.endsWith('@g.us')) {
|
|
141
|
+
jid = toStr + '@g.us';
|
|
145
142
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, messageContent, options), timeoutMs, `Pengiriman media melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
console.error(`Error saat mengirim media: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
152
|
-
// Jika koneksi tertutup, coba reconnect
|
|
153
|
-
if ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('Connection Closed')) {
|
|
154
|
-
try {
|
|
155
|
-
yield (0, Socket_1.reconnect)(sessionId);
|
|
156
|
-
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
157
|
-
// Siapkan content media untuk percobaan ulang
|
|
158
|
-
const retryContent = getMessageContent();
|
|
159
|
-
// Coba kirim lagi setelah reconnect
|
|
160
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan setelah reconnect
|
|
161
|
-
`Pengiriman media setelah reconnect melebihi batas waktu`);
|
|
162
|
-
}
|
|
163
|
-
catch (reconnectError) {
|
|
164
|
-
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
165
|
-
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
// Untuk error timeout atau error lain, coba lagi dengan timeout lebih lama
|
|
169
|
-
try {
|
|
170
|
-
yield (0, create_delay_1.createDelay)(3000);
|
|
171
|
-
// Siapkan content media untuk percobaan ulang
|
|
172
|
-
const retryContent = getMessageContent();
|
|
173
|
-
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
174
|
-
return yield (0, create_delay_1.withTimeout)(session.sendMessage(to, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan kedua
|
|
175
|
-
`Percobaan kedua pengiriman media melebihi batas waktu`);
|
|
176
|
-
}
|
|
177
|
-
catch (retryError) {
|
|
178
|
-
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
179
|
-
throw new Error_1.WhatsappError(`Gagal mengirim media: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
143
|
+
else {
|
|
144
|
+
jid = toStr;
|
|
180
145
|
}
|
|
181
146
|
}
|
|
147
|
+
else {
|
|
148
|
+
jid = (0, Utils_1.phoneToJid)({ to, isGroup: isGroup || isGroupChat });
|
|
149
|
+
}
|
|
150
|
+
let retryCount = 0;
|
|
151
|
+
const maxRetries = 3;
|
|
182
152
|
// Helper function untuk mendapatkan message content berdasarkan tipe
|
|
183
153
|
function getMessageContent() {
|
|
184
154
|
const processedMedia = (0, is_exist_1.isExist)(media);
|
|
@@ -212,6 +182,108 @@ const sendMedia = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionId
|
|
|
212
182
|
}
|
|
213
183
|
return content;
|
|
214
184
|
}
|
|
185
|
+
const attemptSend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
186
|
+
var _a, _b, _c;
|
|
187
|
+
try {
|
|
188
|
+
const mimeType = mime_1.default.getType(typeof media === 'string' ? media : (fileName || '')) || 'application/octet-stream';
|
|
189
|
+
if (!mimeType && type !== 'image' && type !== 'video')
|
|
190
|
+
throw new Error("Cannot get file mimetype!");
|
|
191
|
+
const messageContent = {};
|
|
192
|
+
const options = answering ? { quoted: answering } : {};
|
|
193
|
+
// Konfirmasi sekali lagi apakah ini grup berdasarkan format JID setelah konversi
|
|
194
|
+
const isDestinationGroup = jid.endsWith('@g.us');
|
|
195
|
+
// Tunda sejenak untuk memastikan koneksi stabil
|
|
196
|
+
yield (0, create_delay_1.createDelay)(500);
|
|
197
|
+
// Persiapkan media dengan isExist
|
|
198
|
+
const processedMedia = (0, is_exist_1.isExist)(media);
|
|
199
|
+
switch (type) {
|
|
200
|
+
case "image":
|
|
201
|
+
messageContent.image = processedMedia;
|
|
202
|
+
messageContent.caption = caption;
|
|
203
|
+
if (fileName)
|
|
204
|
+
messageContent.fileName = fileName;
|
|
205
|
+
break;
|
|
206
|
+
case "video":
|
|
207
|
+
messageContent.video = processedMedia;
|
|
208
|
+
messageContent.caption = caption;
|
|
209
|
+
if (fileName)
|
|
210
|
+
messageContent.fileName = fileName;
|
|
211
|
+
break;
|
|
212
|
+
case "audio":
|
|
213
|
+
messageContent.audio = processedMedia;
|
|
214
|
+
messageContent.mimetype = mimeType;
|
|
215
|
+
if (fileName)
|
|
216
|
+
messageContent.fileName = fileName;
|
|
217
|
+
break;
|
|
218
|
+
case "pdf":
|
|
219
|
+
case "xls":
|
|
220
|
+
case "xlsx":
|
|
221
|
+
case "doc":
|
|
222
|
+
case "docx":
|
|
223
|
+
case "zip":
|
|
224
|
+
case "mp3":
|
|
225
|
+
messageContent.document = processedMedia;
|
|
226
|
+
messageContent.mimetype = mimeType;
|
|
227
|
+
messageContent.caption = caption;
|
|
228
|
+
if (fileName)
|
|
229
|
+
messageContent.fileName = fileName;
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
throw new Error("Media type not found! (image, video, audio, pdf)");
|
|
233
|
+
}
|
|
234
|
+
// Timeout lebih lama untuk media karena ukuran file
|
|
235
|
+
const timeoutMs = isDestinationGroup ? 60000 : 120000;
|
|
236
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, messageContent, options), timeoutMs, `Pengiriman media melebihi batas waktu ${timeoutMs / 1000} detik`);
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
console.error(`Error saat mengirim media (percobaan ${retryCount + 1}/${maxRetries}): ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
240
|
+
// Jika error terkait MessageCounterError (grup dengan channel pengumuman)
|
|
241
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('MessageCounterError')) || ((_b = error === null || error === void 0 ? void 0 : error.stack) === null || _b === void 0 ? void 0 : _b.includes('MessageCounterError'))) {
|
|
242
|
+
console.warn('Terdeteksi MessageCounterError, kemungkinan grup dengan channel pengumuman');
|
|
243
|
+
if (retryCount < maxRetries) {
|
|
244
|
+
retryCount++;
|
|
245
|
+
// Tambahkan delay lebih lama antara percobaan
|
|
246
|
+
yield (0, create_delay_1.createDelay)(2000 * retryCount);
|
|
247
|
+
console.log(`Mencoba kembali pengiriman media (${retryCount}/${maxRetries})...`);
|
|
248
|
+
return attemptSend();
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
console.error('Batas maksimum percobaan ulang tercapai');
|
|
252
|
+
throw new Error_1.WhatsappError(`Gagal mengirim media ke grup dengan channel pengumuman setelah ${maxRetries} kali percobaan`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Jika koneksi tertutup, coba reconnect
|
|
256
|
+
if ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection Closed')) {
|
|
257
|
+
try {
|
|
258
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
259
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
260
|
+
// Siapkan content media untuk percobaan ulang
|
|
261
|
+
const retryContent = getMessageContent();
|
|
262
|
+
// Coba kirim lagi setelah reconnect
|
|
263
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan setelah reconnect
|
|
264
|
+
`Pengiriman media setelah reconnect melebihi batas waktu`);
|
|
265
|
+
}
|
|
266
|
+
catch (reconnectError) {
|
|
267
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
268
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Untuk error timeout atau error lain, coba lagi dengan timeout lebih lama
|
|
272
|
+
try {
|
|
273
|
+
yield (0, create_delay_1.createDelay)(3000);
|
|
274
|
+
// Siapkan content media untuk percobaan ulang
|
|
275
|
+
const retryContent = getMessageContent();
|
|
276
|
+
// Untuk percobaan kedua, gunakan timeout yang lebih lama
|
|
277
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, retryContent, answering ? { quoted: answering } : {}), 180000, // 3 menit untuk percobaan kedua
|
|
278
|
+
`Percobaan kedua pengiriman media melebihi batas waktu`);
|
|
279
|
+
}
|
|
280
|
+
catch (retryError) {
|
|
281
|
+
console.error(`Gagal pada percobaan kedua: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
282
|
+
throw new Error_1.WhatsappError(`Gagal mengirim media: ${(retryError === null || retryError === void 0 ? void 0 : retryError.message) || 'Unknown error'}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
return attemptSend();
|
|
215
287
|
});
|
|
216
288
|
exports.sendMedia = sendMedia;
|
|
217
289
|
const sendVoiceNote = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -219,20 +291,87 @@ const sendVoiceNote = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
219
291
|
const session = (0, Socket_1.getSession)(sessionId);
|
|
220
292
|
if (!session)
|
|
221
293
|
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
222
|
-
|
|
294
|
+
// Deteksi otomatis apakah ini adalah grup berdasarkan format JID
|
|
295
|
+
const toStr = to.toString();
|
|
296
|
+
const isGroupChat = toStr.includes('@g.us');
|
|
297
|
+
// Jika sudah dalam format grup, gunakan to langsung
|
|
298
|
+
// Jika tidak, gunakan phoneToJid untuk mengkonversi ke format yang benar
|
|
299
|
+
let jid;
|
|
300
|
+
if (isGroupChat) {
|
|
301
|
+
if (!toStr.endsWith('@g.us')) {
|
|
302
|
+
jid = toStr + '@g.us';
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
jid = toStr;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
jid = (0, Utils_1.phoneToJid)({ to, isGroup: isGroup || isGroupChat });
|
|
310
|
+
}
|
|
223
311
|
if (!media) {
|
|
224
312
|
throw new Error_1.WhatsappError(`Invalid Media`);
|
|
225
313
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
314
|
+
let retryCount = 0;
|
|
315
|
+
const maxRetries = 3;
|
|
316
|
+
const attemptSend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
317
|
+
var _a, _b, _c;
|
|
318
|
+
try {
|
|
319
|
+
// Gunakan timeout untuk mencegah hanging
|
|
320
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
321
|
+
audio: typeof media == "string"
|
|
322
|
+
? {
|
|
323
|
+
url: media,
|
|
324
|
+
}
|
|
325
|
+
: media,
|
|
326
|
+
ptt: true,
|
|
327
|
+
}, {
|
|
328
|
+
quoted: props.answering,
|
|
329
|
+
}), 60000, `Pengiriman voice note melebihi batas waktu`);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
console.error(`Error saat mengirim voice note (percobaan ${retryCount + 1}/${maxRetries}): ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
333
|
+
// Jika error terkait MessageCounterError (grup dengan channel pengumuman)
|
|
334
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('MessageCounterError')) || ((_b = error === null || error === void 0 ? void 0 : error.stack) === null || _b === void 0 ? void 0 : _b.includes('MessageCounterError'))) {
|
|
335
|
+
console.warn('Terdeteksi MessageCounterError, kemungkinan grup dengan channel pengumuman');
|
|
336
|
+
if (retryCount < maxRetries) {
|
|
337
|
+
retryCount++;
|
|
338
|
+
// Tambahkan delay lebih lama antara percobaan
|
|
339
|
+
yield (0, create_delay_1.createDelay)(2000 * retryCount);
|
|
340
|
+
console.log(`Mencoba kembali pengiriman voice note (${retryCount}/${maxRetries})...`);
|
|
341
|
+
return attemptSend();
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
console.error('Batas maksimum percobaan ulang tercapai');
|
|
345
|
+
throw new Error_1.WhatsappError(`Gagal mengirim voice note ke grup dengan channel pengumuman setelah ${maxRetries} kali percobaan`);
|
|
346
|
+
}
|
|
230
347
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
348
|
+
// Jika koneksi tertutup, coba reconnect
|
|
349
|
+
if ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection Closed')) {
|
|
350
|
+
try {
|
|
351
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
352
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
353
|
+
// Coba kirim lagi setelah reconnect
|
|
354
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
355
|
+
audio: typeof media == "string"
|
|
356
|
+
? {
|
|
357
|
+
url: media,
|
|
358
|
+
}
|
|
359
|
+
: media,
|
|
360
|
+
ptt: true,
|
|
361
|
+
}, {
|
|
362
|
+
quoted: props.answering,
|
|
363
|
+
}), 60000, `Pengiriman voice note setelah reconnect melebihi batas waktu`);
|
|
364
|
+
}
|
|
365
|
+
catch (reconnectError) {
|
|
366
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
367
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Re-throw error jika bukan masalah koneksi atau reconnect gagal
|
|
371
|
+
throw new Error_1.WhatsappError(`Gagal mengirim voice note: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
372
|
+
}
|
|
235
373
|
});
|
|
374
|
+
return attemptSend();
|
|
236
375
|
});
|
|
237
376
|
exports.sendVoiceNote = sendVoiceNote;
|
|
238
377
|
const sendSticker = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -240,19 +379,85 @@ const sendSticker = (_a) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
240
379
|
const session = (0, Socket_1.getSession)(sessionId);
|
|
241
380
|
if (!session)
|
|
242
381
|
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
243
|
-
|
|
382
|
+
// Deteksi otomatis apakah ini adalah grup berdasarkan format JID
|
|
383
|
+
const toStr = to.toString();
|
|
384
|
+
const isGroupChat = toStr.includes('@g.us');
|
|
385
|
+
// Jika sudah dalam format grup, gunakan to langsung
|
|
386
|
+
// Jika tidak, gunakan phoneToJid untuk mengkonversi ke format yang benar
|
|
387
|
+
let jid;
|
|
388
|
+
if (isGroupChat) {
|
|
389
|
+
if (!toStr.endsWith('@g.us')) {
|
|
390
|
+
jid = toStr + '@g.us';
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
jid = toStr;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
jid = (0, Utils_1.phoneToJid)({ to, isGroup: isGroup || isGroupChat });
|
|
398
|
+
}
|
|
244
399
|
if (!media) {
|
|
245
400
|
throw new Error_1.WhatsappError(`Invalid Media`);
|
|
246
401
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
402
|
+
let retryCount = 0;
|
|
403
|
+
const maxRetries = 3;
|
|
404
|
+
const attemptSend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
405
|
+
var _a, _b, _c;
|
|
406
|
+
try {
|
|
407
|
+
// Gunakan timeout untuk mencegah hanging
|
|
408
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
409
|
+
sticker: typeof media == "string"
|
|
410
|
+
? {
|
|
411
|
+
url: media,
|
|
412
|
+
}
|
|
413
|
+
: media,
|
|
414
|
+
}, {
|
|
415
|
+
quoted: props.answering,
|
|
416
|
+
}), 60000, `Pengiriman sticker melebihi batas waktu`);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
console.error(`Error saat mengirim sticker (percobaan ${retryCount + 1}/${maxRetries}): ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
420
|
+
// Jika error terkait MessageCounterError (grup dengan channel pengumuman)
|
|
421
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('MessageCounterError')) || ((_b = error === null || error === void 0 ? void 0 : error.stack) === null || _b === void 0 ? void 0 : _b.includes('MessageCounterError'))) {
|
|
422
|
+
console.warn('Terdeteksi MessageCounterError, kemungkinan grup dengan channel pengumuman');
|
|
423
|
+
if (retryCount < maxRetries) {
|
|
424
|
+
retryCount++;
|
|
425
|
+
// Tambahkan delay lebih lama antara percobaan
|
|
426
|
+
yield (0, create_delay_1.createDelay)(2000 * retryCount);
|
|
427
|
+
console.log(`Mencoba kembali pengiriman sticker (${retryCount}/${maxRetries})...`);
|
|
428
|
+
return attemptSend();
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
console.error('Batas maksimum percobaan ulang tercapai');
|
|
432
|
+
throw new Error_1.WhatsappError(`Gagal mengirim sticker ke grup dengan channel pengumuman setelah ${maxRetries} kali percobaan`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Jika koneksi tertutup, coba reconnect
|
|
436
|
+
if ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection Closed')) {
|
|
437
|
+
try {
|
|
438
|
+
yield (0, Socket_1.reconnect)(sessionId);
|
|
439
|
+
yield (0, create_delay_1.createDelay)(3000); // Beri waktu untuk reconnect sepenuhnya
|
|
440
|
+
// Coba kirim lagi setelah reconnect
|
|
441
|
+
return yield (0, create_delay_1.withTimeout)(session.sendMessage(jid, {
|
|
442
|
+
sticker: typeof media == "string"
|
|
443
|
+
? {
|
|
444
|
+
url: media,
|
|
445
|
+
}
|
|
446
|
+
: media,
|
|
447
|
+
}, {
|
|
448
|
+
quoted: props.answering,
|
|
449
|
+
}), 60000, `Pengiriman sticker setelah reconnect melebihi batas waktu`);
|
|
450
|
+
}
|
|
451
|
+
catch (reconnectError) {
|
|
452
|
+
console.error(`Gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
453
|
+
throw new Error_1.WhatsappError(`Koneksi terputus dan gagal reconnect: ${(reconnectError === null || reconnectError === void 0 ? void 0 : reconnectError.message) || 'Unknown error'}`);
|
|
454
|
+
}
|
|
251
455
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
456
|
+
// Re-throw error jika bukan masalah koneksi atau reconnect gagal
|
|
457
|
+
throw new Error_1.WhatsappError(`Gagal mengirim sticker: ${(error === null || error === void 0 ? void 0 : error.message) || 'Unknown error'}`);
|
|
458
|
+
}
|
|
255
459
|
});
|
|
460
|
+
return attemptSend();
|
|
256
461
|
});
|
|
257
462
|
exports.sendSticker = sendSticker;
|
|
258
463
|
/**
|
|
@@ -270,17 +475,33 @@ const sendTyping = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionI
|
|
|
270
475
|
const session = (0, Socket_1.getSession)(sessionId);
|
|
271
476
|
if (!session)
|
|
272
477
|
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionNotFound(sessionId));
|
|
273
|
-
|
|
478
|
+
// Deteksi otomatis apakah ini adalah grup berdasarkan format JID
|
|
479
|
+
const toStr = to.toString();
|
|
480
|
+
const isGroupChat = toStr.includes('@g.us');
|
|
481
|
+
// Jika sudah dalam format grup, gunakan to langsung
|
|
482
|
+
// Jika tidak, gunakan phoneToJid untuk mengkonversi ke format yang benar
|
|
483
|
+
let jid;
|
|
484
|
+
if (isGroupChat) {
|
|
485
|
+
if (!toStr.endsWith('@g.us')) {
|
|
486
|
+
jid = toStr + '@g.us';
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
jid = toStr;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
jid = (0, Utils_1.phoneToJid)({ to, isGroup: isGroup || isGroupChat });
|
|
494
|
+
}
|
|
274
495
|
try {
|
|
275
496
|
// Deteksi apakah ini grup
|
|
276
|
-
const
|
|
277
|
-
const timeoutMs =
|
|
497
|
+
const isDestinationGroup = jid.endsWith('@g.us');
|
|
498
|
+
const timeoutMs = isDestinationGroup ? 5000 : 10000;
|
|
278
499
|
// Kirim status mengetik dengan timeout
|
|
279
|
-
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing",
|
|
500
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing", jid), timeoutMs, `Timeout saat mengirim status mengetik`);
|
|
280
501
|
// Tunggu durasi yang ditentukan
|
|
281
502
|
yield (0, create_delay_1.createDelay)(duration);
|
|
282
503
|
// Setelah durasi, atur kembali status
|
|
283
|
-
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused",
|
|
504
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused", jid), timeoutMs, `Timeout saat menghentikan status mengetik`);
|
|
284
505
|
}
|
|
285
506
|
catch (error) {
|
|
286
507
|
// Jika koneksi tertutup, coba reconnect
|
|
@@ -289,11 +510,11 @@ const sendTyping = (_a) => __awaiter(void 0, [_a], void 0, function* ({ sessionI
|
|
|
289
510
|
yield (0, Socket_1.reconnect)(sessionId);
|
|
290
511
|
yield (0, create_delay_1.createDelay)(2000); // Beri waktu untuk reconnect sepenuhnya
|
|
291
512
|
// Setelah reconnect, coba kirim status mengetik lagi
|
|
292
|
-
const
|
|
293
|
-
const timeoutMs =
|
|
294
|
-
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing",
|
|
513
|
+
const isDestinationGroup = jid.endsWith('@g.us');
|
|
514
|
+
const timeoutMs = isDestinationGroup ? 5000 : 10000;
|
|
515
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("composing", jid), timeoutMs, `Timeout saat mengirim status mengetik setelah reconnect`);
|
|
295
516
|
yield (0, create_delay_1.createDelay)(duration);
|
|
296
|
-
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused",
|
|
517
|
+
yield (0, create_delay_1.withTimeout)(session.sendPresenceUpdate("paused", jid), timeoutMs, `Timeout saat menghentikan status mengetik setelah reconnect`);
|
|
297
518
|
}
|
|
298
519
|
catch (reconnectError) {
|
|
299
520
|
// Tidak melempar error agar aplikasi tetap berjalan
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wa-multi-mongodb",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.1",
|
|
4
4
|
"description": "Multi Session Whatsapp Library with MongoDB Integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/wahdalo/wa-multi-mongodb"
|
|
30
|
+
"url": "git+https://github.com/wahdalo/wa-multi-mongodb.git"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/mime": "^3.0.1",
|
package/readme.md
CHANGED
|
@@ -16,6 +16,7 @@ Built on [Baileys](https://github.com/WhiskeySockets/Baileys) Library.
|
|
|
16
16
|
- Auto-reconnect when connection is lost
|
|
17
17
|
- Better group chat support
|
|
18
18
|
- Automatic retry for failed message deliveries
|
|
19
|
+
- Automatic group chat detection (v3.9.0+)
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
21
22
|
|
|
@@ -123,8 +124,25 @@ await whatsapp.loadSessionsFromMongo();
|
|
|
123
124
|
await whatsapp.sendTextMessage({
|
|
124
125
|
sessionId: "mysession",
|
|
125
126
|
to: "6281234567890", // always include country code
|
|
126
|
-
text: "Hello from wa-multi-mongodb!"
|
|
127
|
-
|
|
127
|
+
text: "Hello from wa-multi-mongodb!"
|
|
128
|
+
// isGroup parameter is optional (v3.9.0+)
|
|
129
|
+
// The library will automatically detect if the destination is a group
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Send to a group (automatic detection in v3.9.0+)
|
|
133
|
+
await whatsapp.sendTextMessage({
|
|
134
|
+
sessionId: "mysession",
|
|
135
|
+
to: "120363152682073800", // group ID
|
|
136
|
+
text: "Hello group!"
|
|
137
|
+
// No need for isGroup: true parameter in v3.9.0+
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Send to a group (compatible with older versions)
|
|
141
|
+
await whatsapp.sendTextMessage({
|
|
142
|
+
sessionId: "mysession",
|
|
143
|
+
to: "120363152682073800", // group ID
|
|
144
|
+
text: "Hello group!",
|
|
145
|
+
isGroup: true // still works but optional in v3.9.0+
|
|
128
146
|
});
|
|
129
147
|
|
|
130
148
|
// Send media (unified function)
|
|
@@ -135,7 +153,7 @@ await whatsapp.sendMedia({
|
|
|
135
153
|
media: fs.readFileSync("./image.jpg"), // or URL string
|
|
136
154
|
caption: "Image caption",
|
|
137
155
|
fileName: "image.jpg", // required for documents
|
|
138
|
-
isGroup
|
|
156
|
+
// isGroup parameter is optional (v3.9.0+)
|
|
139
157
|
});
|
|
140
158
|
|
|
141
159
|
// Send voice note
|
|
@@ -143,6 +161,7 @@ await whatsapp.sendVoiceNote({
|
|
|
143
161
|
sessionId: "mysession",
|
|
144
162
|
to: "6281234567890",
|
|
145
163
|
media: fs.readFileSync("./audio.mp3"),
|
|
164
|
+
// isGroup parameter is optional (v3.9.0+)
|
|
146
165
|
});
|
|
147
166
|
|
|
148
167
|
// Mark message as read
|
|
@@ -151,23 +170,15 @@ await whatsapp.readMessage({
|
|
|
151
170
|
key: msg.key,
|
|
152
171
|
});
|
|
153
172
|
|
|
154
|
-
// Send typing indicator
|
|
173
|
+
// Send typing indicator
|
|
155
174
|
await whatsapp.sendTyping({
|
|
156
175
|
sessionId: "mysession",
|
|
157
|
-
to: "6281234567890",
|
|
176
|
+
to: "6281234567890", // or group ID
|
|
158
177
|
duration: 3000, // milliseconds
|
|
178
|
+
// isGroup parameter is optional (v3.9.0+)
|
|
159
179
|
});
|
|
160
180
|
```
|
|
161
181
|
|
|
162
|
-
> **⚠️ Important:** The "typing" indicator **only works in private chats**. Always check if you're messaging a group:
|
|
163
|
-
>
|
|
164
|
-
> ```js
|
|
165
|
-
> const isGroup = remoteJid.endsWith('@g.us');
|
|
166
|
-
> if (!isGroup) {
|
|
167
|
-
> await whatsapp.sendTyping({...});
|
|
168
|
-
> }
|
|
169
|
-
> ```
|
|
170
|
-
|
|
171
182
|
### Event Listeners
|
|
172
183
|
|
|
173
184
|
```javascript
|
|
@@ -296,8 +307,8 @@ async function startApp() {
|
|
|
296
307
|
if (msg.key.fromMe || msg.key.remoteJid.includes("status")) return;
|
|
297
308
|
|
|
298
309
|
const messageContent = msg.message?.conversation ||
|
|
299
|
-
|
|
300
|
-
|
|
310
|
+
msg.message?.extendedTextMessage?.text ||
|
|
311
|
+
"";
|
|
301
312
|
|
|
302
313
|
// Detect if message is from a group
|
|
303
314
|
const isGroup = msg.key.remoteJid.endsWith('@g.us');
|
|
@@ -317,14 +328,12 @@ async function startApp() {
|
|
|
317
328
|
|
|
318
329
|
// Reply to messages containing "hello"
|
|
319
330
|
if (messageContent.toLowerCase().includes("hello")) {
|
|
320
|
-
// Show typing indicator (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
});
|
|
327
|
-
}
|
|
331
|
+
// Show typing indicator (works in both private and group chats since v3.9.1+)
|
|
332
|
+
await whatsapp.sendTyping({
|
|
333
|
+
sessionId: msg.sessionId,
|
|
334
|
+
to: msg.key.remoteJid,
|
|
335
|
+
duration: 2000,
|
|
336
|
+
});
|
|
328
337
|
|
|
329
338
|
// Use different timeouts for groups vs private chats
|
|
330
339
|
const timeoutMs = isGroup ? 60000 : 30000;
|
|
@@ -336,7 +345,7 @@ async function startApp() {
|
|
|
336
345
|
to: msg.key.remoteJid,
|
|
337
346
|
text: "Hello! How can I help you?",
|
|
338
347
|
answering: msg,
|
|
339
|
-
isGroup
|
|
348
|
+
// isGroup parameter is optional (v3.9.0+)
|
|
340
349
|
}),
|
|
341
350
|
timeoutMs,
|
|
342
351
|
"Message sending timed out"
|
|
@@ -379,20 +388,32 @@ startApp().catch(err => {
|
|
|
379
388
|
|
|
380
389
|
## Best Practices for Group Chats
|
|
381
390
|
|
|
382
|
-
1. **
|
|
383
|
-
2. **
|
|
391
|
+
1. **Auto Group Detection**: Since v3.9.0, the library automatically detects if a chat is a group based on its JID format
|
|
392
|
+
2. **Typing Indicators**: Typing indicators now work in both private and group chats (v3.9.1+)
|
|
384
393
|
3. **Longer Timeouts**: Use longer timeouts when sending media to groups (60+ seconds)
|
|
385
394
|
4. **Handle Errors**: Implement retry mechanisms for failed group messages
|
|
395
|
+
5. **Announcement Channels**: Groups with announcement channels may trigger `MessageCounterError` (handled automatically in v3.9.1+)
|
|
396
|
+
6. **Retry Strategy**: For announcement channel groups, the library will automatically retry sending messages up to 3 times with increasing delays
|
|
386
397
|
|
|
387
398
|
## WhatsApp Limitations
|
|
388
399
|
|
|
389
|
-
1. **
|
|
390
|
-
2. **
|
|
391
|
-
3. **
|
|
400
|
+
1. **Media Transfer**: Large media files to groups may take longer or timeout
|
|
401
|
+
2. **Connection Stability**: Auto-reconnect may be needed in production apps
|
|
402
|
+
3. **Announcement Channels**: Some groups with announcement channels may still fail after multiple retries
|
|
392
403
|
|
|
393
404
|
## Changelog
|
|
394
405
|
|
|
395
|
-
### v3.
|
|
406
|
+
### v3.9.1 (Current)
|
|
407
|
+
- Added special handling for `MessageCounterError` in group chats with announcement channels
|
|
408
|
+
- Implemented automatic retry mechanism for messages to announcement channels
|
|
409
|
+
- Enhanced error reporting for group chat issues
|
|
410
|
+
- Fixed typing indicators to work properly in group chats
|
|
411
|
+
- Added automatic group chat detection - no need to specify `isGroup: true` parameter
|
|
412
|
+
- Improved message sending reliability for group chats
|
|
413
|
+
- Enhanced error handling with better timeout management
|
|
414
|
+
- Implemented automatic format detection for group IDs
|
|
415
|
+
|
|
416
|
+
### v3.8.1
|
|
396
417
|
- Updated baileys to v6.7.16
|
|
397
418
|
- Improved MongoDB integration
|
|
398
419
|
- Enhanced error handling and connection stability
|