trompot 1.6.1 → 1.6.2

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.
Files changed (142) hide show
  1. package/README.md +195 -20
  2. package/lib/client/Client.js +93 -28
  3. package/lib/client/Client.js.map +1 -1
  4. package/lib/client/ClientFunctionHandler.js +39 -3
  5. package/lib/client/ClientFunctionHandler.js.map +1 -1
  6. package/lib/telegram/TelegramAuth.js +36 -1
  7. package/lib/telegram/TelegramAuth.js.map +1 -1
  8. package/lib/telegram/TelegramBot.d.ts +11 -0
  9. package/lib/telegram/TelegramBot.js +101 -15
  10. package/lib/telegram/TelegramBot.js.map +1 -1
  11. package/lib/telegram/TelegramEvents.d.ts +8 -1
  12. package/lib/telegram/TelegramEvents.js +67 -30
  13. package/lib/telegram/TelegramEvents.js.map +1 -1
  14. package/lib/telegram/TelegramSendingController.js +59 -17
  15. package/lib/telegram/TelegramSendingController.js.map +1 -1
  16. package/lib/telegram/TelegramToRompotConverter.js +44 -14
  17. package/lib/telegram/TelegramToRompotConverter.js.map +1 -1
  18. package/lib/wa/Auth.js +17 -5
  19. package/lib/wa/Auth.js.map +1 -1
  20. package/lib/wa/ConfigWAEvents.d.ts +6 -10
  21. package/lib/wa/ConfigWAEvents.js +216 -430
  22. package/lib/wa/ConfigWAEvents.js.map +1 -1
  23. package/lib/wa/ConvertWAMessage.js +28 -19
  24. package/lib/wa/ConvertWAMessage.js.map +1 -1
  25. package/lib/wa/ID.d.ts +10 -1
  26. package/lib/wa/ID.js +22 -2
  27. package/lib/wa/ID.js.map +1 -1
  28. package/lib/wa/WhatsAppBot.d.ts +58 -11
  29. package/lib/wa/WhatsAppBot.js +365 -666
  30. package/lib/wa/WhatsAppBot.js.map +1 -1
  31. package/lib/wa/constants/ConfigDefaults.d.ts +23 -0
  32. package/lib/wa/constants/ConfigDefaults.js +27 -0
  33. package/lib/wa/constants/ConfigDefaults.js.map +1 -0
  34. package/lib/wa/constants/DisconnectReasons.d.ts +24 -0
  35. package/lib/wa/constants/DisconnectReasons.js +36 -0
  36. package/lib/wa/constants/DisconnectReasons.js.map +1 -0
  37. package/lib/wa/constants/ErrorCodes.d.ts +28 -0
  38. package/lib/wa/constants/ErrorCodes.js +32 -0
  39. package/lib/wa/constants/ErrorCodes.js.map +1 -0
  40. package/lib/wa/constants/JIDPatterns.d.ts +23 -0
  41. package/lib/wa/constants/JIDPatterns.js +38 -0
  42. package/lib/wa/constants/JIDPatterns.js.map +1 -0
  43. package/lib/wa/constants/Timeouts.d.ts +11 -0
  44. package/lib/wa/constants/Timeouts.js +15 -0
  45. package/lib/wa/constants/Timeouts.js.map +1 -0
  46. package/lib/wa/core/ConnectionManager.d.ts +84 -0
  47. package/lib/wa/core/ConnectionManager.js +256 -0
  48. package/lib/wa/core/ConnectionManager.js.map +1 -0
  49. package/lib/wa/core/SessionManager.d.ts +29 -0
  50. package/lib/wa/core/SessionManager.js +155 -0
  51. package/lib/wa/core/SessionManager.js.map +1 -0
  52. package/lib/wa/core/StateManager.d.ts +49 -0
  53. package/lib/wa/core/StateManager.js +135 -0
  54. package/lib/wa/core/StateManager.js.map +1 -0
  55. package/lib/wa/events/CallEventHandler.d.ts +17 -0
  56. package/lib/wa/events/CallEventHandler.js +155 -0
  57. package/lib/wa/events/CallEventHandler.js.map +1 -0
  58. package/lib/wa/events/ChatEventHandler.d.ts +12 -0
  59. package/lib/wa/events/ChatEventHandler.js +74 -0
  60. package/lib/wa/events/ChatEventHandler.js.map +1 -0
  61. package/lib/wa/events/ConnectionEventHandler.d.ts +43 -0
  62. package/lib/wa/events/ConnectionEventHandler.js +305 -0
  63. package/lib/wa/events/ConnectionEventHandler.js.map +1 -0
  64. package/lib/wa/events/ContactEventHandler.d.ts +12 -0
  65. package/lib/wa/events/ContactEventHandler.js +55 -0
  66. package/lib/wa/events/ContactEventHandler.js.map +1 -0
  67. package/lib/wa/events/EventManager.d.ts +43 -0
  68. package/lib/wa/events/EventManager.js +198 -0
  69. package/lib/wa/events/EventManager.js.map +1 -0
  70. package/lib/wa/events/GroupEventHandler.d.ts +12 -0
  71. package/lib/wa/events/GroupEventHandler.js +74 -0
  72. package/lib/wa/events/GroupEventHandler.js.map +1 -0
  73. package/lib/wa/events/HistoryEventHandler.d.ts +16 -0
  74. package/lib/wa/events/HistoryEventHandler.js +101 -0
  75. package/lib/wa/events/HistoryEventHandler.js.map +1 -0
  76. package/lib/wa/events/LIDMappingEventHandler.d.ts +20 -0
  77. package/lib/wa/events/LIDMappingEventHandler.js +39 -0
  78. package/lib/wa/events/LIDMappingEventHandler.js.map +1 -0
  79. package/lib/wa/events/MessageEventHandler.d.ts +16 -0
  80. package/lib/wa/events/MessageEventHandler.js +218 -0
  81. package/lib/wa/events/MessageEventHandler.js.map +1 -0
  82. package/lib/wa/interfaces/ICacheService.d.ts +12 -0
  83. package/lib/wa/interfaces/ICacheService.js +3 -0
  84. package/lib/wa/interfaces/ICacheService.js.map +1 -0
  85. package/lib/wa/interfaces/IConnectionManager.d.ts +15 -0
  86. package/lib/wa/interfaces/IConnectionManager.js +3 -0
  87. package/lib/wa/interfaces/IConnectionManager.js.map +1 -0
  88. package/lib/wa/interfaces/IErrorHandler.d.ts +9 -0
  89. package/lib/wa/interfaces/IErrorHandler.js +3 -0
  90. package/lib/wa/interfaces/IErrorHandler.js.map +1 -0
  91. package/lib/wa/interfaces/ILoggerService.d.ts +13 -0
  92. package/lib/wa/interfaces/ILoggerService.js +3 -0
  93. package/lib/wa/interfaces/ILoggerService.js.map +1 -0
  94. package/lib/wa/interfaces/ISessionManager.d.ts +16 -0
  95. package/lib/wa/interfaces/ISessionManager.js +3 -0
  96. package/lib/wa/interfaces/ISessionManager.js.map +1 -0
  97. package/lib/wa/interfaces/IStateManager.d.ts +41 -0
  98. package/lib/wa/interfaces/IStateManager.js +3 -0
  99. package/lib/wa/interfaces/IStateManager.js.map +1 -0
  100. package/lib/wa/operations/ChatOperations.d.ts +117 -0
  101. package/lib/wa/operations/ChatOperations.js +349 -0
  102. package/lib/wa/operations/ChatOperations.js.map +1 -0
  103. package/lib/wa/operations/GroupOperations.d.ts +31 -0
  104. package/lib/wa/operations/GroupOperations.js +128 -0
  105. package/lib/wa/operations/GroupOperations.js.map +1 -0
  106. package/lib/wa/operations/MessageOperations.d.ts +69 -0
  107. package/lib/wa/operations/MessageOperations.js +335 -0
  108. package/lib/wa/operations/MessageOperations.js.map +1 -0
  109. package/lib/wa/operations/UserOperations.d.ts +100 -0
  110. package/lib/wa/operations/UserOperations.js +216 -0
  111. package/lib/wa/operations/UserOperations.js.map +1 -0
  112. package/lib/wa/services/CacheService.d.ts +45 -0
  113. package/lib/wa/services/CacheService.js +93 -0
  114. package/lib/wa/services/CacheService.js.map +1 -0
  115. package/lib/wa/services/ErrorHandler.d.ts +26 -0
  116. package/lib/wa/services/ErrorHandler.js +73 -0
  117. package/lib/wa/services/ErrorHandler.js.map +1 -0
  118. package/lib/wa/services/LIDMappingService.d.ts +42 -0
  119. package/lib/wa/services/LIDMappingService.js +132 -0
  120. package/lib/wa/services/LIDMappingService.js.map +1 -0
  121. package/lib/wa/services/LIDNormalizationService.d.ts +30 -0
  122. package/lib/wa/services/LIDNormalizationService.js +136 -0
  123. package/lib/wa/services/LIDNormalizationService.js.map +1 -0
  124. package/lib/wa/services/LoggerService.d.ts +44 -0
  125. package/lib/wa/services/LoggerService.js +85 -0
  126. package/lib/wa/services/LoggerService.js.map +1 -0
  127. package/lib/wa/services/PendingMessageQueue.d.ts +46 -0
  128. package/lib/wa/services/PendingMessageQueue.js +119 -0
  129. package/lib/wa/services/PendingMessageQueue.js.map +1 -0
  130. package/lib/wa/services/RetryService.d.ts +25 -0
  131. package/lib/wa/services/RetryService.js +59 -0
  132. package/lib/wa/services/RetryService.js.map +1 -0
  133. package/lib/wa/utils/ConfigValidator.d.ts +15 -0
  134. package/lib/wa/utils/ConfigValidator.js +66 -0
  135. package/lib/wa/utils/ConfigValidator.js.map +1 -0
  136. package/lib/wa/utils/ErrorUtils.d.ts +29 -0
  137. package/lib/wa/utils/ErrorUtils.js +66 -0
  138. package/lib/wa/utils/ErrorUtils.js.map +1 -0
  139. package/lib/wa/utils/Validation.d.ts +18 -0
  140. package/lib/wa/utils/Validation.js +40 -0
  141. package/lib/wa/utils/Validation.js.map +1 -0
  142. package/package.json +4 -3
