trompot 1.5.0 → 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 (144) hide show
  1. package/README.md +195 -20
  2. package/lib/bot/BotEvents.d.ts +2 -0
  3. package/lib/bot/BotEvents.js.map +1 -1
  4. package/lib/client/Client.js +93 -28
  5. package/lib/client/Client.js.map +1 -1
  6. package/lib/client/ClientFunctionHandler.js +39 -3
  7. package/lib/client/ClientFunctionHandler.js.map +1 -1
  8. package/lib/telegram/TelegramAuth.js +36 -1
  9. package/lib/telegram/TelegramAuth.js.map +1 -1
  10. package/lib/telegram/TelegramBot.d.ts +11 -0
  11. package/lib/telegram/TelegramBot.js +101 -15
  12. package/lib/telegram/TelegramBot.js.map +1 -1
  13. package/lib/telegram/TelegramEvents.d.ts +8 -1
  14. package/lib/telegram/TelegramEvents.js +67 -30
  15. package/lib/telegram/TelegramEvents.js.map +1 -1
  16. package/lib/telegram/TelegramSendingController.js +59 -17
  17. package/lib/telegram/TelegramSendingController.js.map +1 -1
  18. package/lib/telegram/TelegramToRompotConverter.js +44 -14
  19. package/lib/telegram/TelegramToRompotConverter.js.map +1 -1
  20. package/lib/wa/Auth.js +17 -5
  21. package/lib/wa/Auth.js.map +1 -1
  22. package/lib/wa/ConfigWAEvents.d.ts +6 -10
  23. package/lib/wa/ConfigWAEvents.js +220 -426
  24. package/lib/wa/ConfigWAEvents.js.map +1 -1
  25. package/lib/wa/ConvertWAMessage.js +28 -19
  26. package/lib/wa/ConvertWAMessage.js.map +1 -1
  27. package/lib/wa/ID.d.ts +10 -1
  28. package/lib/wa/ID.js +22 -2
  29. package/lib/wa/ID.js.map +1 -1
  30. package/lib/wa/WhatsAppBot.d.ts +58 -11
  31. package/lib/wa/WhatsAppBot.js +365 -648
  32. package/lib/wa/WhatsAppBot.js.map +1 -1
  33. package/lib/wa/constants/ConfigDefaults.d.ts +23 -0
  34. package/lib/wa/constants/ConfigDefaults.js +27 -0
  35. package/lib/wa/constants/ConfigDefaults.js.map +1 -0
  36. package/lib/wa/constants/DisconnectReasons.d.ts +24 -0
  37. package/lib/wa/constants/DisconnectReasons.js +36 -0
  38. package/lib/wa/constants/DisconnectReasons.js.map +1 -0
  39. package/lib/wa/constants/ErrorCodes.d.ts +28 -0
  40. package/lib/wa/constants/ErrorCodes.js +32 -0
  41. package/lib/wa/constants/ErrorCodes.js.map +1 -0
  42. package/lib/wa/constants/JIDPatterns.d.ts +23 -0
  43. package/lib/wa/constants/JIDPatterns.js +38 -0
  44. package/lib/wa/constants/JIDPatterns.js.map +1 -0
  45. package/lib/wa/constants/Timeouts.d.ts +11 -0
  46. package/lib/wa/constants/Timeouts.js +15 -0
  47. package/lib/wa/constants/Timeouts.js.map +1 -0
  48. package/lib/wa/core/ConnectionManager.d.ts +84 -0
  49. package/lib/wa/core/ConnectionManager.js +256 -0
  50. package/lib/wa/core/ConnectionManager.js.map +1 -0
  51. package/lib/wa/core/SessionManager.d.ts +29 -0
  52. package/lib/wa/core/SessionManager.js +155 -0
  53. package/lib/wa/core/SessionManager.js.map +1 -0
  54. package/lib/wa/core/StateManager.d.ts +49 -0
  55. package/lib/wa/core/StateManager.js +135 -0
  56. package/lib/wa/core/StateManager.js.map +1 -0
  57. package/lib/wa/events/CallEventHandler.d.ts +17 -0
  58. package/lib/wa/events/CallEventHandler.js +155 -0
  59. package/lib/wa/events/CallEventHandler.js.map +1 -0
  60. package/lib/wa/events/ChatEventHandler.d.ts +12 -0
  61. package/lib/wa/events/ChatEventHandler.js +74 -0
  62. package/lib/wa/events/ChatEventHandler.js.map +1 -0
  63. package/lib/wa/events/ConnectionEventHandler.d.ts +43 -0
  64. package/lib/wa/events/ConnectionEventHandler.js +305 -0
  65. package/lib/wa/events/ConnectionEventHandler.js.map +1 -0
  66. package/lib/wa/events/ContactEventHandler.d.ts +12 -0
  67. package/lib/wa/events/ContactEventHandler.js +55 -0
  68. package/lib/wa/events/ContactEventHandler.js.map +1 -0
  69. package/lib/wa/events/EventManager.d.ts +43 -0
  70. package/lib/wa/events/EventManager.js +198 -0
  71. package/lib/wa/events/EventManager.js.map +1 -0
  72. package/lib/wa/events/GroupEventHandler.d.ts +12 -0
  73. package/lib/wa/events/GroupEventHandler.js +74 -0
  74. package/lib/wa/events/GroupEventHandler.js.map +1 -0
  75. package/lib/wa/events/HistoryEventHandler.d.ts +16 -0
  76. package/lib/wa/events/HistoryEventHandler.js +101 -0
  77. package/lib/wa/events/HistoryEventHandler.js.map +1 -0
  78. package/lib/wa/events/LIDMappingEventHandler.d.ts +20 -0
  79. package/lib/wa/events/LIDMappingEventHandler.js +39 -0
  80. package/lib/wa/events/LIDMappingEventHandler.js.map +1 -0
  81. package/lib/wa/events/MessageEventHandler.d.ts +16 -0
  82. package/lib/wa/events/MessageEventHandler.js +218 -0
  83. package/lib/wa/events/MessageEventHandler.js.map +1 -0
  84. package/lib/wa/interfaces/ICacheService.d.ts +12 -0
  85. package/lib/wa/interfaces/ICacheService.js +3 -0
  86. package/lib/wa/interfaces/ICacheService.js.map +1 -0
  87. package/lib/wa/interfaces/IConnectionManager.d.ts +15 -0
  88. package/lib/wa/interfaces/IConnectionManager.js +3 -0
  89. package/lib/wa/interfaces/IConnectionManager.js.map +1 -0
  90. package/lib/wa/interfaces/IErrorHandler.d.ts +9 -0
  91. package/lib/wa/interfaces/IErrorHandler.js +3 -0
  92. package/lib/wa/interfaces/IErrorHandler.js.map +1 -0
  93. package/lib/wa/interfaces/ILoggerService.d.ts +13 -0
  94. package/lib/wa/interfaces/ILoggerService.js +3 -0
  95. package/lib/wa/interfaces/ILoggerService.js.map +1 -0
  96. package/lib/wa/interfaces/ISessionManager.d.ts +16 -0
  97. package/lib/wa/interfaces/ISessionManager.js +3 -0
  98. package/lib/wa/interfaces/ISessionManager.js.map +1 -0
  99. package/lib/wa/interfaces/IStateManager.d.ts +41 -0
  100. package/lib/wa/interfaces/IStateManager.js +3 -0
  101. package/lib/wa/interfaces/IStateManager.js.map +1 -0
  102. package/lib/wa/operations/ChatOperations.d.ts +117 -0
  103. package/lib/wa/operations/ChatOperations.js +349 -0
  104. package/lib/wa/operations/ChatOperations.js.map +1 -0
  105. package/lib/wa/operations/GroupOperations.d.ts +31 -0
  106. package/lib/wa/operations/GroupOperations.js +128 -0
  107. package/lib/wa/operations/GroupOperations.js.map +1 -0
  108. package/lib/wa/operations/MessageOperations.d.ts +69 -0
  109. package/lib/wa/operations/MessageOperations.js +335 -0
  110. package/lib/wa/operations/MessageOperations.js.map +1 -0
  111. package/lib/wa/operations/UserOperations.d.ts +100 -0
  112. package/lib/wa/operations/UserOperations.js +216 -0
  113. package/lib/wa/operations/UserOperations.js.map +1 -0
  114. package/lib/wa/services/CacheService.d.ts +45 -0
  115. package/lib/wa/services/CacheService.js +93 -0
  116. package/lib/wa/services/CacheService.js.map +1 -0
  117. package/lib/wa/services/ErrorHandler.d.ts +26 -0
  118. package/lib/wa/services/ErrorHandler.js +73 -0
  119. package/lib/wa/services/ErrorHandler.js.map +1 -0
  120. package/lib/wa/services/LIDMappingService.d.ts +42 -0
  121. package/lib/wa/services/LIDMappingService.js +132 -0
  122. package/lib/wa/services/LIDMappingService.js.map +1 -0
  123. package/lib/wa/services/LIDNormalizationService.d.ts +30 -0
  124. package/lib/wa/services/LIDNormalizationService.js +136 -0
  125. package/lib/wa/services/LIDNormalizationService.js.map +1 -0
  126. package/lib/wa/services/LoggerService.d.ts +44 -0
  127. package/lib/wa/services/LoggerService.js +85 -0
  128. package/lib/wa/services/LoggerService.js.map +1 -0
  129. package/lib/wa/services/PendingMessageQueue.d.ts +46 -0
  130. package/lib/wa/services/PendingMessageQueue.js +119 -0
  131. package/lib/wa/services/PendingMessageQueue.js.map +1 -0
  132. package/lib/wa/services/RetryService.d.ts +25 -0
  133. package/lib/wa/services/RetryService.js +59 -0
  134. package/lib/wa/services/RetryService.js.map +1 -0
  135. package/lib/wa/utils/ConfigValidator.d.ts +15 -0
  136. package/lib/wa/utils/ConfigValidator.js +66 -0
  137. package/lib/wa/utils/ConfigValidator.js.map +1 -0
  138. package/lib/wa/utils/ErrorUtils.d.ts +29 -0
  139. package/lib/wa/utils/ErrorUtils.js +66 -0
  140. package/lib/wa/utils/ErrorUtils.js.map +1 -0
  141. package/lib/wa/utils/Validation.d.ts +18 -0
  142. package/lib/wa/utils/Validation.js +40 -0
  143. package/lib/wa/utils/Validation.js.map +1 -0
  144. 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,195 +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
