Resolve o erro 'ON CONFLICT DO UPDATE command cannot affect row a second time' que ocorria ao importar histórico de contatos duplicados.
A correção remove a tentativa de atualizar o campo 'identifier' no ON CONFLICT, já que este campo faz parte da constraint de conflito e não pode ser atualizado.
Erro original:
- identifier = EXCLUDED.identifier
Correção:
- updated_at = NOW()
Isso permite que contatos duplicados sejam atualizados corretamente sem causar erro.
- Added update and delete endpoints for WhatsApp Business Meta templates.
- Fixed issues with incoming message events and authentication states after reconnection.
- Resolved unique constraint errors in OnWhatsapp cache and optimized database writes.
- Improved proxy integration for media uploads and fixed handling of base64, filename, and caption in the WhatsApp Business API.
- Enhanced chat service reliability and contact filtering capabilities.
- Made multiple integration improvements between Chatwoot and Baileys.
- Refactored code for better quality and consistency.
Updated the error handling in the saveOnWhatsappCache function to log the error message separately, improving clarity on issues encountered during item processing.
Dessa forma, quando uma nova conexão era estabelecida reutilizando o mesmo instanceName, o Baileys carregava chaves antigas e inválidas, incompatíveis com o novo conjunto de credenciais (creds) gerado na reconexão.
Essa inconsistência gerava o seguinte sintoma prático:
A instância autenticava com sucesso;
Contudo, ao tentar enviar mensagens, entrava em estado de bloqueio, exibindo o status “aguardando mensagem” indefinidamente.
- Add cleanup logic in mount() to prevent memory leaks from multiple subscriptions
- Recreate messageSubject if it was completed during logout
- Remount messageProcessor in connectToWhatsapp() to ensure subscription is active after reconnection
This fixes the issue where incoming message events stop working after logout and reconnect, while outgoing message events continue to work normally.
The root cause was that onDestroy() calls complete() on the RxJS Subject, making it permanently closed. When reconnecting, the Subject would silently ignore all new messages.
The fix ensures that:
1. Old subscriptions are properly cleaned up before creating new ones
2. If the Subject is closed, a new one is created automatically
3. The messageProcessor is remounted on every connection to ensure active subscription
Refactors the cache-saving logic to prevent `Unique constraint failed` errors. This issue occurs when an item's `remoteJid` is not yet included in the `jidOptions` of the existing record.
The database query now uses an `OR` condition to find a matching record by either `jidOptions` (using `contains`) or by the `remoteJid` itself in a single query.
Additionally, this commit introduces several performance optimizations:
1. **Skip Unnecessary Updates**: The function now performs a deep comparison between the new payload and the `existingRecord`. An `update` operation is only executed if the data has actually changed, reducing unnecessary database writes.
2. **Parallel Processing**: The sequential `for...of` loop has been replaced with `Promise.allSettled`. This allows all items in the `data` array to be processed concurrently, significantly speeding up execution for batch inputs.
3. **Data Consistency**: The JIDs in `jidOptions` are now sorted alphabetically before being joined into a string. This ensures that the change-detection logic is accurate, regardless of the order in which JIDs were discovered.
4. **Refactor**: Simplified JID unification logic using a `Set` and introduced a `normalizeJid` helper function for cleaner code.
TODO: Investigate the root cause of why `remoteJid` is sometimes not present in `jidOptions` upon initial discovery.
Ele espera objetos compatíveis com a interface moderna Dispatcher, que possuem o método dispatch().
Ou seja, o Baileys estava recebendo um tipo de agente incompatível com o novo sistema de rede do Node.
Foi criada uma nova função makeProxyAgentUndici() para gerar agentes de proxy compatíveis com o Undici, mantendo a versão antiga (makeProxyAgent()) inalterada para compatibilidade com bibliotecas como Axios.
A nova função substitui os antigos HttpsProxyAgent e SocksProxyAgent por ProxyAgent da biblioteca undici, garantindo compatibilidade total com o Baileys e com qualquer uso de fetch() moderno.
Anteriormente, o endpoint findContacts processava apenas o campo remoteJid da cláusula where, ignorando outros campos como id e pushName.
Alterações:
- Atualiza método fetchContacts para processar todos os campos do where (id, remoteJid, pushName)
- Adiciona campo remoteJid ao contactValidateSchema para validação adequada
- Garante isolamento multi-tenant mantendo filtro por instanceId
Esta correção permite que usuários filtrem contatos por qualquer um dos campos suportados ao invés de sempre retornar todos os contatos da instância.