@@ -37,79 +37,141 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const baileys_1 = __importStar(require("@whiskeysockets/baileys"));
40
- const node_cache_1 = __importDefault(require("node-cache"));
41
40
  const pino_1 = __importDefault(require("pino"));
42
- const long_1 = __importDefault(require("long"));
43
- const messages_1 = require("../messages");
44
- const Generic_1 = require("../utils/Generic");
45
41
  const Auth_1 = require("./Auth");
46
- const Message_1 = require("../messages/Message");
47
- const ConvertToWAMessage_1 = __importDefault(require("./ConvertToWAMessage"));
48
42
  const makeInMemoryStore_1 = __importDefault(require("./makeInMemoryStore"));
43
+ const MediaMessage_1 = __importDefault(require("../messages/MediaMessage"));
49
44
  const ConfigWAEvents_1 = __importDefault(require("./ConfigWAEvents"));
50
45
  const ID_1 = require("./ID");
46
+ const Timeouts_1 = require("./constants/Timeouts");
47
+ const ErrorCodes_1 = require("./constants/ErrorCodes");
48
+ const ConfigValidator_1 = require("./utils/ConfigValidator");
49
+ const MessageOperations_1 = require("./operations/MessageOperations");
50
+ const ChatOperations_1 = require("./operations/ChatOperations");
51
+ const UserOperations_1 = require("./operations/UserOperations");
52
+ const GroupOperations_1 = require("./operations/GroupOperations");
53
+ // Novos serviços e managers
54
+ const LoggerService_1 = require("./services/LoggerService");
55
+ const CacheService_1 = require("./services/CacheService");
56
+ const ErrorHandler_1 = require("./services/ErrorHandler");
57
+ const RetryService_1 = require("./services/RetryService");
58
+ const LIDMappingService_1 = require("./services/LIDMappingService");
59
+ const PendingMessageQueue_1 = require("./services/PendingMessageQueue");
60
+ const LIDNormalizationService_1 = require("./services/LIDNormalizationService");
61
+ const StateManager_1 = require("./core/StateManager");
62
+ const ConnectionManager_1 = require("./core/ConnectionManager");
63
+ const SessionManager_1 = require("./core/SessionManager");
64
+ const EventManager_1 = require("./events/EventManager");
65
+ const ConnectionEventHandler_1 = require("./events/ConnectionEventHandler");
66
+ const MessageEventHandler_1 = require("./events/MessageEventHandler");
67
+ const HistoryEventHandler_1 = require("./events/HistoryEventHandler");
68
+ const ContactEventHandler_1 = require("./events/ContactEventHandler");
69
+ const GroupEventHandler_1 = require("./events/GroupEventHandler");
70
+ const ChatEventHandler_1 = require("./events/ChatEventHandler");
71
+ const CallEventHandler_1 = require("./events/CallEventHandler");
72
+ const LIDMappingEventHandler_1 = require("./events/LIDMappingEventHandler");
51
73
  const BotStatus_1 = require("../bot/BotStatus");
52
- const ChatType_1 = __importDefault(require("../modules/chat/ChatType"));
53
74
  const BotEvents_1 = __importDefault(require("../bot/BotEvents"));