- await this.internalConnect({ browser: baileys_1.Browsers.windows('Rompot') });
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.');
219
224
  }
220
225
  else {
221
- await this.internalConnect({
222
- browser: ['Chrome (linux)', 'Rompot', '22.5.0'],
223
- });
224
- 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)) {
225
- await this.sock.waitForConnectionUpdate(async (update) => Promise.resolve(!!update.qr));
226
- const code = await this.sock.requestPairingCode(this.auth.botPhoneNumber);
227
- this.emit('code', code);
228
- }
226
+ this.loggerService.warn(`⚠️ Sessão pode estar inválida, mas QR code não será gerado automaticamente.`);
229
227
  }
230
- await this.awaitConnectionState('open');
228
+ // Cria e configura o socket (método centralizado)
229
+ await this.createSocket();
231
230
  }
232
- async internalConnect(additionalOptions = {}) {
233
- 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) {
234
273
  try {
235
- const { state, saveCreds } = await (0, Auth_1.getBaileysAuth)(this.auth);
236
- this.saveCreds = saveCreds;
237
- this.sock = (0, baileys_1.default)({
238
- auth: {
239
- creds: state.creds,
240
- keys: (0, baileys_1.makeCacheableSignalKeyStore)(state.keys, this.config.logger),
241
- // v7.0.0-rc.5: Configuração básica de auth
242
- // LIDs serão implementados quando estiverem disponíveis na API estável
243
- },
244
- ...additionalOptions,
245
- ...this.config,
246
- });
247
- this.store.bind(this.sock.ev);
248
- this.configEvents.configureAll();
249
- resolve();
250
- await this.awaitConnectionState('open');
251
- this.sock.ev.on('creds.update', saveCreds);
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);
252
278
  }
