innovators-bot2 2.0.4 ā 2.0.6
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 +246 -12
- package/example.js +515 -181
- package/example.mp4 +0 -0
- package/index.js +308 -38
- package/package.json +2 -2
- package/publish-dual.js +0 -40
package/example.mp4
ADDED
|
Binary file
|
package/index.js
CHANGED
|
@@ -14,7 +14,17 @@ const {
|
|
|
14
14
|
// Anti-Delete
|
|
15
15
|
MessageStore,
|
|
16
16
|
createMessageStoreHandler,
|
|
17
|
-
createAntiDeleteHandler
|
|
17
|
+
createAntiDeleteHandler,
|
|
18
|
+
createTypingIndicator,
|
|
19
|
+
generateInteractiveButtonMessage,
|
|
20
|
+
generateInteractiveListMessage,
|
|
21
|
+
generateCombinedButtons,
|
|
22
|
+
generateCopyCodeButton,
|
|
23
|
+
generateUrlButtonMessage,
|
|
24
|
+
generateQuickReplyButtons,
|
|
25
|
+
StatusHelper,
|
|
26
|
+
STATUS_BACKGROUNDS,
|
|
27
|
+
STATUS_FONTS,
|
|
18
28
|
} = require('@innovatorssoft/baileys');
|
|
19
29
|
|
|
20
30
|
const { Sticker, StickerTypes } = require('wa-sticker-formatter');
|
|
@@ -117,18 +127,43 @@ class WhatsAppClient extends EventEmitter {
|
|
|
117
127
|
return jid.replace(/:\d+@/, '@');
|
|
118
128
|
}
|
|
119
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Internal helper to handle mentions and the "mention all" flag
|
|
132
|
+
* @param {string[]} mentions - Array of JIDs or keywords like 'all'/'@all'
|
|
133
|
+
* @param {boolean} mentionAll - Explicit mentionAll flag
|
|
134
|
+
* @returns {object} Object containing processed mentions and mentionAll flag
|
|
135
|
+
* @private
|
|
136
|
+
*/
|
|
137
|
+
_handleMentions(mentions, mentionAll) {
|
|
138
|
+
let processedMentions = mentions;
|
|
139
|
+
let finalMentionAll = mentionAll;
|
|
140
|
+
|
|
141
|
+
if (mentions && Array.isArray(mentions)) {
|
|
142
|
+
processedMentions = mentions
|
|
143
|
+
.filter(jid => jid !== 'all' && jid !== '@all')
|
|
144
|
+
.map(jid => this._normalizeJid(jid));
|
|
145
|
+
if (mentions.includes('all') || mentions.includes('@all')) {
|
|
146
|
+
finalMentionAll = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
mentions: processedMentions,
|
|
152
|
+
mentionAll: finalMentionAll
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
120
156
|
async connect() {
|
|
121
157
|
try {
|
|
158
|
+
if (this._connectionState === 'connecting' && this.sock) {
|
|
159
|
+
return; // Prevent concurrent connection attempts
|
|
160
|
+
}
|
|
122
161
|
|
|
123
162
|
if (this._connectionState !== 'connecting') {
|
|
124
163
|
this._connectionState = 'connecting';
|
|
125
164
|
this.emit('connecting', 'Connecting to WhatsApp...');
|
|
126
165
|
}
|
|
127
166
|
|
|
128
|
-
const browserConfig = this.authmethod === 'pairing'
|
|
129
|
-
? Browsers.iOS('chrome')
|
|
130
|
-
: ["Innovators Soft", "chrome", "1000.26100.275.0"];
|
|
131
|
-
|
|
132
167
|
const { version: baileysVersion, isLatest: baileysIsLatest } = await fetchLatestBaileysVersion();
|
|
133
168
|
const { version: waWebVersion, isLatest: waWebIsLatest } = await fetchLatestWaWebVersion();
|
|
134
169
|
|
|
@@ -142,13 +177,13 @@ class WhatsAppClient extends EventEmitter {
|
|
|
142
177
|
auth: state,
|
|
143
178
|
logger,
|
|
144
179
|
markOnlineOnConnect: false,
|
|
145
|
-
syncFullHistory:
|
|
180
|
+
syncFullHistory: false,
|
|
146
181
|
getMessage: async (key) => (this.messageStore.getOriginalMessage(key))?.message,
|
|
147
182
|
generateHighQualityLinkPreview: true,
|
|
148
183
|
linkPreviewImageThumbnailWidth: 192,
|
|
149
184
|
emitOwnEvents: true,
|
|
150
|
-
browser:
|
|
151
|
-
version:
|
|
185
|
+
browser: Browsers.android('Innovators Soft'),
|
|
186
|
+
version: baileysVersion,
|
|
152
187
|
cachedGroupMetadata: async (jid) => {
|
|
153
188
|
const cached = this.groupMetadataCache.get(jid);
|
|
154
189
|
if (cached) {
|
|
@@ -285,6 +320,10 @@ class WhatsAppClient extends EventEmitter {
|
|
|
285
320
|
// Save message store to file immediately
|
|
286
321
|
await this.saveMessageStore();
|
|
287
322
|
|
|
323
|
+
/*console.log('-'.repeat(50));
|
|
324
|
+
console.dir(update, { depth: null });
|
|
325
|
+
console.log('-'.repeat(50));*/
|
|
326
|
+
|
|
288
327
|
try {
|
|
289
328
|
if (update.type !== 'notify' || !update.messages?.length) return;
|
|
290
329
|
const [message] = update.messages;
|
|
@@ -295,19 +334,14 @@ class WhatsAppClient extends EventEmitter {
|
|
|
295
334
|
|
|
296
335
|
const msg = message.message || {};
|
|
297
336
|
|
|
337
|
+
let jid = this._normalizeJid(message.key.remoteJid);
|
|
298
338
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
// remoteJidAlt contains the alternate JID (PN if primary is LID, or vice versa)
|
|
303
|
-
if (typeof message.key.remoteJidAlt === 'string' &&
|
|
304
|
-
message.key.remoteJidAlt.endsWith('@s.whatsapp.net')
|
|
305
|
-
) {
|
|
306
|
-
jid = message.key.remoteJidAlt;
|
|
307
|
-
}
|
|
339
|
+
// Keep the original technical JID as the primary identifier for Signal sessions
|
|
340
|
+
// remoteJidAlt can be used if needed, but not to replace the primary jid for technical replies
|
|
341
|
+
const jidAlt = this._normalizeJid(message.key.remoteJidAlt) || null;
|
|
308
342
|
// Resolve the actual sender (preferring PN over LID)
|
|
309
|
-
const participant = message.key.participant || message.participant || null;
|
|
310
|
-
const participantAlt = message.key.participantAlt || null;
|
|
343
|
+
const participant = this._normalizeJid(message.key.participant || message.participant) || null;
|
|
344
|
+
const participantAlt = this._normalizeJid(message.key.participantAlt) || null;
|
|
311
345
|
|
|
312
346
|
let sender = jid;
|
|
313
347
|
if (jid.endsWith('@g.us') || jid === 'status@broadcast') {
|
|
@@ -395,6 +429,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
395
429
|
|
|
396
430
|
this.emit('message', {
|
|
397
431
|
from: jid,
|
|
432
|
+
fromAlt: jidAlt,
|
|
398
433
|
sender,
|
|
399
434
|
participant,
|
|
400
435
|
participantAlt,
|
|
@@ -421,13 +456,13 @@ class WhatsAppClient extends EventEmitter {
|
|
|
421
456
|
this.sock.ev.on('messages.update', (updates) => {
|
|
422
457
|
const deletedMessages = antiDeleteHandler(updates);
|
|
423
458
|
for (const info of deletedMessages) {
|
|
424
|
-
let jid = info.key.remoteJid;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}
|
|
459
|
+
let jid = this._normalizeJid(info.key.remoteJid);
|
|
460
|
+
// Use original remoteJid for technical identification
|
|
461
|
+
const jidAlt = this._normalizeJid(info.key.remoteJidAlt) || null;
|
|
428
462
|
|
|
429
463
|
this.emit('message-deleted', {
|
|
430
464
|
jid: jid,
|
|
465
|
+
jidAlt: jidAlt,
|
|
431
466
|
originalMessage: info.originalMessage,
|
|
432
467
|
key: info.key
|
|
433
468
|
});
|
|
@@ -440,16 +475,16 @@ class WhatsAppClient extends EventEmitter {
|
|
|
440
475
|
|
|
441
476
|
try {
|
|
442
477
|
for (const reaction of reactions) {
|
|
478
|
+
if (reaction.key?.fromMe) continue;
|
|
479
|
+
|
|
443
480
|
// Get the chat JID, preferring PN over LID
|
|
444
|
-
let jid = reaction.key.remoteJid;
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
jid = reaction.key.remoteJidAlt;
|
|
448
|
-
}
|
|
481
|
+
let jid = this._normalizeJid(reaction.key.remoteJid);
|
|
482
|
+
// Use original remoteJid for technical identification
|
|
483
|
+
const jidAlt = this._normalizeJid(reaction.key.remoteJidAlt) || null;
|
|
449
484
|
|
|
450
485
|
// Resolve the sender (who reacted), preferring PN over LID
|
|
451
|
-
const participant = reaction.key.participant || null;
|
|
452
|
-
const participantAlt = reaction.key.participantAlt || null;
|
|
486
|
+
const participant = this._normalizeJid(reaction.key.participant) || null;
|
|
487
|
+
const participantAlt = this._normalizeJid(reaction.key.participantAlt) || null;
|
|
453
488
|
|
|
454
489
|
let sender = jid;
|
|
455
490
|
if (jid.endsWith('@g.us') || jid === 'status@broadcast') {
|
|
@@ -464,6 +499,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
464
499
|
// Emit the reaction event
|
|
465
500
|
this.emit('message-reaction', {
|
|
466
501
|
from: jid,
|
|
502
|
+
fromAlt: jidAlt,
|
|
467
503
|
sender: sender,
|
|
468
504
|
participant: participant,
|
|
469
505
|
participantAlt: participantAlt,
|
|
@@ -604,6 +640,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
604
640
|
* @throws {Error} If client is not connected or message sending fails
|
|
605
641
|
*/
|
|
606
642
|
async sendMessage(chatId, message, options = {}) {
|
|
643
|
+
chatId = this._normalizeJid(chatId);
|
|
607
644
|
if (!this.isConnected) {
|
|
608
645
|
throw new Error('Client is not connected');
|
|
609
646
|
}
|
|
@@ -618,9 +655,9 @@ class WhatsAppClient extends EventEmitter {
|
|
|
618
655
|
switch (message.type) {
|
|
619
656
|
case 'text':
|
|
620
657
|
messageContent = { text: message.text };
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
658
|
+
const { mentions: textMentions, mentionAll: textMentionAll } = this._handleMentions(message.mentions, message.mentionAll);
|
|
659
|
+
if (textMentions) messageContent.mentions = textMentions;
|
|
660
|
+
if (textMentionAll !== undefined) messageContent.mentionAll = textMentionAll;
|
|
624
661
|
break;
|
|
625
662
|
|
|
626
663
|
case 'location':
|
|
@@ -682,6 +719,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
682
719
|
* @throws {Error} If client is not connected or file not found
|
|
683
720
|
*/
|
|
684
721
|
async sendMedia(chatId, filePath, options = {}) {
|
|
722
|
+
chatId = this._normalizeJid(chatId);
|
|
685
723
|
if (!this.isConnected) {
|
|
686
724
|
throw new Error('Client is not connected');
|
|
687
725
|
}
|
|
@@ -733,9 +771,9 @@ class WhatsAppClient extends EventEmitter {
|
|
|
733
771
|
throw new Error('Unsupported file type: ' + fileExtension);
|
|
734
772
|
}
|
|
735
773
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
774
|
+
const { mentions: mediaMentions, mentionAll: mediaMentionAll } = this._handleMentions(options.mentions, options.mentionAll);
|
|
775
|
+
if (mediaMentions) mediaMessage.mentions = mediaMentions;
|
|
776
|
+
if (mediaMentionAll !== undefined) mediaMessage.mentionAll = mediaMentionAll;
|
|
739
777
|
|
|
740
778
|
return await this.sock.sendMessage(chatId, mediaMessage, { ai: true });
|
|
741
779
|
} catch (error) {
|
|
@@ -753,6 +791,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
753
791
|
* @throws {Error} If client is not connected or file not found
|
|
754
792
|
*/
|
|
755
793
|
async sendDocument(chatId, filePath, caption = '') {
|
|
794
|
+
chatId = this._normalizeJid(chatId);
|
|
756
795
|
if (!this.isConnected) {
|
|
757
796
|
throw new Error('Client is not connected');
|
|
758
797
|
}
|
|
@@ -776,7 +815,10 @@ class WhatsAppClient extends EventEmitter {
|
|
|
776
815
|
|
|
777
816
|
if (typeof caption === 'object' && caption !== null) {
|
|
778
817
|
if (caption.caption) messageContent.caption = caption.caption;
|
|
779
|
-
|
|
818
|
+
|
|
819
|
+
const { mentions: docMentions, mentionAll: docMentionAll } = this._handleMentions(caption.mentions, caption.mentionAll);
|
|
820
|
+
if (docMentions) messageContent.mentions = docMentions;
|
|
821
|
+
if (docMentionAll !== undefined) messageContent.mentionAll = docMentionAll;
|
|
780
822
|
}
|
|
781
823
|
|
|
782
824
|
return await this.sock.sendMessage(chatId, {
|
|
@@ -804,6 +846,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
804
846
|
* @throws {Error} If client is not connected or message sending fails
|
|
805
847
|
*/
|
|
806
848
|
async sendButtons(chatId, options = {}, extraOptions = {}) {
|
|
849
|
+
chatId = this._normalizeJid(chatId);
|
|
807
850
|
if (!this.isConnected) {
|
|
808
851
|
throw new Error('Client is not connected');
|
|
809
852
|
}
|
|
@@ -886,7 +929,9 @@ class WhatsAppClient extends EventEmitter {
|
|
|
886
929
|
* @returns {Promise<object>} The sent message info
|
|
887
930
|
* @throws {Error} If client is not connected or message sending fails
|
|
888
931
|
*/
|
|
932
|
+
|
|
889
933
|
async SendList(chatId, listOptions) {
|
|
934
|
+
chatId = this._normalizeJid(chatId);
|
|
890
935
|
if (!this.isConnected) {
|
|
891
936
|
throw new Error('Client is not connected');
|
|
892
937
|
}
|
|
@@ -913,6 +958,97 @@ class WhatsAppClient extends EventEmitter {
|
|
|
913
958
|
throw error;
|
|
914
959
|
}
|
|
915
960
|
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Send Quick Reply Buttons (V2)
|
|
964
|
+
* @param {string} jid - Target JID
|
|
965
|
+
* @param {string} text - Message text
|
|
966
|
+
* @param {Array<object>} buttons - Array of { id, displayText }
|
|
967
|
+
* @param {object} options - { footer }
|
|
968
|
+
*/
|
|
969
|
+
async sendQuickReplyV2(jid, text, buttons, options = {}) {
|
|
970
|
+
jid = this._normalizeJid(jid);
|
|
971
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
972
|
+
const message = generateQuickReplyButtons(text, buttons, options);
|
|
973
|
+
return await this.sock.sendMessage(jid, message, { ai: true });
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* Send Generic Interactive Button Message (V2)
|
|
978
|
+
* @param {string} jid - Target JID
|
|
979
|
+
* @param {object} options - Button options
|
|
980
|
+
*/
|
|
981
|
+
async sendInteractiveButtonV2(jid, options) {
|
|
982
|
+
jid = this._normalizeJid(jid);
|
|
983
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
984
|
+
const message = generateInteractiveButtonMessage(options);
|
|
985
|
+
return await this.sock.sendMessage(jid, message, { ai: true });
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* Send URL Button (V2)
|
|
990
|
+
* @param {string} jid - Target JID
|
|
991
|
+
* @param {string} text - Message text
|
|
992
|
+
* @param {Array<object>} buttons - Array of { displayText, url }
|
|
993
|
+
* @param {object} options - { title, footer }
|
|
994
|
+
*/
|
|
995
|
+
async sendUrlButtonV2(jid, text, buttons, options = {}) {
|
|
996
|
+
jid = this._normalizeJid(jid);
|
|
997
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
998
|
+
const message = generateUrlButtonMessage(text, buttons, options);
|
|
999
|
+
return await this.sock.sendMessage(jid, message, { ai: true });
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
* Send Copy Code Button (V2)
|
|
1004
|
+
* @param {string} jid - Target JID
|
|
1005
|
+
* @param {string} text - Message text
|
|
1006
|
+
* @param {string} code - Code to be copied
|
|
1007
|
+
* @param {string} buttonText - Text on the copy button
|
|
1008
|
+
*/
|
|
1009
|
+
async sendCopyCodeV2(jid, text, code, buttonText) {
|
|
1010
|
+
jid = this._normalizeJid(jid);
|
|
1011
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
1012
|
+
const message = generateCopyCodeButton(text, code, buttonText);
|
|
1013
|
+
return await this.sock.sendMessage(jid, message, { ai: true });
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Send Combined Buttons (V2)
|
|
1018
|
+
* @param {string} jid - Target JID
|
|
1019
|
+
* @param {string} text - Message text
|
|
1020
|
+
* @param {Array<object>} buttons - Mix of { type: 'reply'|'url'|'call'|'copy', ... }
|
|
1021
|
+
* @param {object} options - { title, footer }
|
|
1022
|
+
*/
|
|
1023
|
+
async sendCombinedButtonsV2(jid, text, buttons, options = {}) {
|
|
1024
|
+
jid = this._normalizeJid(jid);
|
|
1025
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
1026
|
+
const message = generateCombinedButtons(text, buttons, options);
|
|
1027
|
+
return await this.sock.sendMessage(jid, message, { ai: true });
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Send Interactive List Message (V2)
|
|
1032
|
+
* @param {string} jid - Target JID
|
|
1033
|
+
* @param {object} options - List options (title, buttonText, description, footer, sections)
|
|
1034
|
+
*/
|
|
1035
|
+
async sendListV2(jid, options) {
|
|
1036
|
+
jid = this._normalizeJid(jid);
|
|
1037
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
1038
|
+
const message = generateInteractiveListMessage(options);
|
|
1039
|
+
return await this.sock.relayMessage(jid, message, { ai: true });
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Send Buttons Cards Message
|
|
1044
|
+
* @param {string} jid - Target JID
|
|
1045
|
+
* @param {object} options - Cards options (text, title, subtile, footer, cards)
|
|
1046
|
+
*/
|
|
1047
|
+
async sendcards(jid, options) {
|
|
1048
|
+
jid = this._normalizeJid(jid);
|
|
1049
|
+
if (!this.isConnected) throw new Error('Client is not connected');
|
|
1050
|
+
return await this.sock.sendMessage(jid, options, { ai: true });
|
|
1051
|
+
}
|
|
916
1052
|
/**
|
|
917
1053
|
* Send an external ad reply with a local image
|
|
918
1054
|
* @param {string} number - The phone number to send the ad to
|
|
@@ -924,6 +1060,7 @@ class WhatsAppClient extends EventEmitter {
|
|
|
924
1060
|
*/
|
|
925
1061
|
|
|
926
1062
|
async sendAdReply(number, msg, imgpath, title, body, sourceurl) {
|
|
1063
|
+
number = this._normalizeJid(number);
|
|
927
1064
|
if (!this.isConnected) {
|
|
928
1065
|
throw new Error('Client is not connected');
|
|
929
1066
|
}
|
|
@@ -993,7 +1130,8 @@ class WhatsAppClient extends EventEmitter {
|
|
|
993
1130
|
const results = [];
|
|
994
1131
|
|
|
995
1132
|
try {
|
|
996
|
-
for (
|
|
1133
|
+
for (let participantId of participantIds) {
|
|
1134
|
+
participantId = this._normalizeJid(participantId);
|
|
997
1135
|
try {
|
|
998
1136
|
let updateResult = await this.sock.groupParticipantsUpdate(
|
|
999
1137
|
groupId,
|
|
@@ -1294,6 +1432,17 @@ class WhatsAppClient extends EventEmitter {
|
|
|
1294
1432
|
await this.sock.sendPresenceUpdate("paused", jid);
|
|
1295
1433
|
}
|
|
1296
1434
|
|
|
1435
|
+
/**
|
|
1436
|
+
* Create a typing indicator controller for manual or standalone presence control
|
|
1437
|
+
* @returns {object} The typing indicator controller
|
|
1438
|
+
*/
|
|
1439
|
+
createPresenceController() {
|
|
1440
|
+
if (!this.sock) throw new Error('Client is not connected');
|
|
1441
|
+
return createTypingIndicator(
|
|
1442
|
+
(jid, presence) => this.sock.sendPresenceUpdate(presence, jid)
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1297
1446
|
/**
|
|
1298
1447
|
* Reinitialize the WhatsApp client by clearing the session and reconnecting
|
|
1299
1448
|
* @returns {Promise<void>}
|
|
@@ -2374,6 +2523,42 @@ class WhatsAppClient extends EventEmitter {
|
|
|
2374
2523
|
}
|
|
2375
2524
|
}
|
|
2376
2525
|
|
|
2526
|
+
/**
|
|
2527
|
+
* Update profile status (about)
|
|
2528
|
+
* @param {string} status - The new status message
|
|
2529
|
+
* @returns {Promise<void>}
|
|
2530
|
+
* @throws {Error} If client is not connected or update fails
|
|
2531
|
+
*/
|
|
2532
|
+
async updateProfileStatus(status) {
|
|
2533
|
+
if (!this.isConnected) {
|
|
2534
|
+
throw new Error('Client is not connected');
|
|
2535
|
+
}
|
|
2536
|
+
try {
|
|
2537
|
+
await this.sock.updateProfileStatus(status);
|
|
2538
|
+
} catch (error) {
|
|
2539
|
+
console.error('Error updating profile status:', error);
|
|
2540
|
+
throw error;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
/**
|
|
2545
|
+
* Update profile name
|
|
2546
|
+
* @param {string} name - The new profile name
|
|
2547
|
+
* @returns {Promise<void>}
|
|
2548
|
+
* @throws {Error} If client is not connected or update fails
|
|
2549
|
+
*/
|
|
2550
|
+
async updateProfileName(name) {
|
|
2551
|
+
if (!this.isConnected) {
|
|
2552
|
+
throw new Error('Client is not connected');
|
|
2553
|
+
}
|
|
2554
|
+
try {
|
|
2555
|
+
await this.sock.updateProfileName(name);
|
|
2556
|
+
} catch (error) {
|
|
2557
|
+
console.error('Error updating profile name:', error);
|
|
2558
|
+
throw error;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2377
2562
|
/**
|
|
2378
2563
|
* Add EXIF metadata to an existing WebP buffer
|
|
2379
2564
|
* @param {Buffer} buffer - WebP buffer
|
|
@@ -2392,6 +2577,89 @@ class WhatsAppClient extends EventEmitter {
|
|
|
2392
2577
|
throw error;
|
|
2393
2578
|
}
|
|
2394
2579
|
}
|
|
2580
|
+
|
|
2581
|
+
/**
|
|
2582
|
+
* Post a status update (story) with various media types and styles
|
|
2583
|
+
* @param {object} options Options for the status update
|
|
2584
|
+
* @param {string} [options.text] Text content for a text status
|
|
2585
|
+
* @param {string|number[]} [options.backgroundColor] Background color for text status (hex or array of rgb)
|
|
2586
|
+
* @param {number} [options.font] Font type for text status (1-5)
|
|
2587
|
+
* @param {string} [options.textColor] Text color (hex)
|
|
2588
|
+
* @param {string} [options.imagePath] Path to image file for image status
|
|
2589
|
+
* @param {string} [options.videoPath] Path to video file for video status
|
|
2590
|
+
* @param {string} [options.audioPath] Path to audio file for voice note status
|
|
2591
|
+
* @param {Buffer} [options.imageBuffer] Buffer containing image data
|
|
2592
|
+
* @param {Buffer} [options.videoBuffer] Buffer containing video data
|
|
2593
|
+
* @param {Buffer} [options.audioBuffer] Buffer containing audio data
|
|
2594
|
+
* @param {string} [options.caption] Caption for image or video status
|
|
2595
|
+
* @param {boolean} [options.isGif=false] Whether the video should be played as a GIF
|
|
2596
|
+
* @param {Array<string>} [contacts=[]] List of JIDs who should receive the status (important for Multi-Device)
|
|
2597
|
+
* @returns {Promise<object>} The sent message info
|
|
2598
|
+
* @throws {Error} If client is not connected or options are invalid
|
|
2599
|
+
*/
|
|
2600
|
+
async sendStatus(options = {}, contacts = []) {
|
|
2601
|
+
if (!this.isConnected) {
|
|
2602
|
+
throw new Error('Client is not connected');
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
try {
|
|
2606
|
+
let statusMessage;
|
|
2607
|
+
|
|
2608
|
+
// Voice Note Status
|
|
2609
|
+
if (options.audioPath || options.audioBuffer) {
|
|
2610
|
+
const buffer = options.audioBuffer || fs.readFileSync(options.audioPath);
|
|
2611
|
+
statusMessage = StatusHelper.voiceNote(buffer);
|
|
2612
|
+
}
|
|
2613
|
+
// Image Status
|
|
2614
|
+
else if (options.imagePath || options.imageBuffer) {
|
|
2615
|
+
const buffer = options.imageBuffer || fs.readFileSync(options.imagePath);
|
|
2616
|
+
statusMessage = StatusHelper.image(buffer, options.caption || '');
|
|
2617
|
+
}
|
|
2618
|
+
// Video / GIF Status
|
|
2619
|
+
else if (options.videoPath || options.videoBuffer) {
|
|
2620
|
+
const buffer = options.videoBuffer || fs.readFileSync(options.videoPath);
|
|
2621
|
+
if (options.isGif) {
|
|
2622
|
+
statusMessage = StatusHelper.gif(buffer, options.caption || '');
|
|
2623
|
+
} else {
|
|
2624
|
+
statusMessage = StatusHelper.video(buffer, options.caption || '');
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
// Text Status
|
|
2628
|
+
else if (options.text) {
|
|
2629
|
+
statusMessage = StatusHelper.text(
|
|
2630
|
+
options.text,
|
|
2631
|
+
options.backgroundColor || STATUS_BACKGROUNDS.solid.purple,
|
|
2632
|
+
options.font || STATUS_FONTS.SANS_SERIF,
|
|
2633
|
+
options.textColor
|
|
2634
|
+
);
|
|
2635
|
+
} else {
|
|
2636
|
+
throw new Error('Invalid status options: Provide text, image, video, or audio.');
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
// Send using the new StatusHelper
|
|
2640
|
+
return await StatusHelper.send(this.sock, statusMessage, contacts);
|
|
2641
|
+
|
|
2642
|
+
} catch (error) {
|
|
2643
|
+
console.error('Error sending status:', error);
|
|
2644
|
+
throw error;
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
async sendGroupStatus(jid, content = {}, options = {}) {
|
|
2649
|
+
if (!this.isConnected) {
|
|
2650
|
+
throw new Error('Client is not connected');
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
if (!jid || typeof jid !== 'string' || !jid.endsWith('@g.us')) {
|
|
2654
|
+
throw new Error('Invalid group JID. Expected a JID ending with @g.us');
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
if (!content || typeof content !== 'object') {
|
|
2658
|
+
throw new Error('Invalid content. Expected an object');
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
return await this.sock.sendMessage(jid, { ...content, groupStatus: true }, options);
|
|
2662
|
+
}
|
|
2395
2663
|
}
|
|
2396
2664
|
|
|
2397
2665
|
function formatCode(code) {
|
|
@@ -2404,4 +2672,6 @@ function formatCode(code) {
|
|
|
2404
2672
|
module.exports = {
|
|
2405
2673
|
WhatsAppClient: WhatsAppClient,
|
|
2406
2674
|
Group: Group,
|
|
2675
|
+
STATUS_BACKGROUNDS,
|
|
2676
|
+
STATUS_FONTS
|
|
2407
2677
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "innovators-bot2",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "WhatsApp API",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/innovatorssoft/WhatsAppAPI?tab=readme-ov-file#whatsapp-api",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@innovatorssoft/baileys": "
|
|
33
|
+
"@innovatorssoft/baileys": "^7.4.3",
|
|
34
34
|
"figlet": "^1.8.0",
|
|
35
35
|
"mime": "^3.0.0",
|
|
36
36
|
"mime-types": "^2.1.35",
|
package/publish-dual.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const { execSync } = require('child_process');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
const packagePath = path.join(__dirname, 'package.json');
|
|
6
|
-
|
|
7
|
-
// Read the original package.json
|
|
8
|
-
const originalPackage = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
9
|
-
const originalName = originalPackage.name;
|
|
10
|
-
|
|
11
|
-
console.log('š Starting dual npm publish...\n');
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
// Step 1: Publish as unscoped package (innovators-bot2)
|
|
15
|
-
console.log(`š¦ Publishing as "${originalName}"...`);
|
|
16
|
-
execSync('npm publish', { stdio: 'inherit', cwd: __dirname });
|
|
17
|
-
console.log(`ā
Successfully published "${originalName}"\n`);
|
|
18
|
-
|
|
19
|
-
// Step 2: Change name to scoped package
|
|
20
|
-
const scopedName = '@innovatorssoft/innovators-bot2';
|
|
21
|
-
console.log(`š¦ Publishing as "${scopedName}"...`);
|
|
22
|
-
|
|
23
|
-
originalPackage.name = scopedName;
|
|
24
|
-
fs.writeFileSync(packagePath, JSON.stringify(originalPackage, null, 2) + '\n');
|
|
25
|
-
|
|
26
|
-
// Step 3: Publish as scoped package with public access
|
|
27
|
-
execSync('npm publish --access public', { stdio: 'inherit', cwd: __dirname });
|
|
28
|
-
console.log(`ā
Successfully published "${scopedName}"\n`);
|
|
29
|
-
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('ā Error during publish:', error.message);
|
|
32
|
-
process.exitCode = 1;
|
|
33
|
-
} finally {
|
|
34
|
-
// Step 4: Always restore original package.json
|
|
35
|
-
console.log('š Restoring original package.json...');
|
|
36
|
-
originalPackage.name = originalName;
|
|
37
|
-
fs.writeFileSync(packagePath, JSON.stringify(originalPackage, null, 2) + '\n');
|
|
38
|
-
console.log('ā
Original package.json restored');
|
|
39
|
-
console.log('\nš Dual publish complete!');
|
|
40
|
-
}
|