54
- const WAStatus_1 = require("./WAStatus");
55
- const User_1 = __importDefault(require("../modules/user/User"));
56
- const Chat_1 = __importDefault(require("../modules/chat/Chat"));
57
75
  class WhatsAppBot extends BotEvents_1.default {
76
+ // Tornar stateManager acessível para ConfigWAEvents (sem type casting)
77
+ getStateManager() {
78
+ return this.stateManager;
79
+ }
80
+ // Getters para compatibilidade (delegam para StateManager)
81
+ get id() {
82
+ return this.stateManager.id;
83
+ }
84
+ get status() {
85
+ return this.stateManager.status;
86
+ }
87
+ get phoneNumber() {
88
+ return this.stateManager.phoneNumber;
89
+ }
90
+ get name() {
91
+ return this.stateManager.name;
92
+ }
93
+ get profileUrl() {
94
+ return this.stateManager.profileUrl;
95
+ }
96
+ get lastConnectionUpdateDate() {
97
+ return this.stateManager.lastConnectionUpdateDate;
98
+ }
99
+ get lastDisconnectError() {
100
+ return this.stateManager.lastDisconnectError;
101
+ }
58
102
  constructor(config) {
59
- var _a, _b;
60
103
  super();
61
104
  //@ts-ignore
62
105
  this.sock = {};
63
106
  this.auth = new Auth_1.MultiFileAuthState('./session', undefined, false);
64
107
  this.messagesCached = [];
65
- this.msgRetryCountercache = new node_cache_1.default({
66
- stdTTL: baileys_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
67
- useClones: false,
68
- });
69
108
  this.saveCreds = async (creds) => {
70
- // v7.0.0-rc.5: Salvar credenciais básicas
71
- // LIDs e deviceIndex serão implementados quando estiverem disponíveis na API estável
72
- await this.auth.set('creds', creds);
109
+ await this.sessionManager.saveCredentials(this.auth, creds);
73
110
  };
74
111
  this.connectionListeners = [];
75
112
  this.DisconnectReason = baileys_1.DisconnectReason;
76
113
  this.logger = (0, pino_1.default)({ level: 'silent' });
77
- this.id = '';
78
- this.status = BotStatus_1.BotStatus.Offline;
79
- this.phoneNumber = '';
80
- this.name = '';
81
- this.profileUrl = '';
82
- this.lastConnectionUpdateDate = Date.now();
83
114
  this.checkConnectionInterval = null;
84
115
  this.configEvents = new ConfigWAEvents_1.default(this);
85
- // Inicializa caches com TTLs apropriados (fallback numérico para 6.7.x)
86
- const GROUP_META_TTL = (_a = baileys_1.DEFAULT_CACHE_TTLS === null || baileys_1.DEFAULT_CACHE_TTLS === void 0 ? void 0 : baileys_1.DEFAULT_CACHE_TTLS.CALL_OFFER) !== null && _a !== void 0 ? _a : 300; // 5min
87
- const SIGNAL_KEY_TTL = (_b = baileys_1.DEFAULT_CACHE_TTLS === null || baileys_1.DEFAULT_CACHE_TTLS === void 0 ? void 0 : baileys_1.DEFAULT_CACHE_TTLS.USER_DEVICES) !== null && _b !== void 0 ? _b : 300; // 5min
88
- this.groupMetadataCache = new node_cache_1.default({
89
- stdTTL: GROUP_META_TTL,
90
- useClones: false,
91
- });
92
- this.signalKeyCache = new node_cache_1.default({
93
- stdTTL: SIGNAL_KEY_TTL,
94
- useClones: false,
95
- });
116
+ this.eventsIsStoped = false;
117
+ /**
118
+ * Cria e configura um novo socket (método centralizado)
119
+ * Usado tanto em connect() quanto após restartRequired
120
+ */
121
+ this.isCreatingSocket = false;
122
+ this.createSocketPromise = null;
123
+ // Valida e normaliza configuração
124
+ const validatedConfig = ConfigValidator_1.ConfigValidator.validateWithWarnings(config);
125
+ // Inicializa serviços
126
+ this.loggerService = new LoggerService_1.LoggerService(validatedConfig.logLevel || 'info');
127
+ this.cacheService = new CacheService_1.CacheService(this.loggerService);
128
+ this.errorHandler = new ErrorHandler_1.ErrorHandler(this.loggerService);
129
+ this.retryService = new RetryService_1.RetryService();
130
+ this.lidMappingService = new LIDMappingService_1.LIDMappingService(this.loggerService, this.cacheService);
131
+ this.lidNormalizationService = new LIDNormalizationService_1.LIDNormalizationService(this.loggerService, this.lidMappingService);
132
+ this.pendingMessageQueue = new PendingMessageQueue_1.PendingMessageQueue(this.loggerService);
133
+ this.stateManager = new StateManager_1.StateManager(this.loggerService);
134
+ this.sessionManager = new SessionManager_1.SessionManager(this.loggerService);
135
+ this.connectionManager = new ConnectionManager_1.ConnectionManager(this.stateManager, this.sessionManager, this.retryService, this.errorHandler, this.loggerService);
136
+ this.eventManager = new EventManager_1.EventManager(this.loggerService);
137
+ // Inicializa handlers
138
+ this.connectionEventHandler = new ConnectionEventHandler_1.ConnectionEventHandler(this, this.loggerService, this.stateManager, this.sessionManager);
139
+ this.messageEventHandler = new MessageEventHandler_1.MessageEventHandler(this, this.loggerService);
140
+ this.historyEventHandler = new HistoryEventHandler_1.HistoryEventHandler(this, this.loggerService);
141
+ this.contactEventHandler = new ContactEventHandler_1.ContactEventHandler(this, this.loggerService);
142
+ this.groupEventHandler = new GroupEventHandler_1.GroupEventHandler(this, this.loggerService);
143
+ this.chatEventHandler = new ChatEventHandler_1.ChatEventHandler(this, this.loggerService);
144
+ this.callEventHandler = new CallEventHandler_1.CallEventHandler(this, this.loggerService);
145
+ this.lidMappingEventHandler = new LIDMappingEventHandler_1.LIDMappingEventHandler(this, this.loggerService, this.lidMappingService, this.pendingMessageQueue);
146
+ // Inicializa operações especializadas
147
+ this.messageOperations = new MessageOperations_1.MessageOperations(this, this.errorHandler, this.pendingMessageQueue);
148
+ this.chatOperations = new ChatOperations_1.ChatOperations(this);
149
+ this.userOperations = new UserOperations_1.UserOperations(this);
150
+ this.groupOperations = new GroupOperations_1.GroupOperations(this);
151
+ // Configura caches usando CacheService
152
+ this.msgRetryCountercache = this.cacheService.getMessageRetryCache();
153
+ this.groupMetadataCache = this.cacheService.getGroupMetadataCache();
154
+ this.signalKeyCache = this.cacheService.getSignalKeyCache();
155
+ // Cria store
96
156
  const store = (0, makeInMemoryStore_1.default)({ logger: this.logger });
97
157
  this.store = store;
98
158
  const waBot = this;
159
+ // Configuração do socket (usa valores validados)
99
160
  this.config = {
100
161
  ...baileys_1.DEFAULT_CONNECTION_CONFIG,
101
162
  logger: this.logger,
102
- qrTimeout: 60000,
103
- defaultQueryTimeoutMs: 10000,
104
- retryRequestDelayMs: 500,
163
+ qrTimeout: validatedConfig.qrTimeout,
164
+ defaultQueryTimeoutMs: validatedConfig.defaultQueryTimeoutMs,
165
+ retryRequestDelayMs: validatedConfig.retryRequestDelayMs,
105
166
  maxMsgRetryCount: 5,
106
- readAllFailedMessages: false,
167
+ readAllFailedMessages: validatedConfig.readAllFailedMessages,
107
168
  msgRetryCounterCache: this.msgRetryCountercache,
108
- autoRestartInterval: 1000 * 60 * 30, // 30 minutes (recommended)
109
- useExperimentalServers: false,
110
- autoSyncHistory: false,
111
- autoLoadContactInfo: false,
112
- autoLoadGroupInfo: false,
169
+ autoRestartInterval: validatedConfig.autoRestartInterval,
170
+ useExperimentalServers: validatedConfig.useExperimentalServers,
171
+ autoSyncHistory: validatedConfig.autoSyncHistory,
172
+ autoLoadContactInfo: validatedConfig.autoLoadContactInfo,
173
+ autoLoadGroupInfo: validatedConfig.autoLoadGroupInfo,
174
+ autoRejectCalls: validatedConfig.autoRejectCalls,
113
175
  shouldIgnoreJid: () => false,
114
176
  // v7.0.0-rc.5: Removido ACKs automáticos para evitar banimentos
115
177
  generateHighQualityLinkPreview: false,
@@ -138,213 +200,197 @@ class WhatsAppBot extends BotEvents_1.default {
138
200
  return msg.message;
139
201
  },
140
202
  cachedGroupMetadata: async (jid) => this.groupMetadataCache.get(jid),
141
- ...config,
142
203
  };
143
204
  delete this.config.auth;
144
- // Listeners de eventos Baileys
145
- setTimeout(() => {
146
- if (this.sock && this.sock.ev) {
147
- this.sock.ev.on('messages.upsert', async ({ type, messages }) => {
148
- // Exemplo: processa todas as mensagens recebidas
149
- for (const msg of messages) {
150
- // Aqui você pode converter proto.IMessage para Message do Rompot
151
- // e emitir eventos ou chamar handlers do seu fluxo
152
- // Exemplo:
153
- // const rompotMsg = await ConvertWAMessage.fromBaileys(this, msg, type);
154
- // this.emit('message', rompotMsg);
155
- }
156
- });
157
- this.sock.ev.on('messages.update', (updates) => {
158
- // Handler para mensagens editadas, deletadas, etc.
159
- });
160
- this.sock.ev.on('messages.delete', (deletes) => {
161
- // Handler para deleção de mensagens
162
- });
163
- this.sock.ev.on('messages.reaction', (reaction) => {
164
- // Handler para reações em mensagens
165
- });
166
- // Listener para histórico de mensagens (history sync)
167
- this.sock.ev.on('messaging-history.set', async ({ chats, contacts, messages, syncType }) => {
168
- // Armazena chats
169
- if (chats && Array.isArray(chats)) {
170
- for (const chat of chats) {
171
- await this.auth.set(`chats-${chat.id}`, chat);
172
- }
173
- }
174
- // Armazena contatos
175
- if (contacts && Array.isArray(contacts)) {
176
- for (const contact of contacts) {
177
- await this.auth.set(`users-${contact.id}`, contact);
178
- }
179
- }
180
- // Armazena mensagens
181
- if (messages && Array.isArray(messages)) {
182
- for (const msg of messages) {
183
- if (msg.key && msg.key.id && msg.key.remoteJid) {
184
- await this.store.saveMessage(msg.key.remoteJid, msg, false);
185
- }
186
- }
187
- }
188
- // Você pode emitir eventos ou processar syncType conforme necessário
189
- });
190
- // Listener padrão Baileys: emite evento 'qr' para o client externo
191
- this.sock.ev.on('connection.update', (update) => {
192
- if (update.qr) {
193
- this.emit('qr', update.qr);
194
- }
195
- });
196
- // Para exibir o QR code no terminal, utilize:
197
- //
198
- // client.on('qr', async (qr) => {
199
- // try {
200
- // const QRCode = (await import('qrcode')).default;
201
- // console.log(await QRCode.toString(qr, { type: 'terminal' }));
202
- // } catch (err) {
203
- // console.log('QRCode:', qr);
204
- // }
205
- // });
206
- }
207
- }, 0);
205
+ // NOTA: Listeners de eventos Baileys são configurados em:
206
+ // - setupEventHandlers() - handlers especializados (MessageEventHandler, etc.)
207
+ // - ConfigWAEvents.configureAll() - configuração de eventos do Baileys
208
+ // Não adicionar listeners diretamente aqui para evitar vazamento de memória
208
209
  }
209
210
  async connect(auth) {
210
- var _a, _b, _c;
211
211
  if (!auth || typeof auth == 'string') {
212
212
  this.auth = new Auth_1.MultiFileAuthState(`${auth || './session'}`);
213
213
  }
214
214
  else {
215
215
  this.auth = auth;
216
216
  }
217
- if (!this.auth.botPhoneNumber) {
218
- // Fluxo normal com QR code
219
- await this.internalConnect({ browser: baileys_1.Browsers.windows('Rompot') });
220
- await this.awaitConnectionState('open');
217
+ // Valida sessão antes de criar socket (evita gerar QR code desnecessário)
218
+ const validation = await this.sessionManager.validateSession(this.auth);
219
+ if (!validation.isValid && validation.shouldGenerateQR) {
220
+ this.loggerService.warn(`⚠️ Sessão inválida: ${validation.reason}. QR code será gerado.`);
221
+ }
222
+ else if (validation.isValid) {
223
+ this.loggerService.info('✅ Sessão válida encontrada. Reconectando sem QR code.');
221
224
  }
222
225
  else {
223
- // Fluxo de pairing code (sem QR)
224
- // Segundo o README do Baileys: printQRInTerminal deve ser false
225
- // IMPORTANTE: Criar socket SEM esperar por 'open' primeiro
226
- await this.internalConnect({
227
- browser: ['Chrome (linux)', 'Rompot', '22.5.0'],
228
- printQRInTerminal: false, // Necessário para pairing code
229
- }, false); // false = não esperar por 'open' ainda
230
- // Verifica se já está registrado ANTES de esperar conexão
231
- // O README do Baileys mostra que requestPairingCode deve ser chamado
232
- // logo após criar o socket, antes de esperar por 'open'
233
- if (!((_c = (_b = (_a = this.sock) === null || _a === void 0 ? void 0 : _a.authState) === null || _b === void 0 ? void 0 : _b.creds) === null || _c === void 0 ? void 0 : _c.registered)) {
234
- // Não espera por QR - chama requestPairingCode diretamente
235
- // O número deve estar no formato: apenas números com código do país (sem +, (), -)
236
- const code = await this.sock.requestPairingCode(this.auth.botPhoneNumber);
237
- this.emit('code', code);
238
- }
239
- // Só agora espera pela conexão abrir
240
- await this.awaitConnectionState('open');
226
+ this.loggerService.warn(`⚠️ Sessão pode estar inválida, mas QR code não será gerado automaticamente.`);
241
227
  }
228
+ // Cria e configura o socket (método centralizado)
229
+ await this.createSocket();
242
230
  }
243
- async internalConnect(additionalOptions = {}, waitForOpen = true) {
244
- return new Promise(async (resolve, reject) => {
231
+ async createSocket() {
232
+ // Previne race condition: se já estiver criando, retorna a Promise existente
233
+ if (this.isCreatingSocket && this.createSocketPromise) {
234
+ return this.createSocketPromise;
235
+ }
236
+ this.isCreatingSocket = true;
237
+ this.createSocketPromise = this._createSocketInternal().finally(() => {
238
+ this.isCreatingSocket = false;
239
+ this.createSocketPromise = null;
240
+ });
241
+ return this.createSocketPromise;
242
+ }
243
+ async _createSocketInternal() {
244
+ var _a, _b;
245
+ // Carrega credenciais
246
+ const { state, saveCreds } = await (0, Auth_1.getBaileysAuth)(this.auth);
247
+ this.saveCreds = saveCreds;
248
+ // Verifica se as credenciais são válidas antes de criar socket
249
+ // Se não forem válidas, o Baileys gerará QR code automaticamente
250
+ if (!state.creds || !state.creds.registered || !((_a = state.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
251
+ this.loggerService.warn('Credenciais inválidas detectadas. QR code será gerado pelo Baileys.');
252
+ }
253
+ else {
254
+ this.loggerService.debug('Credenciais válidas carregadas. Reconectando sem QR code.');
255
+ }
256
+ // Cria logger para o Baileys (filtra logs de sessão se logLevel for 'warn' ou superior)
257
+ // O Baileys usa este logger para logs internos, incluindo "Closing session"
258
+ const baileysLogger = this.config.logger || (0, pino_1.default)({
259
+ level: this.config.logLevel === 'info' ? 'warn' : this.config.logLevel || 'warn'
260
+ });
261
+ // Cria configuração do socket
262
+ const socketConfig = {
263
+ auth: {
264
+ creds: state.creds,
265
+ keys: (0, baileys_1.makeCacheableSignalKeyStore)(state.keys, baileysLogger),
266
+ },
267
+ browser: baileys_1.Browsers.windows('Rompot'),
268
+ logger: baileysLogger, // Passa logger explicitamente para o Baileys
269
+ ...this.config,
270
+ };
271
+ // Fecha socket anterior se existir
272
+ if (this.sock) {
245
273
  try {
246
- const { state, saveCreds } = await (0, Auth_1.getBaileysAuth)(this.auth);
247
- this.saveCreds = saveCreds;
248
- this.sock = (0, baileys_1.default)({
249
- auth: {
250
- creds: state.creds,
251
- keys: (0, baileys_1.makeCacheableSignalKeyStore)(state.keys, this.config.logger),
252
- // v7.0.0-rc.5: Configuração básica de auth
253
- // LIDs serão implementados quando estiverem disponíveis na API estável
254
- },
255
- ...additionalOptions,
256
- ...this.config,
257
- });
258
- this.store.bind(this.sock.ev);
259
- this.configEvents.configureAll();
260
- this.sock.ev.on('creds.update', saveCreds);
261
- resolve();
262
- // Só espera por 'open' se solicitado (para pairing code, não esperamos ainda)
263
- if (waitForOpen) {
264
- await this.awaitConnectionState('open');
265
- }
274
+ // Remove todos os listeners ANTES de fechar para evitar vazamento
275
+ this.configEvents.cleanup(); // Limpa listeners do ConfigWAEvents
276
+ this.eventManager.cleanup(); // Limpa listeners do EventManager
277
+ this.sock.end(undefined);
266
278
  }
267
279
  catch (err) {
268
- this.ev.emit('error', err);
269
- reject(err);
280
+ // Ignora erros
270
281
  }
271
- });
282
+ }
283
+ // Cria novo socket
284
+ this.sock = (0, baileys_1.default)(socketConfig);
285
+ // Armazena configuração no ConnectionManager
286
+ this.connectionManager.connectionConfig = socketConfig;
287
+ // Configura componentes
288
+ this.store.bind(this.sock.ev);
289
+ this.eventManager.setSocket(this.sock);
290
+ this.lidMappingService.setSocket(this.sock);
291
+ this.lidNormalizationService.setSocket(this.sock);
292
+ // Configura handlers (CRÍTICO: antes de qualquer evento)
293
+ this.configEvents.configureAll();
294
+ this.setupEventHandlers();
295
+ // Configura limpeza periódica da fila de mensagens pendentes (a cada 30 segundos)
296
+ if (this.pendingMessageQueue) {
297
+ setInterval(() => {
298
+ this.pendingMessageQueue.cleanup();
299
+ }, 30000);
300
+ }
301
+ // Configura creds.update
302
+ this.sock.ev.on('creds.update', saveCreds);
303
+ // Se já estiver conectado, emite evento
304
+ if ((_b = this.sock) === null || _b === void 0 ? void 0 : _b.ws.isOpen) {
305
+ this.emit('open', { isNewLogin: false });
306
+ }
307
+ }
308
+ /**
309
+ * Configura todos os handlers de eventos
310
+ */
311
+ setupEventHandlers() {
312
+ if (!this.sock)
313
+ return;
314
+ this.connectionEventHandler.setup(this.sock);
315
+ this.messageEventHandler.setup(this.sock);
316
+ this.historyEventHandler.setup(this.sock);
317
+ this.contactEventHandler.setup(this.sock);
318
+ this.groupEventHandler.setup(this.sock);
319
+ this.chatEventHandler.setup(this.sock);
320
+ this.callEventHandler.setup(this.sock);
321
+ this.lidMappingEventHandler.setup(this.sock);
272
322
  }
273
323
  /**
274
324
  * * Reconecta ao servidor do WhatsApp
275
325
  * @returns
276
326
  */
277
- async reconnect(stopEvents = false, showOpen) {
278
- if (stopEvents) {
279
- this.eventsIsStoped = true;
280
- let state = this.status == BotStatus_1.BotStatus.Online ? 'close' : 'connecting';
281
- let status = baileys_1.DisconnectReason.connectionClosed;
282
- let retryCount = 0;
283
- this.connectionListeners.push((update) => {
284
- var _a, _b, _c, _d, _e, _f, _g, _h;
285
- if (!update.connection)
286
- return false;
287
- if (retryCount >= 3) {
288
- this.eventsIsStoped = false;
289
- return true;
290
- }
291
- if (update.connection != state) {
292
- if (update.connection == 'close') {
293
- state = 'connecting';
294
- status =
295
- ((_c = (_b = (_a = update.lastDisconnect) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.output) === null || _c === void 0 ? void 0 : _c.statusCode) ||
296
- ((_d = update.lastDisconnect) === null || _d === void 0 ? void 0 : _d.error) ||
297
- baileys_1.DisconnectReason.connectionClosed;
298
- retryCount++;
299
- }
300
- else {
301
- this.eventsIsStoped = false;
302
- if (state == 'connecting') {
303
- this.emit('close', { reason: status });
304
- }
305
- else if (state == 'open') {
306
- this.emit('close', { reason: status });
307
- this.emit('connecting', {});
308
- }
309
- }
310
- return true;
311
- }
312
- if (state == 'close') {
313
- state = 'connecting';
314
- status =
315
- ((_g = (_f = (_e = update.lastDisconnect) === null || _e === void 0 ? void 0 : _e.error) === null || _f === void 0 ? void 0 : _f.output) === null || _g === void 0 ? void 0 : _g.statusCode) ||
316
- ((_h = update.lastDisconnect) === null || _h === void 0 ? void 0 : _h.error) ||
317
- baileys_1.DisconnectReason.connectionClosed;
318
- }
319
- else if (state == 'connecting') {
320
- state = 'open';
321
- }
322
- else if (state == 'open' && showOpen) {
323
- this.eventsIsStoped = !showOpen;
324
- return true;
325
- }
326
- return false;
327
- });
327
+ async reconnect(stopEvents = false, showOpen, force = false) {
328
+ // 428 foi removido da lista de erros não reconectáveis
329
+ // É um erro temporário que permite reconexão
330
+ // Apenas 401/421 (token expirado) impedem reconexão
331
+ var _a;
332
+ // Se já estiver conectado, não precisa reconectar
333
+ if ((_a = this.sock) === null || _a === void 0 ? void 0 : _a.ws.isOpen) {
334
+ return;
335
+ }
336
+ // Se force=true (vindo de restartRequired após QR code), sempre reconecta
337
+ // Caso contrário, verifica se está aguardando QR code inicial
338
+ // IMPORTANTE: Não impede reconexão se for restartRequired (código 515)
339
+ // O restartRequired acontece após escanear QR code e precisa reconectar imediatamente
340
+ if (!force && this.sock && !this.sock.ws.isOpen) {
341
+ // Verifica se o último erro foi restartRequired (515) - se sim, permite reconexão
342
+ const isRestartRequired = this.lastDisconnectError === baileys_1.DisconnectReason.restartRequired;
343
+ if (!isRestartRequired) {
344
+ // Verifica se há QR code pendente - se sim, não reconecta
345
+ // Mas permite se for restartRequired
346
+ this.loggerService.warn('Aguardando autenticação (QR code). Não reconectando para evitar limpar sessão.');
347
+ return;
348
+ }
349
+ // Se for restartRequired, continua e reconecta (force será true implicitamente)
350
+ this.loggerService.info('RestartRequired detectado (após QR code). Reconectando...');
351
+ force = true; // Força reconexão para restartRequired
352
+ }
353
+ // Limpa socket anterior se existir (sem desconectar explicitamente)
354
+ if (this.sock) {
355
+ try {
356
+ this.sock.end(undefined);
357
+ }
358
+ catch (err) {
359
+ // Ignora erros ao fechar socket anterior
360
+ }
361
+ }
362
+ // Delay antes de reconectar (mas não para restartRequired - precisa ser imediato)
363
+ if (!force) {
364
+ await new Promise((resolve) => setTimeout(resolve, Timeouts_1.Timeouts.RECONNECT_DELAY));
328
365
  }
329
- await this.stop();
330
- // Delay antes de reconectar para evitar loops infinitos
331
- // Especialmente importante para erros como 428 (Connection Terminated)
332
- await new Promise((resolve) => setTimeout(resolve, 2000));
333
366
  this.emit('reconnecting', {});
334
- await this.internalConnect();
367
+ // Reconecta usando o auth existente (CRÍTICO: não criar novo auth)
368
+ // Para restartRequired (force=true), reconecta imediatamente sem delay
369
+ // Usa createSocket() diretamente para manter o auth original
370
+ await this.createSocket();
335
371
  }
336
372
  /**
337
373
  * * Desliga a conexão com o servidor do WhatsApp
338
374
  * @param reason
339
375
  * @returns
340
376
  */
341
- async stop(reason = 402) {
342
- var _a;
377
+ async stop(reason = ErrorCodes_1.ErrorCodes.CONNECTION_CLOSED) {
343
378
  try {
344
- this.status = BotStatus_1.BotStatus.Offline;
345
- (_a = this.sock) === null || _a === void 0 ? void 0 : _a.end(reason);
379
+ this.stateManager.setStatus(BotStatus_1.BotStatus.Offline);
380
+ // Limpa event handlers (já remove listeners do socket)
381
+ this.configEvents.cleanup(); // Limpa listeners do ConfigWAEvents
382
+ this.eventManager.cleanup(); // Limpa listeners do EventManager
383
+ // Limpa connection listeners
384
+ this.connectionListeners = [];
385
+ // Limpa checkConnectionInterval
386
+ if (this.checkConnectionInterval) {
387
+ clearInterval(this.checkConnectionInterval);
388
+ this.checkConnectionInterval = null;
389
+ }
390
+ await this.connectionManager.disconnect(reason);
346
391
  }
347
392
  catch (err) {
393
+ this.errorHandler.handle(err, 'WhatsAppBot.stop');
348
394
  this.emit('error', err);
349
395
  }
350
396
  }
@@ -356,13 +402,41 @@ class WhatsAppBot extends BotEvents_1.default {
356
402
  * * Aguarda um status de conexão
357
403
  */
358
404
  async awaitConnectionState(connection) {
359
- return new Promise((res) => {
360
- this.connectionListeners.push((update) => {
405
+ return new Promise((res, rej) => {
406
+ var _a;
407
+ // Timeout usando constante
408
+ const timeout = setTimeout(() => {
409
+ // Remove listener do array para evitar vazamento
410
+ const index = this.connectionListeners.indexOf(listener);
411
+ if (index > -1) {
412
+ this.connectionListeners.splice(index, 1);
413
+ }
414
+ rej(new Error(`Timeout ao aguardar conexão '${connection}'`));
415
+ }, Timeouts_1.Timeouts.CONNECTION_WAIT);
416
+ const listener = (update) => {
361
417
  if (update.connection != connection)
362
418
  return false;
419
+ clearTimeout(timeout);
420
+ // Remove listener do array após resolver
421
+ const index = this.connectionListeners.indexOf(listener);
422
+ if (index > -1) {
423
+ this.connectionListeners.splice(index, 1);
424
+ }
363
425
  res(update);
364
426
  return true;
365
- });
427
+ };
428
+ this.connectionListeners.push(listener);
429
+ // Se já estiver no estado desejado, resolve imediatamente
430
+ if (((_a = this.sock) === null || _a === void 0 ? void 0 : _a.ws.isOpen) && connection === 'open') {
431
+ clearTimeout(timeout);
432
+ // Remove listener do array
433
+ const index = this.connectionListeners.indexOf(listener);
434
+ if (index > -1) {
435
+ this.connectionListeners.splice(index, 1);
436
+ }
437
+ res({ connection: 'open' });
438
+ return;
439
+ }
366
440
  });
367
441
  }
368
442
  /**
@@ -370,110 +444,14 @@ class WhatsAppBot extends BotEvents_1.default {
370
444
  * @param chat Sala de bate-papo
371
445
  */
372
446
  async readChat(chat, metadata, updateMetadata = true) {
373
- try {
374
- if (!chat.id || !(chat.id.includes('@s') || chat.id.includes('@g')))
375
- return;
376
- chat.type = (0, baileys_1.isJidGroup)(chat.id) ? ChatType_1.default.Group : ChatType_1.default.PV;
377
- if (chat.type == ChatType_1.default.Group) {
378
- if (updateMetadata) {
379
- chat.profileUrl =
380
- (await this.getChatProfileUrl(new Chat_1.default(chat.id))) || undefined;
381
- if (!metadata) {
382
- try {
383
- metadata = await this.sock.groupMetadata(chat.id);
384
- }
385
- catch (_a) { }
386
- }
387
- else if (!metadata.participants) {
388
- try {
389
- metadata = {
390
- ...metadata,
391
- ...(await this.sock.groupMetadata(chat.id)),
392
- };
393
- }
394
- catch (_b) { }
395
- if (metadata.participant) {
396
- metadata.participants = [
397
- ...(metadata.participants || []),
398
- ...metadata.participant.map((p) => {
399
- return {
400
- id: p.userJid,
401
- isSuperAdmin: p.rank == baileys_1.proto.GroupParticipant.Rank.SUPERADMIN,
402
- isAdmin: p.rank == baileys_1.proto.GroupParticipant.Rank.ADMIN,
403
- };
404
- }),
405
- ];
406
- }
407
- }
408
- }
409
- if (metadata === null || metadata === void 0 ? void 0 : metadata.participants) {
410
- chat.users = [];
411
- chat.admins = [];
412
- for (const p of metadata.participants) {
413
- chat.users.push(p.id);
414
- if (p.admin == 'admin' || p.isAdmin) {
415
- chat.admins.push(`${p.id}`);
416
- }
417
- else if (p.isSuperAdmin) {
418
- chat.leader = p.id;
419
- chat.admins.push(`${p.id}`);
420
- }
421
- }
422
- }
423
- if (metadata === null || metadata === void 0 ? void 0 : metadata.subjectOwner) {
424
- chat.leader = metadata.subjectOwner;
425
- }
426
- }
427
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.subject) || (metadata === null || metadata === void 0 ? void 0 : metadata.name)) {
428
- chat.name = metadata.subject || metadata.name || undefined;
429
- }
430
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.desc) || (metadata === null || metadata === void 0 ? void 0 : metadata.description)) {
431
- chat.description = metadata.desc || metadata.description || undefined;
432
- }
433
- if (metadata === null || metadata === void 0 ? void 0 : metadata.unreadCount) {
434
- chat.unreadCount = metadata.unreadCount || undefined;
435
- }
436
- if (metadata === null || metadata === void 0 ? void 0 : metadata.conversationTimestamp) {
437
- if (long_1.default.isLong(metadata.conversationTimestamp)) {
438
- chat.timestamp = metadata.conversationTimestamp.toNumber() * 1000;
439
- }
440
- else {
441
- chat.timestamp = Number(metadata.conversationTimestamp) * 1000;
442
- }
443
- }
444
- await this.updateChat({ id: chat.id, ...chat });
445
- }
446
- catch (_c) { }
447
+ return this.chatOperations.readChat(chat, metadata, updateMetadata);
447
448
  }
448
449
  /**
449
450
  * * Lê o usuário
450
451
  * @param user Usuário
451
452
  */
452
453
  async readUser(user, metadata) {
453
- try {
454
- if (!user.id || !user.id.includes('@s'))
455
- return;
456
- if (metadata === null || metadata === void 0 ? void 0 : metadata.imgUrl) {
457
- user.profileUrl = await this.getUserProfileUrl(new User_1.default(user.id));
458
- }
459
- else {
460
- const userData = await this.getUser(new User_1.default(user.id || ''));
461
- if (userData == null || !userData.profileUrl) {
462
- user.profileUrl = await this.getUserProfileUrl(new User_1.default(user.id));
463
- }
464
- }
465
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.notify) || (metadata === null || metadata === void 0 ? void 0 : metadata.verifiedName)) {
466
- user.name = (metadata === null || metadata === void 0 ? void 0 : metadata.notify) || (metadata === null || metadata === void 0 ? void 0 : metadata.verifiedName);
467
- }
468
- if (metadata === null || metadata === void 0 ? void 0 : metadata.name) {
469
- user.savedName = metadata.name;
470
- }
471
- user.name = user.name || user.savedName;
472
- await this.updateUser({ id: user.id || '', ...user });
473
- }
474
- catch (err) {
475
- this.emit('error', err);
476
- }
454
+ return this.userOperations.readUser(user, metadata);
477
455
  }
478
456
  /**
479
457
  * Obtem uma mensagem de enquete.
@@ -481,20 +459,14 @@ class WhatsAppBot extends BotEvents_1.default {
481
459
  * @returns A mensagem de enquete salva.
482
460
  */
483
461
  async getPollMessage(pollMessageId) {
484
- const pollMessage = await this.auth.get(`polls-${pollMessageId}`);
485
- if (!pollMessage || !messages_1.PollMessage.isValid(pollMessage))
486
- return messages_1.PollMessage.fromJSON({ id: pollMessageId });
487
- if (pollMessage.type == Message_1.MessageType.PollUpdate) {
488
- return messages_1.PollUpdateMessage.fromJSON(pollMessage);
489
- }
490
- return messages_1.PollMessage.fromJSON(pollMessage);
462
+ return this.messageOperations.getPollMessage(pollMessageId);
491
463
  }
492
464
  /**
493
465
  * Salva a mensagem de enquete.
494
466
  * @param pollMessage - Mensagem de enquete que será salva.
495
467
  */
496
468
  async savePollMessage(pollMessage) {
497
- await this.auth.set(`polls-${pollMessage.id}`, pollMessage.toJSON());
469
+ return this.messageOperations.savePollMessage(pollMessage);
498
470
  }
499
471
  /**
500
472
  * * Trata atualizações de participantes
@@ -504,341 +476,154 @@ class WhatsAppBot extends BotEvents_1.default {
504
476
  * @param fromId Usuário que realizou a ação
505
477
  */
506
478
  async groupParticipantsUpdate(action, chatId, userId, fromId) {
507
- if (!chatId.includes('@g'))
508
- return;
509
- const event = action == 'join' ? 'add' : action == 'leave' ? 'remove' : action;
510
- let chat = await this.getChat(new Chat_1.default(chatId));
511
- if (!chat) {
512
- if (!this.config.autoLoadGroupInfo)
513
- return;
514
- chat = Chat_1.default.fromJSON({
515
- id: chatId,
516
- phoneNumber: (0, ID_1.getPhoneNumber)(chatId),
517
- type: ChatType_1.default.Group,
518
- });
519
- }
520
- const fromUser = (await this.getUser(new User_1.default(fromId))) ||
521
- User_1.default.fromJSON({ id: fromId, phoneNumber: (0, ID_1.getPhoneNumber)(fromId) });
522
- const user = (await this.getUser(new User_1.default(userId))) ||
523
- User_1.default.fromJSON({ id: userId, phoneNumber: (0, ID_1.getPhoneNumber)(userId) });
524
- let users = chat.users || [];
525
- const admins = chat.admins || [];
526
- if (event == 'add')
527
- users.push(user.id);
528
- if (event == 'remove')
529
- users = users.filter((u) => u != user.id);
530
- if (event == 'demote')
531
- chat.admins = admins.filter((admin) => admin != user.id);
532
- if (event == 'promote')
533
- admins.push(user.id);
534
- chat.users = users;
535
- chat.admins = admins;
536
- if (user.id == this.id) {
537
- if (event == 'remove')
538
- await this.removeChat(chat);
539
- if (event == 'add')
540
- await this.updateChat(chat);
541
- }
542
- else {
543
- await this.updateChat(chat);
544
- }
545
- this.ev.emit('user', { action, event, user, fromUser, chat });
479
+ return this.groupOperations.groupParticipantsUpdate(action, chatId, userId, fromId);
546
480
  }
547
481
  //! ********************************* CHAT *********************************
548
482
  async getChatName(chat) {
549
- var _a;
550
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.name) || '';
483
+ return this.chatOperations.getChatName(chat);
551
484
  }
552
485
  async setChatName(chat, name) {
553
- if (!(0, baileys_1.isJidGroup)(chat.id))
554
- return;
555
- const admins = await this.getChatAdmins(chat);
556
- if (admins.length && !admins.includes(this.id))
557
- return;
558
- await this.sock.groupUpdateSubject(chat.id, name);
486
+ return this.chatOperations.setChatName(chat, name);
559
487
  }
560
488
  async getChatDescription(chat) {
561
- var _a;
562
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.description) || '';
489
+ return this.chatOperations.getChatDescription(chat);
563
490
  }
564
491
  async setChatDescription(chat, description) {
565
- if (!(0, baileys_1.isJidGroup)(chat.id))
566
- return;
567
- const admins = await this.getChatAdmins(chat);
568
- if (admins.length && !admins.includes(this.id))
569
- return;
570
- await this.sock.groupUpdateDescription(chat.id, description);
492
+ return this.chatOperations.setChatDescription(chat, description);
571
493
  }
572
494
  async getChatProfile(chat, lowQuality) {
573
- const uri = await this.getChatProfileUrl(chat, lowQuality);
574
- return await (0, Generic_1.getImageURL)(uri);
495
+ return this.chatOperations.getChatProfile(chat, lowQuality);
575
496
  }
576
497
  async getChatProfileUrl(chat, lowQuality) {
577
- try {
578
- return ((await this.sock.profilePictureUrl(chat.id, lowQuality ? 'preview' : 'image')) || '');
579
- }
580
- catch (_a) {
581
- return '';
582
- }
498
+ return this.chatOperations.getChatProfileUrl(chat, lowQuality);
583
499
  }
584
500
  async setChatProfile(chat, image) {
585
- if (!(0, baileys_1.isJidGroup)(chat.id))
586
- return;
587
- const admins = await this.getChatAdmins(chat);
588
- if (admins.length && !admins.includes(this.id))
589
- return;
590
- await this.sock.updateProfilePicture(chat.id, image);
501
+ return this.chatOperations.setChatProfile(chat, image);
591
502
  }
592
503
  async updateChat(chat) {
593
- const chatData = await this.getChat(new Chat_1.default(chat.id));
594
- if (chatData != null) {
595
- chat = Object.keys(chat).reduce((data, key) => {
596
- if (chat[key] == undefined || chat[key] == null)
597
- return data;
598
- if ((0, Generic_1.verifyIsEquals)(chat[key], chatData[key]))
599
- return data;
600
- return { ...data, [key]: chat[key] };
601
- }, { id: chat.id });
602
- if (Object.keys(chat).length < 2)
603
- return;
604
- }
605
- const newChat = Chat_1.default.fromJSON({ ...(chatData || {}), ...chat });
606
- newChat.type = (0, baileys_1.isJidGroup)(chat.id) ? ChatType_1.default.Group : ChatType_1.default.PV;
607
- newChat.phoneNumber = newChat.phoneNumber || (0, ID_1.getPhoneNumber)(chat.id);
608
- await this.auth.set(`chats-${chat.id}`, newChat.toJSON());
609
- this.ev.emit('chat', { action: chatData != null ? 'update' : 'add', chat });
504
+ return this.chatOperations.updateChat(chat);
610
505
  }
611
506
  async removeChat(chat) {
612
- await this.auth.remove(`chats-${chat.id}`);
613
- this.ev.emit('chat', { action: 'remove', chat });
507
+ return this.chatOperations.removeChat(chat);
614
508
  }
615
509
  async getChat(chat) {
616
- const chatData = await this.auth.get(`chats-${chat.id}`);
617
- if (!chatData)
618
- return null;
619
- if (!chat.name || !chat.profileUrl) {
620
- const user = await this.getUser(new User_1.default(chat.id));
621
- if (user != null) {
622
- return Chat_1.default.fromJSON({ ...chat, ...user });
623
- }
624
- }
625
- return Chat_1.default.fromJSON(chatData);
510
+ return this.chatOperations.getChat(chat);
626
511
  }
627
512
  async getChats() {
628
- return (await this.auth.listAll('chats-')).map((id) => id.replace('chats-', ''));
513
+ return this.chatOperations.getChats();
629
514
  }
630
515
  async setChats(chats) {
631
- await Promise.all(chats.map(async (chat) => await this.updateChat(chat)));
516
+ return this.chatOperations.setChats(chats);
632
517
  }
633
518
  async getChatUsers(chat) {
634
- var _a;
635
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.users) || [];
519
+ return this.chatOperations.getChatUsers(chat);
636
520
  }
637
521
  async getChatAdmins(chat) {
638
- var _a, _b;
639
- const chatReaded = await this.getChat(chat);
640
- if (!chatReaded)
641
- return [];
642
- if ((_a = chatReaded.admins) === null || _a === void 0 ? void 0 : _a.length) {
643
- return chatReaded.admins || [];
644
- }
645
- if (chatReaded.type !== ChatType_1.default.Group)
646
- return [];
647
- await this.readChat(chat);
648
- return ((_b = (await this.getChat(chat))) === null || _b === void 0 ? void 0 : _b.admins) || [];
522
+ return this.chatOperations.getChatAdmins(chat);
649
523
  }
650
524
  async getChatLeader(chat) {
651
- var _a;
652
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.leader) || '';
525
+ return this.chatOperations.getChatLeader(chat);
653
526
  }
654
527
  async addUserInChat(chat, user) {
655
- if (!(0, baileys_1.isJidGroup)(chat.id))
656
- return;
657
- const admins = await this.getChatAdmins(chat);
658
- if (admins.length && !admins.includes(this.id))
659
- return;
660
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'add');
528
+ return this.groupOperations.addUserInChat(chat, user);
661
529
  }
662
530
  async removeUserInChat(chat, user) {
663
- if (!(0, baileys_1.isJidGroup)(chat.id))
664
- return;
665
- const admins = await this.getChatAdmins(chat);
666
- if (admins.length && !admins.includes(this.id))
667
- return;
668
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'remove');
531
+ return this.groupOperations.removeUserInChat(chat, user);
669
532
  }