253
279
  catch (err) {
254
- this.ev.emit('error', err);
280
+ // Ignora erros
255
281
  }
256
- });
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);
257
322
  }
258
323
  /**
259
324
  * * Reconecta ao servidor do WhatsApp
260
325
  * @returns
261
326
  */
262
- async reconnect(stopEvents = false, showOpen) {
263
- if (stopEvents) {
264
- this.eventsIsStoped = true;
265
- let state = this.status == BotStatus_1.BotStatus.Online ? 'close' : 'connecting';
266
- let status = baileys_1.DisconnectReason.connectionClosed;
267
- let retryCount = 0;
268
- this.connectionListeners.push((update) => {
269
- var _a, _b, _c, _d, _e, _f, _g, _h;
270
- if (!update.connection)
271
- return false;
272
- if (retryCount >= 3) {
273
- this.eventsIsStoped = false;
274
- return true;
275
- }
276
- if (update.connection != state) {
277
- if (update.connection == 'close') {
278
- state = 'connecting';
279
- status =
280
- ((_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) ||
281
- ((_d = update.lastDisconnect) === null || _d === void 0 ? void 0 : _d.error) ||
282
- baileys_1.DisconnectReason.connectionClosed;
283
- retryCount++;
284
- }
285
- else {
286
- this.eventsIsStoped = false;
287
- if (state == 'connecting') {
288
- this.emit('close', { reason: status });
289
- }
290
- else if (state == 'open') {
291
- this.emit('close', { reason: status });
292
- this.emit('connecting', {});
293
- }
294
- }
295
- return true;
296
- }
297
- if (state == 'close') {
298
- state = 'connecting';
299
- status =
300
- ((_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) ||
301
- ((_h = update.lastDisconnect) === null || _h === void 0 ? void 0 : _h.error) ||
302
- baileys_1.DisconnectReason.connectionClosed;
303
- }
304
- else if (state == 'connecting') {
305
- state = 'open';
306
- }
307
- else if (state == 'open' && showOpen) {
308
- this.eventsIsStoped = !showOpen;
309
- return true;
310
- }
311
- return false;
312
- });
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));
313
365
  }
314
- await this.stop();
315
366
  this.emit('reconnecting', {});
316
- 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();
317
371
  }
318
372
  /**
319
373
  * * Desliga a conexão com o servidor do WhatsApp
320
374
  * @param reason
321
375
  * @returns
322
376
  */
323
- async stop(reason = 402) {
324
- var _a;
377
+ async stop(reason = ErrorCodes_1.ErrorCodes.CONNECTION_CLOSED) {
325
378
  try {
326
- this.status = BotStatus_1.BotStatus.Offline;
327
- (_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);
328
391
  }
329
392
  catch (err) {
393
+ this.errorHandler.handle(err, 'WhatsAppBot.stop');
330
394
  this.emit('error', err);
331
395
  }
332
396
  }
@@ -338,13 +402,41 @@ class WhatsAppBot extends BotEvents_1.default {
338
402
  * * Aguarda um status de conexão
339
403
  */
340
404
  async awaitConnectionState(connection) {
341
- return new Promise((res) => {
342
- 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) => {
343
417
  if (update.connection != connection)
344
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
+ }
345
425
  res(update);
346
426
  return true;
347
- });
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
+ }
348
440
  });
349
441
  }
350
442
  /**
@@ -352,110 +444,14 @@ class WhatsAppBot extends BotEvents_1.default {
352
444
  * @param chat Sala de bate-papo
353
445
  */
