whatsapp-pi 1.0.57 → 1.0.59
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/package.json +1 -1
- package/src/i18n.ts +0 -10
- package/src/models/whatsapp.types.ts +0 -2
- package/src/services/session.manager.ts +5 -36
- package/src/services/whatsapp.service.ts +12 -31
- package/src/ui/menu.handler.ts +1 -32
package/package.json
CHANGED
package/src/i18n.ts
CHANGED
|
@@ -109,11 +109,6 @@ const fallback = {
|
|
|
109
109
|
"menu.allowedGroups.group.history": "History",
|
|
110
110
|
"menu.allowedGroups.group.sendMessage": "Send Message",
|
|
111
111
|
"menu.allowedGroups.group.printGroup": "Print Group JID",
|
|
112
|
-
"menu.allowedGroups.group.reactionMode": "Reaction Mode",
|
|
113
|
-
"menu.allowedGroups.group.reactionMode.title": "Reaction Mode • {displayName}",
|
|
114
|
-
"menu.allowedGroups.group.reactionMode.active": "Active",
|
|
115
|
-
"menu.allowedGroups.group.reactionMode.passive": "Passive",
|
|
116
|
-
"menu.allowedGroups.group.reactionMode.updated": "Reaction mode set to {mode} for {displayName}",
|
|
117
112
|
"menu.allowedGroups.group.removeAlias": "Remove Alias",
|
|
118
113
|
"menu.allowedGroups.group.addAlias": "Add Alias",
|
|
119
114
|
"menu.allowedGroups.group.removeGroup": "Remove Group",
|
|
@@ -327,11 +322,6 @@ const translations: Record<Locale, Partial<Record<Key, string>>> = {
|
|
|
327
322
|
"menu.allowedGroups.group.history": "Histórico",
|
|
328
323
|
"menu.allowedGroups.group.sendMessage": "Enviar mensagem",
|
|
329
324
|
"menu.allowedGroups.group.printGroup": "Mostrar JID do grupo",
|
|
330
|
-
"menu.allowedGroups.group.reactionMode": "Modo de reação",
|
|
331
|
-
"menu.allowedGroups.group.reactionMode.title": "Modo de reação • {displayName}",
|
|
332
|
-
"menu.allowedGroups.group.reactionMode.active": "Ativo",
|
|
333
|
-
"menu.allowedGroups.group.reactionMode.passive": "Passivo",
|
|
334
|
-
"menu.allowedGroups.group.reactionMode.updated": "Modo de reação definido como {mode} para {displayName}",
|
|
335
325
|
"menu.allowedGroups.group.removeAlias": "Remover apelido",
|
|
336
326
|
"menu.allowedGroups.group.addAlias": "Adicionar apelido",
|
|
337
327
|
"menu.allowedGroups.group.removeGroup": "Remover grupo",
|
|
@@ -2,14 +2,13 @@ import { useMultiFileAuthState } from 'baileys';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { readFile, writeFile, mkdir, rm, rename } from 'fs/promises';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
|
-
import { SessionStatus
|
|
5
|
+
import { SessionStatus } from '../models/whatsapp.types.js';
|
|
6
6
|
import { t } from '../i18n.js';
|
|
7
7
|
|
|
8
8
|
export interface Contact {
|
|
9
9
|
number: string;
|
|
10
10
|
name?: string;
|
|
11
11
|
sendNumber?: string;
|
|
12
|
-
reactionMode?: ReactionMode;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export class SessionManager {
|
|
@@ -75,11 +74,8 @@ export class SessionManager {
|
|
|
75
74
|
num = num.number;
|
|
76
75
|
}
|
|
77
76
|
if (typeof num === 'string') {
|
|
78
|
-
const reactionMode = item.reactionMode === 'active' || item.reactionMode === 'passive'
|
|
79
|
-
? item.reactionMode
|
|
80
|
-
: undefined;
|
|
81
77
|
const sendNumber = typeof item.sendNumber === 'string' ? item.sendNumber : undefined;
|
|
82
|
-
return { number: num, name: item.name, sendNumber
|
|
78
|
+
return { number: num, name: item.name, sendNumber };
|
|
83
79
|
}
|
|
84
80
|
}
|
|
85
81
|
return null;
|
|
@@ -88,8 +84,6 @@ export class SessionManager {
|
|
|
88
84
|
const loadedAllowList = (config.allowList || []).map(cleanContact).filter(Boolean) as Contact[];
|
|
89
85
|
const loadedAllowedGroups = (config.allowedGroups || []).map(cleanContact).filter(Boolean) as Contact[];
|
|
90
86
|
const migratedGroups = loadedAllowList.filter(c => SessionManager.isGroupJid(c.number));
|
|
91
|
-
const needsReactionModeBackfill = loadedAllowedGroups.some(group => !group.reactionMode)
|
|
92
|
-
|| migratedGroups.some(group => !group.reactionMode);
|
|
93
87
|
this.allowList = loadedAllowList.filter(c => !SessionManager.isGroupJid(c.number));
|
|
94
88
|
this.allowedGroups = this.mergeContacts(loadedAllowedGroups, migratedGroups);
|
|
95
89
|
this.ignoredNumbers = (config.ignoredNumbers || []).map(cleanContact).filter(Boolean) as Contact[];
|
|
@@ -99,7 +93,7 @@ export class SessionManager {
|
|
|
99
93
|
this.visionModel = config.visionModel || 'gpt-4o';
|
|
100
94
|
this.operatorJid = config.operatorJid || '';
|
|
101
95
|
|
|
102
|
-
if (recovered
|
|
96
|
+
if (recovered) {
|
|
103
97
|
await this.saveConfig();
|
|
104
98
|
}
|
|
105
99
|
} catch {
|
|
@@ -258,7 +252,7 @@ export class SessionManager {
|
|
|
258
252
|
|
|
259
253
|
const existing = this.allowedGroups.find(c => c.number === groupJid);
|
|
260
254
|
if (!existing) {
|
|
261
|
-
this.allowedGroups.push({ number: groupJid, name
|
|
255
|
+
this.allowedGroups.push({ number: groupJid, name });
|
|
262
256
|
this.ignoredNumbers = this.ignoredNumbers.filter(c => c.number !== groupJid);
|
|
263
257
|
await this.saveConfig();
|
|
264
258
|
return;
|
|
@@ -268,11 +262,6 @@ export class SessionManager {
|
|
|
268
262
|
existing.name = name;
|
|
269
263
|
await this.saveConfig();
|
|
270
264
|
}
|
|
271
|
-
|
|
272
|
-
if (!existing.reactionMode) {
|
|
273
|
-
existing.reactionMode = 'active';
|
|
274
|
-
await this.saveConfig();
|
|
275
|
-
}
|
|
276
265
|
}
|
|
277
266
|
|
|
278
267
|
async removeAllowedGroup(groupJid: string) {
|
|
@@ -334,20 +323,6 @@ export class SessionManager {
|
|
|
334
323
|
await this.saveConfig();
|
|
335
324
|
}
|
|
336
325
|
|
|
337
|
-
getAllowedGroupReactionMode(groupJid: string): ReactionMode {
|
|
338
|
-
return this.getAllowedGroup(groupJid)?.reactionMode || 'active';
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
async setAllowedGroupReactionMode(groupJid: string, reactionMode: ReactionMode) {
|
|
342
|
-
const group = this.getAllowedGroup(groupJid);
|
|
343
|
-
if (!group) {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
group.reactionMode = reactionMode;
|
|
348
|
-
await this.saveConfig();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
326
|
async removeAllowedGroupAlias(groupJid: string) {
|
|
352
327
|
const group = this.getAllowedGroup(groupJid);
|
|
353
328
|
if (!group || !group.name) {
|
|
@@ -391,15 +366,9 @@ export class SessionManager {
|
|
|
391
366
|
if (!existing.name && contact.name) {
|
|
392
367
|
existing.name = contact.name;
|
|
393
368
|
}
|
|
394
|
-
if (!existing.reactionMode && contact.reactionMode) {
|
|
395
|
-
existing.reactionMode = contact.reactionMode;
|
|
396
|
-
}
|
|
397
369
|
}
|
|
398
370
|
}
|
|
399
|
-
return merged
|
|
400
|
-
...contact,
|
|
401
|
-
reactionMode: contact.reactionMode || 'active'
|
|
402
|
-
}));
|
|
371
|
+
return merged;
|
|
403
372
|
}
|
|
404
373
|
|
|
405
374
|
public async isRegistered(): Promise<boolean> {
|
|
@@ -46,12 +46,23 @@ interface IncomingMessageContextInfo {
|
|
|
46
46
|
mentionedJid?: string[];
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
interface IncomingMessageWithContext {
|
|
50
|
+
contextInfo?: IncomingMessageContextInfo;
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
interface IncomingMessageContent {
|
|
50
54
|
conversation?: string;
|
|
51
55
|
extendedTextMessage?: {
|
|
52
56
|
text?: string;
|
|
53
57
|
contextInfo?: IncomingMessageContextInfo;
|
|
54
58
|
};
|
|
59
|
+
imageMessage?: IncomingMessageWithContext;
|
|
60
|
+
videoMessage?: IncomingMessageWithContext;
|
|
61
|
+
documentMessage?: IncomingMessageWithContext;
|
|
62
|
+
audioMessage?: IncomingMessageWithContext;
|
|
63
|
+
stickerMessage?: IncomingMessageWithContext;
|
|
64
|
+
buttonsMessage?: IncomingMessageWithContext;
|
|
65
|
+
templateMessage?: IncomingMessageWithContext;
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
interface IncomingMessageLike {
|
|
@@ -204,24 +215,6 @@ export class WhatsAppService {
|
|
|
204
215
|
return [...candidates];
|
|
205
216
|
}
|
|
206
217
|
|
|
207
|
-
private messageHasDirectMention(message: IncomingMessageLike): boolean {
|
|
208
|
-
const mentionedJids = message.message?.extendedTextMessage?.contextInfo?.mentionedJid || [];
|
|
209
|
-
if (mentionedJids.length === 0) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const agentCandidates = this.getAgentJidCandidates();
|
|
214
|
-
if (agentCandidates.length === 0) {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return mentionedJids.some(jid => {
|
|
219
|
-
const normalizedMention = this.normalizeJidForComparison(jid);
|
|
220
|
-
const mentionIdentity = this.normalizeJidIdentity(jid);
|
|
221
|
-
return agentCandidates.includes(normalizedMention) || agentCandidates.includes(mentionIdentity);
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
218
|
private getDisconnectStatusCode(error: unknown): number | undefined {
|
|
226
219
|
if (!error || typeof error !== 'object') {
|
|
227
220
|
return undefined;
|
|
@@ -469,7 +462,7 @@ export class WhatsAppService {
|
|
|
469
462
|
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
|
|
470
463
|
const isBadMac = this.isBadMacError(errorMessage);
|
|
471
464
|
const isAuthRejected = this.isAuthRejected(statusCode, errorMessage);
|
|
472
|
-
const shouldTreatAsLoggedOut = isBadMac
|
|
465
|
+
const shouldTreatAsLoggedOut = isBadMac
|
|
473
466
|
|
|
474
467
|
if (this.intentionalStop) {
|
|
475
468
|
return;
|
|
@@ -589,10 +582,6 @@ export class WhatsAppService {
|
|
|
589
582
|
void this.recordIncomingMessage(message, remoteJid, text);
|
|
590
583
|
|
|
591
584
|
const pushName = message.pushName || undefined;
|
|
592
|
-
const groupAllowed = isGroup && this.sessionManager.isAllowedGroup(remoteJid);
|
|
593
|
-
const passiveGroupBlocked = groupAllowed
|
|
594
|
-
&& this.sessionManager.getAllowedGroupReactionMode(remoteJid) === 'passive'
|
|
595
|
-
&& !this.messageHasDirectMention(message);
|
|
596
585
|
|
|
597
586
|
if (this.boundGroupJid) {
|
|
598
587
|
if (!this.sessionManager.isAllowedGroup(this.boundGroupJid)) {
|
|
@@ -600,10 +589,6 @@ export class WhatsAppService {
|
|
|
600
589
|
return;
|
|
601
590
|
}
|
|
602
591
|
|
|
603
|
-
if (this.sessionManager.getAllowedGroupReactionMode(this.boundGroupJid) === 'passive' && !this.messageHasDirectMention(message)) {
|
|
604
|
-
return;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
592
|
this.lastRemoteJid = remoteJid;
|
|
608
593
|
this.onMessage?.(payload);
|
|
609
594
|
return;
|
|
@@ -617,10 +602,6 @@ export class WhatsAppService {
|
|
|
617
602
|
return;
|
|
618
603
|
}
|
|
619
604
|
|
|
620
|
-
if (passiveGroupBlocked) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
605
|
this.lastRemoteJid = remoteJid;
|
|
625
606
|
this.onMessage?.(payload);
|
|
626
607
|
}
|
package/src/ui/menu.handler.ts
CHANGED
|
@@ -291,12 +291,11 @@ export class MenuHandler {
|
|
|
291
291
|
const historyLabel = t('menu.allowedGroups.group.history');
|
|
292
292
|
const sendMessageLabel = t('menu.allowedGroups.group.sendMessage');
|
|
293
293
|
const printGroupLabel = t('menu.allowedGroups.group.printGroup');
|
|
294
|
-
const reactionModeLabel = t('menu.allowedGroups.group.reactionMode');
|
|
295
294
|
const removeAliasLabel = t('menu.allowedGroups.group.removeAlias');
|
|
296
295
|
const addAliasLabel = t('menu.allowedGroups.group.addAlias');
|
|
297
296
|
const removeGroupLabel = t('menu.allowedGroups.group.removeGroup');
|
|
298
297
|
const backLabel = t('menu.allowedGroups.group.back');
|
|
299
|
-
const options = [historyLabel, sendMessageLabel, printGroupLabel
|
|
298
|
+
const options = [historyLabel, sendMessageLabel, printGroupLabel];
|
|
300
299
|
if (group.name) {
|
|
301
300
|
options.push(removeAliasLabel);
|
|
302
301
|
} else {
|
|
@@ -324,12 +323,6 @@ export class MenuHandler {
|
|
|
324
323
|
return;
|
|
325
324
|
}
|
|
326
325
|
|
|
327
|
-
if (choice === reactionModeLabel) {
|
|
328
|
-
await this.manageAllowedGroupReactionMode(ctx, group);
|
|
329
|
-
await this.manageAllowedGroup(ctx, group);
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
326
|
if (choice === addAliasLabel) {
|
|
334
327
|
const alias = await ctx.ui.input(t('menu.allowedGroups.enterAlias', { groupJid: group.number }));
|
|
335
328
|
const trimmedAlias = alias?.trim() || '';
|
|
@@ -514,30 +507,6 @@ export class MenuHandler {
|
|
|
514
507
|
});
|
|
515
508
|
}
|
|
516
509
|
|
|
517
|
-
private async manageAllowedGroupReactionMode(ctx: ExtensionCommandContext, group: Contact) {
|
|
518
|
-
const displayName = this.formatAllowedGroupOption(group);
|
|
519
|
-
const title = t('menu.allowedGroups.group.reactionMode.title', { displayName });
|
|
520
|
-
const activeLabel = t('menu.allowedGroups.group.reactionMode.active');
|
|
521
|
-
const passiveLabel = t('menu.allowedGroups.group.reactionMode.passive');
|
|
522
|
-
const backLabel = t('menu.allowedGroups.group.back');
|
|
523
|
-
const currentMode = this.sessionManager.getAllowedGroupReactionMode(group.number);
|
|
524
|
-
const options = [activeLabel, passiveLabel, backLabel];
|
|
525
|
-
|
|
526
|
-
const choice = await ctx.ui.select(title, options);
|
|
527
|
-
|
|
528
|
-
if (choice === backLabel || !choice) {
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
if (choice === activeLabel || choice === passiveLabel) {
|
|
533
|
-
const nextMode = choice === activeLabel ? 'active' : 'passive';
|
|
534
|
-
if (currentMode !== nextMode) {
|
|
535
|
-
await this.sessionManager.setAllowedGroupReactionMode(group.number, nextMode);
|
|
536
|
-
}
|
|
537
|
-
ctx.ui.notify(t('menu.allowedGroups.group.reactionMode.updated', { displayName, mode: choice }), 'info');
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
510
|
private async sendPromptedMenuMessage(
|
|
542
511
|
ctx: ExtensionCommandContext,
|
|
543
512
|
options: {
|