670
533
  async promoteUserInChat(chat, user) {
671
- if (!(0, baileys_1.isJidGroup)(chat.id))
672
- return;
673
- const admins = await this.getChatAdmins(chat);
674
- if (admins.length && !admins.includes(this.id))
675
- return;
676
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'promote');
534
+ return this.groupOperations.promoteUserInChat(chat, user);
677
535
  }
678
536
  async demoteUserInChat(chat, user) {
679
- if (!(0, baileys_1.isJidGroup)(chat.id))
680
- return;
681
- const admins = await this.getChatAdmins(chat);
682
- if (admins.length && !admins.includes(this.id))
683
- return;
684
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'demote');
537
+ return this.groupOperations.demoteUserInChat(chat, user);
685
538
  }
686
539
  async changeChatStatus(chat, status) {
687
- await this.sock.sendPresenceUpdate(WAStatus_1.WAStatus[status] || 'available', chat.id);
540
+ return this.chatOperations.changeChatStatus(chat, status);
688
541
  }
689
542
  async createChat(chat) {
690
- await this.sock.groupCreate(chat.name || '', [this.id]);
543
+ return this.chatOperations.createChat(chat);
691
544
  }
692
545
  async leaveChat(chat) {
693
- if (!(0, baileys_1.isJidGroup)(chat.id))
694
- return;
695
- if ((await this.getChat(chat)) == null)
696
- return;
697
- await this.sock.groupLeave(chat.id);
698
- await this.removeChat(chat);
546
+ return this.chatOperations.leaveChat(chat);
699
547
  }