354
446
  async readChat(chat, metadata, updateMetadata = true) {
355
- try {
356
- if (!chat.id || !(chat.id.includes('@s') || chat.id.includes('@g')))
357
- return;
358
- chat.type = (0, baileys_1.isJidGroup)(chat.id) ? ChatType_1.default.Group : ChatType_1.default.PV;
359
- if (chat.type == ChatType_1.default.Group) {
360
- if (updateMetadata) {
361
- chat.profileUrl =
362
- (await this.getChatProfileUrl(new Chat_1.default(chat.id))) || undefined;
363
- if (!metadata) {
364
- try {
365
- metadata = await this.sock.groupMetadata(chat.id);
366
- }
367
- catch (_a) { }
368
- }
369
- else if (!metadata.participants) {
370
- try {
371
- metadata = {
372
- ...metadata,
373
- ...(await this.sock.groupMetadata(chat.id)),
374
- };
375
- }
376
- catch (_b) { }
377
- if (metadata.participant) {
378
- metadata.participants = [
379
- ...(metadata.participants || []),
380
- ...metadata.participant.map((p) => {
381
- return {
382
- id: p.userJid,
383
- isSuperAdmin: p.rank == baileys_1.proto.GroupParticipant.Rank.SUPERADMIN,
384
- isAdmin: p.rank == baileys_1.proto.GroupParticipant.Rank.ADMIN,
385
- };
386
- }),
387
- ];
388
- }
389
- }
390
- }
391
- if (metadata === null || metadata === void 0 ? void 0 : metadata.participants) {
392
- chat.users = [];
393
- chat.admins = [];
394
- for (const p of metadata.participants) {
395
- chat.users.push(p.id);
396
- if (p.admin == 'admin' || p.isAdmin) {
397
- chat.admins.push(`${p.id}`);
398
- }
399
- else if (p.isSuperAdmin) {
400
- chat.leader = p.id;
401
- chat.admins.push(`${p.id}`);
402
- }
403
- }
404
- }
405
- if (metadata === null || metadata === void 0 ? void 0 : metadata.subjectOwner) {
406
- chat.leader = metadata.subjectOwner;
407
- }
408
- }
409
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.subject) || (metadata === null || metadata === void 0 ? void 0 : metadata.name)) {
410
- chat.name = metadata.subject || metadata.name || undefined;
411
- }
412
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.desc) || (metadata === null || metadata === void 0 ? void 0 : metadata.description)) {
413
- chat.description = metadata.desc || metadata.description || undefined;
414
- }
415
- if (metadata === null || metadata === void 0 ? void 0 : metadata.unreadCount) {
416
- chat.unreadCount = metadata.unreadCount || undefined;
417
- }
418
- if (metadata === null || metadata === void 0 ? void 0 : metadata.conversationTimestamp) {
419
- if (long_1.default.isLong(metadata.conversationTimestamp)) {
420
- chat.timestamp = metadata.conversationTimestamp.toNumber() * 1000;
421
- }
422
- else {
423
- chat.timestamp = Number(metadata.conversationTimestamp) * 1000;
424
- }
425
- }
426
- await this.updateChat({ id: chat.id, ...chat });
427
- }
428
- catch (_c) { }
447
+ return this.chatOperations.readChat(chat, metadata, updateMetadata);
429
448
  }
430
449
  /**
431
450
  * * Lê o usuário
432
451
  * @param user Usuário
433
452
  */
434
453
  async readUser(user, metadata) {
435
- try {
436
- if (!user.id || !user.id.includes('@s'))
437
- return;
438
- if (metadata === null || metadata === void 0 ? void 0 : metadata.imgUrl) {
439
- user.profileUrl = await this.getUserProfileUrl(new User_1.default(user.id));
440
- }
441
- else {
442
- const userData = await this.getUser(new User_1.default(user.id || ''));
443
- if (userData == null || !userData.profileUrl) {
444
- user.profileUrl = await this.getUserProfileUrl(new User_1.default(user.id));
445
- }
446
- }
447
- if ((metadata === null || metadata === void 0 ? void 0 : metadata.notify) || (metadata === null || metadata === void 0 ? void 0 : metadata.verifiedName)) {
448
- user.name = (metadata === null || metadata === void 0 ? void 0 : metadata.notify) || (metadata === null || metadata === void 0 ? void 0 : metadata.verifiedName);
449
- }
450
- if (metadata === null || metadata === void 0 ? void 0 : metadata.name) {
451
- user.savedName = metadata.name;
452
- }
453
- user.name = user.name || user.savedName;
454
- await this.updateUser({ id: user.id || '', ...user });
455
- }
456
- catch (err) {
457
- this.emit('error', err);
458
- }
454
+ return this.userOperations.readUser(user, metadata);
459
455
  }
460
456
  /**
461
457
  * Obtem uma mensagem de enquete.
@@ -463,20 +459,14 @@ class WhatsAppBot extends BotEvents_1.default {
463
459
  * @returns A mensagem de enquete salva.
464
460
  */
465
461
  async getPollMessage(pollMessageId) {
466
- const pollMessage = await this.auth.get(`polls-${pollMessageId}`);
467
- if (!pollMessage || !messages_1.PollMessage.isValid(pollMessage))
468
- return messages_1.PollMessage.fromJSON({ id: pollMessageId });
469
- if (pollMessage.type == Message_1.MessageType.PollUpdate) {
470
- return messages_1.PollUpdateMessage.fromJSON(pollMessage);
471
- }
472
- return messages_1.PollMessage.fromJSON(pollMessage);
462
+ return this.messageOperations.getPollMessage(pollMessageId);
473
463
  }
474
464
  /**
475
465
  * Salva a mensagem de enquete.
476
466
  * @param pollMessage - Mensagem de enquete que será salva.
477
467
  */
478
468
  async savePollMessage(pollMessage) {
479
- await this.auth.set(`polls-${pollMessage.id}`, pollMessage.toJSON());
469
+ return this.messageOperations.savePollMessage(pollMessage);
480
470
  }
481
471
  /**
482
472
  * * Trata atualizações de participantes
@@ -486,341 +476,154 @@ class WhatsAppBot extends BotEvents_1.default {
486
476
  * @param fromId Usuário que realizou a ação
487
477
  */