700
548
  async joinChat(code) {
701
- await this.sock.groupAcceptInvite(code.replace('https://chat.whatsapp.com/', ''));
549
+ return this.chatOperations.joinChat(code);
702
550
  }
703
551
  async getChatInvite(chat) {
704
- if (!(0, baileys_1.isJidGroup)(chat.id))
705
- return '';
706
- // TODO: Return undefined if user is not admin
707
- const admins = await this.getChatAdmins(chat);
708
- if (admins.length && !admins.includes(this.id))
709
- return '';
710
- return (await this.sock.groupInviteCode(chat.id)) || '';
552
+ return this.chatOperations.getChatInvite(chat);
711
553
  }
712
554
  async revokeChatInvite(chat) {
713
- if (!(0, baileys_1.isJidGroup)(chat.id))
714
- return '';
715
- const admins = await this.getChatAdmins(chat);
716
- if (admins.length && !admins.includes(this.id))
717
- return '';
718
- return (await this.sock.groupRevokeInvite(chat.id)) || '';
555
+ return this.chatOperations.revokeChatInvite(chat);
719
556
  }
720
557
  async rejectCall(call) {
721
558
  await this.sock.rejectCall(call.id, call.chat.id);
722
559
  }
723
560
  async getUserName(user) {
724
- var _a;
725
- return ((_a = (await this.getUser(user))) === null || _a === void 0 ? void 0 : _a.name) || '';
561
+ return this.userOperations.getUserName(user);
726
562
  }
727
563
  async setUserName(user, name) {
728
- if (user.id != this.id)
729
- return;
730
- await this.setBotName(name);
564
+ return this.userOperations.setUserName(user, name);
731
565
  }
732
566
  async getUserDescription(user) {
733
- // O método fetchStatus não existe na API pública do Baileys
734
- // return (await this.sock.fetchStatus(String(user.id)))[0]?.status || '';
735
- throw new Error('getUserDescription não implementado: fetchStatus não disponível na API do Baileys');
567
+ return this.userOperations.getUserDescription(user);
736
568
  }
737
569
  async setUserDescription(user, description) {
738
- if (user.id != this.id)
739
- return;
740
- await this.setBotDescription(description);
570
+ return this.userOperations.setUserDescription(user, description);
741
571
  }
742
572
  async getUserProfile(user, lowQuality) {
743
- const uri = await this.getUserProfileUrl(user, lowQuality);
744
- return await (0, Generic_1.getImageURL)(uri);
573
+ return this.userOperations.getUserProfile(user, lowQuality);
745
574
  }
746
575
  async getUserProfileUrl(user, lowQuality) {
747
- try {
748
- return ((await this.sock.profilePictureUrl(user.id, lowQuality ? 'preview' : 'image')) || '');
749
- }
750
- catch (_a) {
751
- return '';
752
- }
576
+ return this.userOperations.getUserProfileUrl(user, lowQuality);
753
577
  }