488
478
  async groupParticipantsUpdate(action, chatId, userId, fromId) {
489
- if (!chatId.includes('@g'))
490
- return;
491
- const event = action == 'join' ? 'add' : action == 'leave' ? 'remove' : action;
492
- let chat = await this.getChat(new Chat_1.default(chatId));
493
- if (!chat) {
494
- if (!this.config.autoLoadGroupInfo)
495
- return;
496
- chat = Chat_1.default.fromJSON({
497
- id: chatId,
498
- phoneNumber: (0, ID_1.getPhoneNumber)(chatId),
499
- type: ChatType_1.default.Group,
500
- });
501
- }
502
- const fromUser = (await this.getUser(new User_1.default(fromId))) ||
503
- User_1.default.fromJSON({ id: fromId, phoneNumber: (0, ID_1.getPhoneNumber)(fromId) });
504
- const user = (await this.getUser(new User_1.default(userId))) ||
505
- User_1.default.fromJSON({ id: userId, phoneNumber: (0, ID_1.getPhoneNumber)(userId) });
506
- let users = chat.users || [];
507
- const admins = chat.admins || [];
508
- if (event == 'add')
509
- users.push(user.id);
510
- if (event == 'remove')
511
- users = users.filter((u) => u != user.id);
512
- if (event == 'demote')
513
- chat.admins = admins.filter((admin) => admin != user.id);
514
- if (event == 'promote')
515
- admins.push(user.id);
516
- chat.users = users;
517
- chat.admins = admins;
518
- if (user.id == this.id) {
519
- if (event == 'remove')
520
- await this.removeChat(chat);
521
- if (event == 'add')
522
- await this.updateChat(chat);
523
- }
524
- else {
525
- await this.updateChat(chat);
526
- }
527
- this.ev.emit('user', { action, event, user, fromUser, chat });
479
+ return this.groupOperations.groupParticipantsUpdate(action, chatId, userId, fromId);
528
480
  }
529
481
  //! ********************************* CHAT *********************************
530
482
  async getChatName(chat) {
531
- var _a;
532
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.name) || '';
483
+ return this.chatOperations.getChatName(chat);
533
484
  }
534
485
  async setChatName(chat, name) {
535
- if (!(0, baileys_1.isJidGroup)(chat.id))
536
- return;
537
- const admins = await this.getChatAdmins(chat);
538
- if (admins.length && !admins.includes(this.id))
539
- return;
540
- await this.sock.groupUpdateSubject(chat.id, name);
486
+ return this.chatOperations.setChatName(chat, name);
541
487
  }
542
488
  async getChatDescription(chat) {
543
- var _a;
544
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.description) || '';
489
+ return this.chatOperations.getChatDescription(chat);
545
490
  }
546
491
  async setChatDescription(chat, description) {
547
- if (!(0, baileys_1.isJidGroup)(chat.id))
548
- return;
549
- const admins = await this.getChatAdmins(chat);
550
- if (admins.length && !admins.includes(this.id))
551
- return;
552
- await this.sock.groupUpdateDescription(chat.id, description);
492
+ return this.chatOperations.setChatDescription(chat, description);
553
493
  }
554
494
  async getChatProfile(chat, lowQuality) {
555
- const uri = await this.getChatProfileUrl(chat, lowQuality);
556
- return await (0, Generic_1.getImageURL)(uri);
495
+ return this.chatOperations.getChatProfile(chat, lowQuality);
557
496
  }
558
497
  async getChatProfileUrl(chat, lowQuality) {
559
- try {
560
- return ((await this.sock.profilePictureUrl(chat.id, lowQuality ? 'preview' : 'image')) || '');
561
- }
562
- catch (_a) {
563
- return '';
564
- }
498
+ return this.chatOperations.getChatProfileUrl(chat, lowQuality);
565
499
  }
566
500
  async setChatProfile(chat, image) {
567
- if (!(0, baileys_1.isJidGroup)(chat.id))
568
- return;
569
- const admins = await this.getChatAdmins(chat);
570
- if (admins.length && !admins.includes(this.id))
571
- return;
572
- await this.sock.updateProfilePicture(chat.id, image);
501
+ return this.chatOperations.setChatProfile(chat, image);
573
502
  }
574
503
  async updateChat(chat) {
575
- const chatData = await this.getChat(new Chat_1.default(chat.id));
576
- if (chatData != null) {
577
- chat = Object.keys(chat).reduce((data, key) => {
578
- if (chat[key] == undefined || chat[key] == null)
579
- return data;
580
- if ((0, Generic_1.verifyIsEquals)(chat[key], chatData[key]))
581
- return data;
582
- return { ...data, [key]: chat[key] };
583
- }, { id: chat.id });
584
- if (Object.keys(chat).length < 2)
585
- return;
586
- }
587
- const newChat = Chat_1.default.fromJSON({ ...(chatData || {}), ...chat });
588
- newChat.type = (0, baileys_1.isJidGroup)(chat.id) ? ChatType_1.default.Group : ChatType_1.default.PV;
589
- newChat.phoneNumber = newChat.phoneNumber || (0, ID_1.getPhoneNumber)(chat.id);
590
- await this.auth.set(`chats-${chat.id}`, newChat.toJSON());
591
- this.ev.emit('chat', { action: chatData != null ? 'update' : 'add', chat });
504
+ return this.chatOperations.updateChat(chat);
592
505
  }
593
506
  async removeChat(chat) {
594
- await this.auth.remove(`chats-${chat.id}`);
595
- this.ev.emit('chat', { action: 'remove', chat });
507
+ return this.chatOperations.removeChat(chat);
596
508
  }
597
509
  async getChat(chat) {
598
- const chatData = await this.auth.get(`chats-${chat.id}`);
599
- if (!chatData)
600
- return null;
601
- if (!chat.name || !chat.profileUrl) {
602
- const user = await this.getUser(new User_1.default(chat.id));
603
- if (user != null) {
604
- return Chat_1.default.fromJSON({ ...chat, ...user });
605
- }
606
- }
607
- return Chat_1.default.fromJSON(chatData);
510
+ return this.chatOperations.getChat(chat);
608
511
  }
609
512
  async getChats() {
610
- return (await this.auth.listAll('chats-')).map((id) => id.replace('chats-', ''));
513
+ return this.chatOperations.getChats();
611
514
  }
612
515
  async setChats(chats) {
613
- await Promise.all(chats.map(async (chat) => await this.updateChat(chat)));
516
+ return this.chatOperations.setChats(chats);
614
517
  }
615
518
  async getChatUsers(chat) {
616
- var _a;
617
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.users) || [];
519
+ return this.chatOperations.getChatUsers(chat);
618
520
  }