754
578
  async setUserProfile(user, image) {
755
- if (user.id != this.id)
756
- return;
757
- await this.setBotProfile(image);
579
+ return this.userOperations.setUserProfile(user, image);
758
580
  }
759
581
  async getUser(user) {
760
- const userData = await this.auth.get(`users-${user.id}`);
761
- if (!userData)
762
- return null;
763
- return User_1.default.fromJSON(userData);
582
+ return this.userOperations.getUser(user);
764
583
  }
765
584
  async getUsers() {
766
- return (await this.auth.listAll('users-')).map((id) => id.replace('users-', ''));
585
+ return this.userOperations.getUsers();
767
586
  }
768
587
  async updateUser(user) {
769
- const userData = await this.getUser(new User_1.default(user.id));
770
- if (userData != null) {
771
- user = Object.keys(user).reduce((data, key) => {
772
- if (user[key] == undefined || user[key] == null)
773
- return data;
774
- if ((0, Generic_1.verifyIsEquals)(user[key], userData[key]))
775
- return data;
776
- return { ...data, [key]: user[key] };
777
- }, { id: user.id });
778
- if (Object.keys(user).length < 2)
779
- return;
780
- }
781
- const newUser = User_1.default.fromJSON({ ...(userData || {}), ...user });
782
- newUser.phoneNumber = newUser.phoneNumber || (0, ID_1.getPhoneNumber)(user.id);
783
- await this.auth.set(`users-${user.id}`, newUser.toJSON());
588
+ return this.userOperations.updateUser(user);
784
589
  }
785
590
  async setUsers(users) {
786
- await Promise.all(users.map(async (user) => await this.updateUser(user)));
591
+ return this.userOperations.setUsers(users);
787
592
  }
788
593
  async removeUser(user) {
789
- await this.auth.remove(`users-${user.id}`);
594
+ return this.userOperations.removeUser(user);
790
595
  }
791
596
  async blockUser(user) {
792
- if (user.id == this.id)
793
- return;
794
- await this.sock.updateBlockStatus(user.id, 'block');
597
+ return this.userOperations.blockUser(user);
795
598
  }
796
599
  async unblockUser(user) {
797
- if (user.id == this.id)
798
- return;
799
- await this.sock.updateBlockStatus(user.id, 'unblock');
600
+ return this.userOperations.unblockUser(user);
800
601
  }
801
602
  //! ******************************** BOT ********************************
802
603
  async getBotName() {
803
- return await this.getUserName(new User_1.default(this.id));
604
+ return this.userOperations.getBotName();
804
605
  }