619
521
  async getChatAdmins(chat) {
620
- var _a, _b;
621
- const chatReaded = await this.getChat(chat);
622
- if (!chatReaded)
623
- return [];
624
- if ((_a = chatReaded.admins) === null || _a === void 0 ? void 0 : _a.length) {
625
- return chatReaded.admins || [];
626
- }
627
- if (chatReaded.type !== ChatType_1.default.Group)
628
- return [];
629
- await this.readChat(chat);
630
- return ((_b = (await this.getChat(chat))) === null || _b === void 0 ? void 0 : _b.admins) || [];
522
+ return this.chatOperations.getChatAdmins(chat);
631
523
  }
632
524
  async getChatLeader(chat) {
633
- var _a;
634
- return ((_a = (await this.getChat(chat))) === null || _a === void 0 ? void 0 : _a.leader) || '';
525
+ return this.chatOperations.getChatLeader(chat);
635
526
  }
636
527
  async addUserInChat(chat, user) {
637
- if (!(0, baileys_1.isJidGroup)(chat.id))
638
- return;
639
- const admins = await this.getChatAdmins(chat);
640
- if (admins.length && !admins.includes(this.id))
641
- return;
642
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'add');
528
+ return this.groupOperations.addUserInChat(chat, user);
643
529
  }
644
530
  async removeUserInChat(chat, user) {
645
- if (!(0, baileys_1.isJidGroup)(chat.id))
646
- return;
647
- const admins = await this.getChatAdmins(chat);
648
- if (admins.length && !admins.includes(this.id))
649
- return;
650
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'remove');
531
+ return this.groupOperations.removeUserInChat(chat, user);
651
532
  }
652
533
  async promoteUserInChat(chat, user) {
653
- if (!(0, baileys_1.isJidGroup)(chat.id))
654
- return;
655
- const admins = await this.getChatAdmins(chat);
656
- if (admins.length && !admins.includes(this.id))
657
- return;
658
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'promote');
534
+ return this.groupOperations.promoteUserInChat(chat, user);
659
535
  }
660
536
  async demoteUserInChat(chat, user) {
661
- if (!(0, baileys_1.isJidGroup)(chat.id))
662
- return;
663
- const admins = await this.getChatAdmins(chat);
664
- if (admins.length && !admins.includes(this.id))
665
- return;
666
- await this.sock.groupParticipantsUpdate(chat.id, [user.id], 'demote');
537
+ return this.groupOperations.demoteUserInChat(chat, user);
667
538
  }
668
539
  async changeChatStatus(chat, status) {
669
- await this.sock.sendPresenceUpdate(WAStatus_1.WAStatus[status] || 'available', chat.id);
540
+ return this.chatOperations.changeChatStatus(chat, status);
670
541
  }
671
542
  async createChat(chat) {
672
- await this.sock.groupCreate(chat.name || '', [this.id]);
543
+ return this.chatOperations.createChat(chat);
673
544
  }
674
545
  async leaveChat(chat) {
675
- if (!(0, baileys_1.isJidGroup)(chat.id))
676
- return;
677
- if ((await this.getChat(chat)) == null)
678
- return;
679
- await this.sock.groupLeave(chat.id);
680
- await this.removeChat(chat);
546
+ return this.chatOperations.leaveChat(chat);
681
547
  }
682
548
  async joinChat(code) {
683
- await this.sock.groupAcceptInvite(code.replace('https://chat.whatsapp.com/', ''));
549
+ return this.chatOperations.joinChat(code);
684
550
  }
685
551
  async getChatInvite(chat) {
686
- if (!(0, baileys_1.isJidGroup)(chat.id))
687
- return '';
688
- // TODO: Return undefined if user is not admin
689
- const admins = await this.getChatAdmins(chat);
690
- if (admins.length && !admins.includes(this.id))
691
- return '';
692
- return (await this.sock.groupInviteCode(chat.id)) || '';
552
+ return this.chatOperations.getChatInvite(chat);
693
553
  }
694
554
  async revokeChatInvite(chat) {
695
- if (!(0, baileys_1.isJidGroup)(chat.id))
696
- return '';
697
- const admins = await this.getChatAdmins(chat);
698
- if (admins.length && !admins.includes(this.id))
699
- return '';
700
- return (await this.sock.groupRevokeInvite(chat.id)) || '';
555
+ return this.chatOperations.revokeChatInvite(chat);
701
556
  }
702
557
  async rejectCall(call) {
703
558
  await this.sock.rejectCall(call.id, call.chat.id);
704
559
  }
705
560
  async getUserName(user) {
706
- var _a;
707
- return ((_a = (await this.getUser(user))) === null || _a === void 0 ? void 0 : _a.name) || '';
561
+ return this.userOperations.getUserName(user);
708
562
  }
709
563
  async setUserName(user, name) {
710
- if (user.id != this.id)
711
- return;
712
- await this.setBotName(name);
564
+ return this.userOperations.setUserName(user, name);
713
565
  }
714
566
  async getUserDescription(user) {
715
- // O método fetchStatus não existe na API pública do Baileys
716
- // return (await this.sock.fetchStatus(String(user.id)))[0]?.status || '';
717
- throw new Error('getUserDescription não implementado: fetchStatus não disponível na API do Baileys');
567
+ return this.userOperations.getUserDescription(user);
718
568
  }
719
569
  async setUserDescription(user, description) {
720
- if (user.id != this.id)
721
- return;
722
- await this.setBotDescription(description);
570
+ return this.userOperations.setUserDescription(user, description);
723
571
  }
724
572
  async getUserProfile(user, lowQuality) {
725
- const uri = await this.getUserProfileUrl(user, lowQuality);
726
- return await (0, Generic_1.getImageURL)(uri);
573
+ return this.userOperations.getUserProfile(user, lowQuality);
727
574
  }
728
575
  async getUserProfileUrl(user, lowQuality) {
729
- try {
730
- return ((await this.sock.profilePictureUrl(user.id, lowQuality ? 'preview' : 'image')) || '');
731
- }
732
- catch (_a) {
733
- return '';
734
- }
576
+ return this.userOperations.getUserProfileUrl(user, lowQuality);
735
577
  }
736
578
  async setUserProfile(user, image) {
737
- if (user.id != this.id)
738
- return;
739
- await this.setBotProfile(image);
579
+ return this.userOperations.setUserProfile(user, image);
740
580
  }
741
581
  async getUser(user) {
742
- const userData = await this.auth.get(`users-${user.id}`);
743
- if (!userData)
744
- return null;
745
- return User_1.default.fromJSON(userData);
582
+ return this.userOperations.getUser(user);
746
583
  }
747
584
  async getUsers() {
748
- return (await this.auth.listAll('users-')).map((id) => id.replace('users-', ''));
585
+ return this.userOperations.getUsers();
749
586
  }
750
587
  async updateUser(user) {
751
- const userData = await this.getUser(new User_1.default(user.id));
752
- if (userData != null) {
753
- user = Object.keys(user).reduce((data, key) => {
754
- if (user[key] == undefined || user[key] == null)
755
- return data;
756
- if ((0, Generic_1.verifyIsEquals)(user[key], userData[key]))
757
- return data;
758
- return { ...data, [key]: user[key] };
759
- }, { id: user.id });
760
- if (Object.keys(user).length < 2)
761
- return;
762
- }
763
- const newUser = User_1.default.fromJSON({ ...(userData || {}), ...user });
764
- newUser.phoneNumber = newUser.phoneNumber || (0, ID_1.getPhoneNumber)(user.id);
765
- await this.auth.set(`users-${user.id}`, newUser.toJSON());
588
+ return this.userOperations.updateUser(user);
766
589
  }
767
590
  async setUsers(users) {
768
- await Promise.all(users.map(async (user) => await this.updateUser(user)));
591
+ return this.userOperations.setUsers(users);
769
592
  }
770
593
  async removeUser(user) {
771
- await this.auth.remove(`users-${user.id}`);
594
+ return this.userOperations.removeUser(user);
772
595
  }
773
596
  async blockUser(user) {
774
- if (user.id == this.id)
775
- return;
776
- await this.sock.updateBlockStatus(user.id, 'block');
597
+ return this.userOperations.blockUser(user);
777
598
  }
778
599
  async unblockUser(user) {
779
- if (user.id == this.id)
780
- return;
781
- await this.sock.updateBlockStatus(user.id, 'unblock');
600
+ return this.userOperations.unblockUser(user);
782
601
  }
783
602
  //! ******************************** BOT ********************************
784
603
  async getBotName() {
785
- return await this.getUserName(new User_1.default(this.id));
604
+ return this.userOperations.getBotName();
786
605
  }
787
606
  async setBotName(name) {
788
- await this.sock.updateProfileName(name);
607
+ return this.userOperations.setBotName(name);
789
608
  }
790
609
  async getBotDescription() {
791
- return await this.getUserDescription(new User_1.default(this.id));
610
+ return this.userOperations.getBotDescription();
792
611
  }
793
612
  async setBotDescription(description) {
794
- await this.sock.updateProfileStatus(description);
613
+ return this.userOperations.setBotDescription(description);
795
614
  }
796
615
  async getBotProfile(lowQuality) {
797
- return await this.getUserProfile(new User_1.default(this.id), lowQuality);
616
+ return this.userOperations.getBotProfile(lowQuality);
798
617
  }
799
618
  async getBotProfileUrl(lowQuality) {
800
- return (await this.getUserProfileUrl(new User_1.default(this.id), lowQuality)) || '';
619
+ return this.userOperations.getBotProfileUrl(lowQuality);
801
620
  }
802
621
  async setBotProfile(image) {
803
- await this.sock.updateProfilePicture(this.id, image);
622
+ return this.userOperations.setBotProfile(image);
804
623
  }
805
624
  //! ******************************* MESSAGE *******************************
806
625
  async readMessage(message) {
807
- const key = {
808
- remoteJid: message.chat.id,
809
- id: message.id || '',
810
- fromMe: message.fromMe || message.user.id == this.id,
811
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
812
- ? message.user.id || this.id || undefined
813
- : undefined,
814
- toJSON: () => key,
815
- };
816
- // v7.0.0: Removido ACKs automáticos para evitar banimentos
817
- // O WhatsApp agora gerencia automaticamente o status de leitura
818
- const chat = await this.getChat(message.chat);
819
- // Apenas marcar como lido localmente, sem enviar ACK
820
- 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) {
821
- // Marcar mensagem como lida apenas no cache local
822
- this.addMessageCache(message.id || '');
823
- }
626
+ return this.messageOperations.readMessage(message);
824
627
  }
825
628
  // Adiciona um método utilitário para cache de mensagens