805
606
  async setBotName(name) {
806
- await this.sock.updateProfileName(name);
607
+ return this.userOperations.setBotName(name);
807
608
  }
808
609
  async getBotDescription() {
809
- return await this.getUserDescription(new User_1.default(this.id));
610
+ return this.userOperations.getBotDescription();
810
611
  }
811
612
  async setBotDescription(description) {
812
- await this.sock.updateProfileStatus(description);
613
+ return this.userOperations.setBotDescription(description);
813
614
  }
814
615
  async getBotProfile(lowQuality) {
815
- return await this.getUserProfile(new User_1.default(this.id), lowQuality);
616
+ return this.userOperations.getBotProfile(lowQuality);
816
617
  }
817
618
  async getBotProfileUrl(lowQuality) {
818
- return (await this.getUserProfileUrl(new User_1.default(this.id), lowQuality)) || '';
619
+ return this.userOperations.getBotProfileUrl(lowQuality);
819
620
  }
820
621
  async setBotProfile(image) {
821
- await this.sock.updateProfilePicture(this.id, image);
622
+ return this.userOperations.setBotProfile(image);
822
623
  }
823
624
  //! ******************************* MESSAGE *******************************
824
625
  async readMessage(message) {
825
- const key = {
826
- remoteJid: message.chat.id,
827
- id: message.id || '',
828
- fromMe: message.fromMe || message.user.id == this.id,
829
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
830
- ? message.user.id || this.id || undefined
831
- : undefined,
832
- toJSON: () => key,
833
- };
834
- // v7.0.0: Removido ACKs automáticos para evitar banimentos
835
- // O WhatsApp agora gerencia automaticamente o status de leitura
836
- const chat = await this.getChat(message.chat);
837
- // Apenas marcar como lido localmente, sem enviar ACK
838
- if ((chat === null || chat === void 0 ? void 0 : chat.type) == ChatType_1.default.Group || (chat === null || chat === void 0 ? void 0 : chat.type) == ChatType_1.default.PV) {
839
- // Marcar mensagem como lida apenas no cache local
840
- this.addMessageCache(message.id || '');
841
- }
626
+ return this.messageOperations.readMessage(message);
842
627
  }
843
628
  // Adiciona um método utilitário para cache de mensagens
844
629
  addMessageCache(id) {
@@ -849,23 +634,19 @@ class WhatsAppBot extends BotEvents_1.default {
849
634
  // ================= APP STATE UPDATES =================
850
635
  /** Arquiva ou desarquiva um chat */
851
636
  async archiveChat(chat, archive = true, lastMessages) {
852
- const chatId = typeof chat === 'string' ? chat : chat.id;
853
- await this.sock.chatModify({ archive, lastMessages }, chatId);
637
+ return this.chatOperations.archiveChat(chat, archive, lastMessages);
854
638
  }
855
639
  /** Silencia ou dessilencia um chat */
856
640
  async muteChat(chat, mute, lastMessages) {
857
- const chatId = typeof chat === 'string' ? chat : chat.id;
858
- await this.sock.chatModify({ mute, lastMessages }, chatId);
641
+ return this.chatOperations.muteChat(chat, mute, lastMessages);
859
642
  }
860
643
  /** Marca um chat como lido */
861
644
  async markChatRead(chat, read = true, lastMessages) {
862
- const chatId = typeof chat === 'string' ? chat : chat.id;
863
- await this.sock.chatModify({ markRead: read, lastMessages }, chatId);
645
+ return this.chatOperations.markChatRead(chat, read, lastMessages);
864
646
  }
865
647
  /** Define o modo de mensagens temporárias em um chat */
866
648
  async setDisappearingMessages(chat, duration) {
867
- const chatId = typeof chat === 'string' ? chat : chat.id;
868
- await this.sock.sendMessage(chatId, { disappearingMessagesInChat: duration });
649
+ return this.chatOperations.setDisappearingMessages(chat, duration);
869
650
  }
870
651
  // ================= BUSINESS FEATURES =================
871
652
  /** Busca o perfil de negócio de um contato */
@@ -903,121 +684,39 @@ class WhatsAppBot extends BotEvents_1.default {
903
684
  * Adiciona uma reação a uma mensagem
904
685
  */
905
686
  async addReaction(message) {
906
- var _a;
907
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id) || !message.reaction)
908
- return;
909
- await this.sock.sendMessage(message.chat.id, {
910
- react: {
911
- text: message.reaction,
912
- key: {
913
- id: message.id,
914
- remoteJid: message.chat.id,
915
- fromMe: message.fromMe || message.user.id === this.id,
916
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
917
- ? message.user.id || this.id || undefined
918
- : undefined,
919
- },
920
- },
921
- });
687
+ return this.messageOperations.addReaction(message);
922
688
  }
923
689
  /** Remove uma reação de uma mensagem */
924
690
  async removeReaction(message) {
925
- var _a;
926
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
927
- return;
928
- await this.sock.sendMessage(message.chat.id, {
929
- react: {
930
- text: '',
931
- key: {
932
- id: message.id,
933
- remoteJid: message.chat.id,
934
- fromMe: message.fromMe || message.user.id === this.id,
935
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
936
- ? message.user.id || this.id || undefined
937
- : undefined,
938
- },
939
- },
940
- });
691
+ return this.messageOperations.removeReaction(message);
941
692
  }
942
693
  /** Edita o texto de uma mensagem enviada */
943
694
  async editMessage(message) {
944
- var _a;
945
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
946
- return;
947
- await this.sock.sendMessage(message.chat.id, {
948
- edit: {
949
- remoteJid: message.chat.id,
950
- id: message.id,
951
- fromMe: message.fromMe || message.user.id === this.id,
952
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
953
- ? message.user.id || this.id || undefined
954
- : undefined,
955
- },
956
- text: message.text,
957
- });
695
+ return this.messageOperations.editMessage(message);
958
696
  }
959
697
  /** Envia uma mensagem */
960
698
  async send(message) {
961
- var _a;
962
- try {
963
- const waMsg = (await new ConvertToWAMessage_1.default(this, message).refactory()).waMessage;
964
- const sent = await this.sock.sendMessage(message.chat.id, waMsg);
965
- if (sent && sent.key && sent.key.id)
966
- message.id = sent.key.id;
967
- return message;
968
- }
969
- catch (error) {
970
- // Log detalhado para diagnóstico
971
- console.error('[WhatsAppBot.send] Erro ao enviar mensagem', {
972
- chatId: (_a = message === null || message === void 0 ? void 0 : message.chat) === null || _a === void 0 ? void 0 : _a.id,
973
- messageObj: message,
974
- error
975
- });
976
- throw error;
977
- }
699
+ return this.messageOperations.send(message);
978
700
  }
979
701
  /** Remove uma mensagem (marca como removida para todos) */
980
702
  async removeMessage(message) {
981
- var _a;
982
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
983
- return;
984
- await this.sock.sendMessage(message.chat.id, {
985
- delete: {
986
- remoteJid: message.chat.id,
987
- id: message.id,
988
- fromMe: message.fromMe || message.user.id === this.id,
989
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
990
- ? message.user.id || this.id || undefined
991
- : undefined,
992
- },
993
- });
703
+ return this.messageOperations.removeMessage(message);
994
704
  }
995
705
  /** Deleta uma mensagem (remove do histórico) */
996
706
  async deleteMessage(message) {
997
- var _a;
998
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
999
- return;
1000
- await this.sock.sendMessage(message.chat.id, {
1001
- delete: {
1002
- remoteJid: message.chat.id,
1003
- id: message.id,
1004
- fromMe: message.fromMe || message.user.id === this.id,
1005
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
1006
- ? message.user.id || this.id || undefined
1007
- : undefined,
1008
- },
1009
- });
707
+ return this.messageOperations.deleteMessage(message);
1010
708
  }
1011
709
  /** Baixa a stream de mídia de uma mensagem */
1012
710
  async downloadStreamMessage(media) {
1013
- // media é um MediaMessage, que herda de Message
1014
- const msg = await this.store.loadMessage(media.chat.id, media.id);
1015
- if (!msg)
1016
- return Buffer.from("");
1017
- // downloadMediaMessage espera (msg, type, options?)
1018
- return Buffer.from(await (0, baileys_1.downloadMediaMessage)(msg, "buffer", {
1019
- // opções extras se necessário
1020
- }));
711
+ // A interface IBot espera Media, mas internamente precisamos de MediaMessage
712
+ // MediaMessage estende Message e tem chat e id necessários para carregar do store
713
+ // Na prática, sempre será passado MediaMessage, então fazemos type assertion
714
+ if (media instanceof MediaMessage_1.default) {
715
+ return this.messageOperations.downloadStreamMessage(media);
716
+ }
717
+ // Se não for MediaMessage, tenta usar como MediaMessage (compatibilidade)
718
+ // Isso permite que código que passa MediaMessage funcione
719
+ return this.messageOperations.downloadStreamMessage(media);
1021
720
  }
1022
721
  }
1023
722
  exports.default = WhatsAppBot;