826
629
  addMessageCache(id) {
@@ -831,23 +634,19 @@ class WhatsAppBot extends BotEvents_1.default {
831
634
  // ================= APP STATE UPDATES =================
832
635
  /** Arquiva ou desarquiva um chat */
833
636
  async archiveChat(chat, archive = true, lastMessages) {
834
- const chatId = typeof chat === 'string' ? chat : chat.id;
835
- await this.sock.chatModify({ archive, lastMessages }, chatId);
637
+ return this.chatOperations.archiveChat(chat, archive, lastMessages);
836
638
  }
837
639
  /** Silencia ou dessilencia um chat */
838
640
  async muteChat(chat, mute, lastMessages) {
839
- const chatId = typeof chat === 'string' ? chat : chat.id;
840
- await this.sock.chatModify({ mute, lastMessages }, chatId);
641
+ return this.chatOperations.muteChat(chat, mute, lastMessages);
841
642
  }
842
643
  /** Marca um chat como lido */
843
644
  async markChatRead(chat, read = true, lastMessages) {
844
- const chatId = typeof chat === 'string' ? chat : chat.id;
845
- await this.sock.chatModify({ markRead: read, lastMessages }, chatId);
645
+ return this.chatOperations.markChatRead(chat, read, lastMessages);
846
646
  }
847
647
  /** Define o modo de mensagens temporárias em um chat */
848
648
  async setDisappearingMessages(chat, duration) {
849
- const chatId = typeof chat === 'string' ? chat : chat.id;
850
- await this.sock.sendMessage(chatId, { disappearingMessagesInChat: duration });
649
+ return this.chatOperations.setDisappearingMessages(chat, duration);
851
650
  }
852
651
  // ================= BUSINESS FEATURES =================
853
652
  /** Busca o perfil de negócio de um contato */
@@ -885,121 +684,39 @@ class WhatsAppBot extends BotEvents_1.default {
885
684
  * Adiciona uma reação a uma mensagem
886
685
  */
887
686
  async addReaction(message) {
888
- var _a;
889
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id) || !message.reaction)
890
- return;
891
- await this.sock.sendMessage(message.chat.id, {
892
- react: {
893
- text: message.reaction,
894
- key: {
895
- id: message.id,
896
- remoteJid: message.chat.id,
897
- fromMe: message.fromMe || message.user.id === this.id,
898
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
899
- ? message.user.id || this.id || undefined
900
- : undefined,
901
- },
902
- },
903
- });
687
+ return this.messageOperations.addReaction(message);
904
688
  }
905
689
  /** Remove uma reação de uma mensagem */
906
690
  async removeReaction(message) {
907
- var _a;
908
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
909
- return;
910
- await this.sock.sendMessage(message.chat.id, {
911
- react: {
912
- text: '',
913
- key: {
914
- id: message.id,
915
- remoteJid: message.chat.id,
916
- fromMe: message.fromMe || message.user.id === this.id,
917
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
918
- ? message.user.id || this.id || undefined
919
- : undefined,
920
- },
921
- },
922
- });
691
+ return this.messageOperations.removeReaction(message);
923
692
  }
924
693
  /** Edita o texto de uma mensagem enviada */
925
694
  async editMessage(message) {
926
- var _a;
927
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
928
- return;
929
- await this.sock.sendMessage(message.chat.id, {
930
- edit: {
931
- remoteJid: message.chat.id,
932
- id: message.id,
933
- fromMe: message.fromMe || message.user.id === this.id,
934
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
935
- ? message.user.id || this.id || undefined
936
- : undefined,
937
- },
938
- text: message.text,
939
- });
695
+ return this.messageOperations.editMessage(message);
940
696
  }
941
697
  /** Envia uma mensagem */
942
698
  async send(message) {
943
- var _a;
944
- try {
945
- const waMsg = (await new ConvertToWAMessage_1.default(this, message).refactory()).waMessage;
946
- const sent = await this.sock.sendMessage(message.chat.id, waMsg);
947
- if (sent && sent.key && sent.key.id)
948
- message.id = sent.key.id;
949
- return message;
950
- }
951
- catch (error) {
952
- // Log detalhado para diagnóstico
953
- console.error('[WhatsAppBot.send] Erro ao enviar mensagem', {
954
- chatId: (_a = message === null || message === void 0 ? void 0 : message.chat) === null || _a === void 0 ? void 0 : _a.id,
955
- messageObj: message,
956
- error
957
- });
958
- throw error;
959
- }
699
+ return this.messageOperations.send(message);
960
700
  }
961
701
  /** Remove uma mensagem (marca como removida para todos) */
962
702
  async removeMessage(message) {
963
- var _a;
964
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
965
- return;
966
- await this.sock.sendMessage(message.chat.id, {
967
- delete: {
968
- remoteJid: message.chat.id,
969
- id: message.id,
970
- fromMe: message.fromMe || message.user.id === this.id,
971
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
972
- ? message.user.id || this.id || undefined
973
- : undefined,
974
- },
975
- });
703
+ return this.messageOperations.removeMessage(message);
976
704
  }
977
705
  /** Deleta uma mensagem (remove do histórico) */
978
706
  async deleteMessage(message) {
979
- var _a;
980
- if (!message.id || !((_a = message.chat) === null || _a === void 0 ? void 0 : _a.id))
981
- return;
982
- await this.sock.sendMessage(message.chat.id, {
983
- delete: {
984
- remoteJid: message.chat.id,
985
- id: message.id,
986
- fromMe: message.fromMe || message.user.id === this.id,
987
- participant: (0, baileys_1.isJidGroup)(message.chat.id)
988
- ? message.user.id || this.id || undefined
989
- : undefined,
990
- },
991
- });
707
+ return this.messageOperations.deleteMessage(message);
992
708
  }
993
709
  /** Baixa a stream de mídia de uma mensagem */
994
710
  async downloadStreamMessage(media) {
995
- // media é um MediaMessage, que herda de Message
996
- const msg = await this.store.loadMessage(media.chat.id, media.id);
997
- if (!msg)
998
- return Buffer.from("");
999
- // downloadMediaMessage espera (msg, type, options?)
1000
- return Buffer.from(await (0, baileys_1.downloadMediaMessage)(msg, "buffer", {
1001
- // opções extras se necessário
1002
- }));
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);
1003
720
  }
1004
721
  }
1005
722
  exports.default = WhatsAppBot;