Compare commits

..

1320 Commits
1.8.1 ... 2.3.6

Author SHA1 Message Date
Davidson Gomes
3454bec79f Merge branch 'release/2.3.6'
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
2025-10-21 11:40:39 -03:00
Davidson Gomes
8c27f11f5b chore(changelog): update to version 2.3.6
Some checks failed
Security Scan / Dependency Review (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
2025-10-21 11:40:27 -03:00
Davidson Gomes
ae9f3efeff Merge pull request #2108 from KokeroO/develop
chore: bump version to 2.3.6 and update baileys dependency to 7.0.0-rc.6
2025-10-21 09:00:58 -03:00
Willian Coqueiro
ba3a2fae59 chore: atualizar versão da API para 2.3.6 nos templates e configurações do Docker 2025-10-20 03:06:37 +00:00
Willian Coqueiro
aa0d793d26 chore: bump version to 2.3.6 and update baileys dependency to 7.0.0-rc.6 2025-10-20 02:24:56 +00:00
Davidson Gomes
48bda1b5af Merge pull request #2107 from KokeroO/develop
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
fix( baileys.service ): Corrige ao salvar no DB valores Uint8Array
2025-10-19 17:59:26 -03:00
Willian Coqueiro
dd21a29ea6 fix(baileys): salvar corretamente buffer no db 2025-10-19 18:53:16 +00:00
Davidson Gomes
e83a7e2e88 Merge pull request #2105 from KokeroO/develop
fix: Simplify logging of messageSent object
2025-10-19 06:41:28 -03:00
Willian Coqueiro
d58d0b8bff Merge branch 'EvolutionAPI:develop' into develop 2025-10-19 06:34:58 -03:00
Willian Coqueiro
4efc9b65bc Simplify logging of messageSent object
Evita o erro de this.isZero not is function
2025-10-19 06:34:45 -03:00
Davidson Gomes
cd71ff503d Merge pull request #2103 from KokeroO/develop
feat(baileys,chatwoot,on-whatsapp-cache): implementações e correções na baileys e chatwoot
2025-10-19 06:23:39 -03:00
Willian Coqueiro
582166e5ae fix(lint): lint 2025-10-19 05:41:55 +00:00
Willian Coqueiro
e1ae03c1e4 fix(comments): comments fix 2025-10-19 05:37:22 +00:00
Willian Coqueiro
0737c45df2 Update src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-10-19 02:29:04 -03:00
Willian Coqueiro
adbe1079d5 Update src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-10-19 02:28:45 -03:00
Willian Coqueiro
423f629b04 Update src/utils/onWhatsappCache.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-10-19 02:26:52 -03:00
Willian Coqueiro
946dcaeb2e feat(baileys,chatwoot,on-whatsapp-cache): implementações e correções na baileys e chatwoot
* corrige cache de números PN, LIDs e g.us para enviar o número correto
* atualiza para os últimos commits da baileys
* corrige envio de áudio e documentos via chatwoot no canal baileys
* diversas correções na integração com chatwoot
* corrige mensagens ignoradas no recebimento de leads
2025-10-19 03:05:11 +00:00
Davidson Gomes
d48fbc3a4e Merge branch 'release/2.3.5'
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
2025-10-15 09:58:37 -03:00
Davidson Gomes
cdf06666a1 chore(workflows): update checkout step to include submodules
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
- Added 'submodules: recursive' option to the checkout step in multiple workflow files to ensure submodules are properly initialized during CI/CD processes.
2025-10-15 09:58:27 -03:00
Davidson Gomes
5254928887 Merge branch 'release/2.3.5' 2025-10-15 09:48:00 -03:00
Davidson Gomes
8468690d37 chore(manager): update asset files and install process
- Updated subproject reference in evolution-manager-v2 to the latest commit.
- Enhanced the manager_install.sh script to include npm install and build steps for the evolution-manager-v2.
- Replaced old JavaScript asset file with a new version for improved performance.
- Added a new CSS file for consistent styling across the application.
2025-10-15 09:47:32 -03:00
Willian Coqueiro
bdd9257c47 Merge branch 'develop' of https://github.com/KokeroO/evolution-api into develop 2025-10-15 09:47:32 -03:00
Willian Coqueiro
d6834c8741 fix(chatwoot): correct chatId extraction for non-group JIDs 2025-10-15 09:47:31 -03:00
Davidson Gomes
164beddb39 chore(manager): update asset files and install process
- Updated subproject reference in evolution-manager-v2 to the latest commit.
- Enhanced the manager_install.sh script to include npm install and build steps for the evolution-manager-v2.
- Replaced old JavaScript asset file with a new version for improved performance.
- Added a new CSS file for consistent styling across the application.
2025-10-15 09:44:15 -03:00
Davidson Gomes
4991f1dc37 feat(telemetry): add message type telemetry logging in channel services
- Integrated telemetry logging for received messages in Evolution, WhatsApp Business, and Baileys services.
- Enhanced message tracking by sending the message type to the telemetry system for better observability.
2025-10-15 09:42:45 -03:00
Davidson Gomes
1b1e3b3e9d chore(changelog): update CHANGELOG for version 2.3.5 release date
- Updated the release date for version 2.3.5 to 2025-10-15.
- Adjusted subproject reference in evolution-manager-v2 to the latest commit.
2025-10-15 09:42:44 -03:00
Davidson Gomes
563ca2dd22 chore(changelog): update CHANGELOG for version 2.3.5
- Added features for Chatwoot enhancements, participants data handling, and LID to phone number conversion.
- Updated Docker configurations to include Kafka and frontend services.
- Fixed PostgreSQL migration errors and improved message handling in Baileys and Chatwoot services.
- Refactored TypeScript build process and implemented exponential backoff patterns.
2025-10-15 09:42:44 -03:00
Davidson Gomes
4e44bfb222 chore(manager): update asset files and dependencies
- Updated subproject reference in evolution-manager-v2.
- Replaced old JavaScript and CSS asset files with new versions for improved performance and styling.
- Added new CSS file for consistent font styling across the application.
- Updated the evolution logo image to the latest version.
2025-10-15 09:42:44 -03:00
Davidson Gomes
9edd600513 Merge pull request #2083 from davidmnzs/main
fix: correct the error of hardcoded prisma/kafka schema
2025-10-15 09:40:15 -03:00
Davidson Gomes
501b06d133 Merge branch 'release/2.3.5' 2025-10-15 09:38:34 -03:00
Davidson Gomes
dc530285d5 feat(telemetry): add message type telemetry logging in channel services
- Integrated telemetry logging for received messages in Evolution, WhatsApp Business, and Baileys services.
- Enhanced message tracking by sending the message type to the telemetry system for better observability.
2025-10-15 09:38:06 -03:00
Davidson Gomes
8775cdf036 chore(changelog): update CHANGELOG for version 2.3.5 release date
- Updated the release date for version 2.3.5 to 2025-10-15.
- Adjusted subproject reference in evolution-manager-v2 to the latest commit.
2025-10-15 09:32:09 -03:00
Davidson Gomes
6ad33df879 chore(changelog): update CHANGELOG for version 2.3.5
- Added features for Chatwoot enhancements, participants data handling, and LID to phone number conversion.
- Updated Docker configurations to include Kafka and frontend services.
- Fixed PostgreSQL migration errors and improved message handling in Baileys and Chatwoot services.
- Refactored TypeScript build process and implemented exponential backoff patterns.
2025-10-15 09:31:45 -03:00
Davidson Gomes
633d0b4c45 Merge pull request #2085 from KokeroO/develop
Convert LIDs to PN by sending a call rejection message
2025-10-15 09:25:37 -03:00
Davidson Gomes
82c0eadf7c chore(manager): update asset files and dependencies
- Updated subproject reference in evolution-manager-v2.
- Replaced old JavaScript and CSS asset files with new versions for improved performance and styling.
- Added new CSS file for consistent font styling across the application.
- Updated the evolution logo image to the latest version.
2025-10-15 09:25:21 -03:00
Willian Coqueiro
1756abf1e6 Merge branch 'develop' of https://github.com/KokeroO/evolution-api into develop 2025-10-14 05:33:54 +00:00
Willian Coqueiro
a2f48030dc Merge branch 'develop' of https://github.com/KokeroO/evolution-api into develop 2025-10-14 05:33:33 +00:00
Willian Coqueiro
3214a9fb5b fix(chatwoot): correct chatId extraction for non-group JIDs 2025-10-14 05:25:36 +00:00
Willian Coqueiro
4b89e3f987 fix(chatwoot): correct chatId extraction for non-group JIDs 2025-10-14 02:16:22 +00:00
Willian Coqueiro
72622dca31 Merge upstream/develop into develop 2025-10-14 02:12:15 +00:00
davidmnzs
d73b72b67e fix: correct the error of hardcoded prisma/kafka schema 2025-10-13 20:28:17 -03:00
Davidson Gomes
20eef33df3 Merge pull request #2076 from KokeroO/fix/chatwoot
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
Implementations and corrections of previous commits in the chatwoot and baileys services
2025-10-13 12:19:58 -03:00
Davidson Gomes
37571c03b4 Merge pull request #2072 from nolramaf/fix/media-content-validation
fix/media content validation
2025-10-13 12:19:05 -03:00
Willian Coqueiro
017949458b refactor(baileys): simplify linkPreview handling in BaileysStartupService 2025-10-12 15:38:05 +00:00
Willian Coqueiro
2feaf1c74e fix(baileys): handle undefined status in update by defaulting to 'DELETED' 2025-10-12 15:29:48 +00:00
Willian Coqueiro
4b043cb4b8 refactor: update TypeScript build process and dependencies
- Changed the build command in package.json to use TypeScript compiler (tsc) with noEmit option.
- Added @swc/core and @swc/helpers as development dependencies for improved performance.

refactor: clean up WhatsApp Baileys service

- Removed unused properties and interfaces related to message keys.
- Simplified message handling logic by removing redundant checks and conditions.
- Updated message timestamp handling for consistency.
- Improved readability and maintainability by restructuring code and removing commented-out sections.

refactor: optimize Chatwoot service

- Streamlined database queries by reusing PostgreSQL client connection.
- Enhanced conversation creation logic with better cache handling.
- Removed unnecessary methods and improved existing ones for clarity.
- Updated message sending logic to handle file streams instead of buffers.

fix: improve translation loading mechanism

- Simplified translation file loading by removing environment variable checks.
- Ensured translations are loaded from a consistent path within the project structure.
2025-10-12 15:03:48 +00:00
Marlon Alves
b0d261b305 fix/media content validation 2025-10-11 04:13:12 -03:00
Willian Coqueiro
c041986e26 Merge upstream/develop into develop 2025-10-10 02:11:44 +00:00
Davidson Gomes
0976109d27 Merge pull request #2025 from guispiller/main
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
feat: convert LID to phoneNumber on GROUP_PARTICIPANTS_UPDATE webhook
2025-10-09 15:05:41 -03:00
Davidson Gomes
b808dda33b Merge pull request #2048 from dersonbsb2022/main
feat(chatwoot): comprehensive improvements to message handling, editing, deletion and i18n (translate messages)
2025-10-09 14:59:53 -03:00
Anderson Silva
98b7f15a43 fix(baileys): update to 7.0.0-rc.5 and fix assertSessions signature
Problem:
- GitHub Actions failing: Expected 1 arguments, but got 2
- Local had outdated Baileys 7.0.0-rc.3 in node_modules
- assertSessions signature changed between versions

Solution:
- Fresh npm install with Baileys 7.0.0-rc.5
- Updated assertSessions to pass only jids (no force param)
- Regenerated Prisma Client after reinstall
- Updated package-lock.json for version consistency

Changes:
- assertSessions now receives 1 argument (jids only)
- Kept force param in method signature for API compatibility
- Removed @ts-expect-error directives (no longer needed)

Tested:
-  Server starts successfully
-  Build passes without errors
-  Lint passes
2025-10-06 19:30:13 -03:00
Anderson Silva
94ddc0dfbe fix(baileys): use type assertion for assertSessions compatibility
Problem:
- GitHub Actions shows: Expected 1 arguments, but got 2
- Local environment shows: Expected 2 arguments, but got 1
- Different Baileys versions/definitions between environments

Solution:
- Use 'as any' type assertion for force parameter
- Maintains compatibility with both signature variations
- Allows code to work in all environments

Technical notes:
- Local: baileys@7.0.0-rc.5 expects 2 arguments (jids, force)
- GitHub Actions: May have different version/cache expecting 1 argument
- Type assertion bypasses strict type checking for cross-version compatibility
2025-10-06 19:12:32 -03:00
Anderson Silva
d4b0cfd2ba fix(chatwoot): resolve webhook timeout on deletion with 5+ images
Problem:
- Chatwoot shows red error when deleting messages with 5+ images
- Cause: Chatwoot webhook timeout of 5 seconds
- Processing 5 images takes ~9 seconds
- Duplicate webhooks arrive during processing

Solution:
- Implemented async processing with setImmediate()
- Webhook responds immediately (< 100ms)
- Deletion processes in background without blocking
- Maintains idempotency with cache (1 hour TTL)
- Maintains lock mechanism (60 seconds TTL)

Benefits:
- Scales infinitely (10, 20, 100+ images)
- No timeout regardless of quantity
- No error messages in Chatwoot
- Reliable background processing

Tested:
- 5 images: 9s background processing
- Webhook response: < 100ms
- No red error in Chatwoot
- Deletion completes successfully

BREAKING CHANGE: Fixed assertSessions signature to accept force parameter
2025-10-06 16:14:26 -03:00
dersonbsb2022
a5a46dc72a Merge branch 'develop' into main 2025-10-06 15:21:10 -03:00
Anderson Silva
e13434804c refactor: implement exponential backoff patterns and extract magic numbers to constants
- Extract HTTP timeout constant (60s for large file downloads)
- Extract S3/MinIO retry configuration (3 retries, 1s-8s exponential backoff)
- Extract database polling retry configuration (5 retries, 100ms-2s exponential backoff)
- Extract webhook and lock polling delays to named constants
- Extract cache TTL values (5min for messages, 30min for updates) in Baileys service
- Implement exponential backoff for S3/MinIO downloads following webhook controller pattern
- Implement exponential backoff for database polling removing fixed delays
- Add deletion event lock to prevent race conditions with duplicate webhooks
- Process deletion events immediately (no delay) to fix Chatwoot local storage red error
- Make i18n translations path configurable via TRANSLATIONS_BASE_DIR env variable
- Add detailed logging for deletion events debugging

Addresses code review suggestions from Sourcery AI and Copilot AI:
- Magic numbers extracted to well-documented constants
- Retry configurations consolidated and clearly separated by use case
- S3/MinIO retry uses longer delays (external storage)
- Database polling uses shorter delays (internal operations)
- Fixes Chatwoot local storage deletion error (red message issue)
- Maintains full compatibility with S3/MinIO storage (tested)

Breaking changes: None - all changes are internal improvements
2025-10-06 15:10:38 -03:00
Davidson Gomes
53cd7d5d13 chore(deps): update baileys package to version 7.0.0-rc.5
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
- Bumped baileys dependency version in package.json and package-lock.json to 7.0.0-rc.5 for improved functionality and bug fixes.
- Added p-queue and p-timeout packages for enhanced performance and timeout management.
2025-10-06 14:29:22 -03:00
Spiller
bedfb019aa fix lint 2025-10-06 11:53:50 -03:00
Anderson Silva
6e1d027750 feat(chatwoot): comprehensive improvements to message handling, editing, deletion and i18n
- Fix bidirectional message deletion between Chatwoot and WhatsApp
- Support deletion of multiple attachments sent together
- Implement proper message editing with 'Edited Message:' prefix format
- Enable deletion of edited messages by updating chatwootMessageId
- Skip cache for deleted messages (messageStubType === 1) to prevent duplicates
- Fix i18n translation path detection for production environment
- Add automatic dev/prod path resolution for translation files
- Improve error handling and logging for message operations

Technical improvements:
- Changed Chatwoot deletion query from findFirst to findMany for multiple attachments
- Fixed instanceId override issue in message deletion payload
- Added retry logic with Prisma MessageUpdate validation
- Implemented cache bypass for revoked messages to ensure proper processing
- Enhanced i18n to detect dist/ folder in production vs src/ in development

Resolves issues with:
- Message deletion not working from Chatwoot to WhatsApp
- Multiple attachments causing incomplete deletion
- Edited messages showing raw i18n keys instead of translated text
- Cache collision preventing deletion of edited messages
- Production environment not loading translation files correctly

Note: Tested and validated with Chatwoot v4.1 in production environment
2025-10-03 14:47:24 -03:00
Spiller
fb1fa4d91a feat: add participantsData field maintaining backward
compatibility

  - Keep original participants array (string[]) for backward
  compatibility
  - Add new participantsData field with resolved phone numbers and
  metadata
  - Consumers can migrate gradually from participants to
  participantsData
  - No breaking changes to existing webhook integrations

  Payload structure:
  - participants: string[] (original JID strings)
  - participantsData: object[] (enhanced with phoneNumber, name,
  imgUrl)
2025-09-30 10:12:14 -03:00
Spiller
57ea6707bc feat: convert LID to phoneNumber on
GROUP_PARTICIPANTS_UPDATE
2025-09-29 20:50:39 -03:00
Davidson Gomes
ad8df44236 Merge pull request #2023 from Vitordotpy/fix/chatwoot-conversation-handling
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
fix(chatwoot): Corrige Reabertura de Conversas e Loop de Mensagem de Conexão
2025-09-29 16:08:52 -03:00
Vitordotpy
c132379b3a fix(chatwoot): ajustar lógica de verificação de conversas e cache
Este commit modifica a lógica de verificação de conversas no serviço Chatwoot, garantindo que a busca por conversas ativas seja priorizada em relação ao uso de cache. A verificação de cache foi removida em pontos críticos para evitar que conversas desatualizadas sejam utilizadas, melhorando a precisão na recuperação de dados. Além disso, a lógica de reabertura de conversas foi refinada para garantir que as interações sejam tratadas corretamente, mantendo a experiência do usuário mais fluida.
2025-09-29 15:26:24 -03:00
Vitordotpy
f7862637b1 fix(chatwoot): otimizar lógica de reabertura de conversas e notificação de conexão
Este commit introduz melhorias na integração com o Chatwoot, focando na reabertura de conversas e na notificação de conexão. A lógica foi refatorada para centralizar a busca por conversas abertas e a reabertura de conversas resolvidas, garantindo que interações não sejam perdidas. Além disso, foi implementado um intervalo mínimo para notificações de conexão, evitando mensagens excessivas e melhorando a experiência do usuário.
2025-09-28 22:38:45 -03:00
Vitordotpy
0d8e8bc0fb fix(chatwoot): corrige reabertura de conversas e loop de conexão
Este commit aborda duas questões críticas na integração com o Chatwoot para melhorar a estabilidade e a experiência do agente.

Primeiro, as conversas que já estavam marcadas como "resolvidas" no Chatwoot não eram reabertas automaticamente quando o cliente enviava uma nova mensagem. Isso foi corrigido para que o sistema verifique o status da conversa e a reabra, garantindo que nenhuma nova interação seja perdida.

Segundo, um bug no tratamento do evento de conexão fazia com que a mensagem de status "Conexão estabelecida com sucesso" fosse enviada repetidamente, poluindo o histórico da conversa. A lógica foi ajustada para garantir que esta notificação seja enviada apenas uma vez por evento de conexão.
2025-09-28 22:19:36 -03:00
Davidson Gomes
b62917e80f Merge pull request #2021 from Vitordotpy/fix/message-update-and-i18n-errors
Some checks failed
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
fix(baileys): message update and i18n errors
2025-09-26 16:37:24 -03:00
Vitordotpy
eeb324227b fix(baileys): adicionar log de aviso para mensagens não encontradas
- Implementada uma mensagem de aviso no serviço Baileys quando a mensagem original não é encontrada durante a atualização, melhorando a rastreabilidade de erros.
- Ajustada a lógica de verificação do caminho de traduções para garantir que o diretório correto seja utilizado, com tratamento de erro caso não seja encontrado.
2025-09-26 16:12:40 -03:00
Vitordotpy
c31b62fb3d fix(baileys): corrigir verificação de mensagem no serviço Baileys
- Ajustada a lógica de verificação para garantir que o ID da mensagem seja definido apenas quando disponível, evitando possíveis erros de referência.
- Atualizada a definição do caminho de traduções para suportar a estrutura de diretórios em produção.
2025-09-26 16:00:39 -03:00
Davidson Gomes
22465c0a56 fix: corrigido incompatibilidade no use voise call da wavoip com versao nova da baileys 2025-09-26 13:00:52 -03:00
Davidson Gomes
da6f1bd540 chore(changelog): update CHANGELOG for Baileys v7.0.0-rc.4 and PostgreSQL connection improvements
- Added entry for Baileys version update to v7.0.0-rc.4.
- Refactored PostgreSQL connection handling and enhanced message processing capabilities.
2025-09-26 12:58:36 -03:00
Davidson Gomes
069786b9fe chore(deps): update baileys package to version 7.0.0-rc.4
- Bumped baileys dependency version in package.json and package-lock.json to 7.0.0-rc.4 for improved functionality and bug fixes.
2025-09-26 12:56:40 -03:00
Davidson Gomes
bd0c43feac Merge pull request #2017 from Vitordotpy/fix/enhanced-chatwoot-database-connection
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
Fix Chatwoot DB Connection Instability and Implement Stale Conversation Cache Handling
2025-09-26 07:35:26 -03:00
Vitordotpy
5dc1d02d0a refactor(chatbot): melhorar tratamento de erros em mensagens no Chatwoot
- Implementada a função `handleStaleConversationError` para centralizar a lógica de tratamento de erros relacionados a conversas não encontradas.
- A lógica de retry foi aprimorada para as funções `createMessage` e `sendData`, garantindo que as operações sejam reprocessadas corretamente em caso de falhas.
- Removido código duplicado e melhorada a legibilidade do serviço Chatwoot.
2025-09-25 17:38:10 -03:00
Vitor Manoel Santos Moura
8697329f71 Update src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts
aplicação de desestruturação de objetos que é uma boa prática do ts

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-09-25 17:30:43 -03:00
Vitor Manoel Santos Moura
58b5561f72 Update src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts
aplicação de desestruturação de objetos que é uma boa prática do ts

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-09-25 17:30:30 -03:00
Vitordotpy
093515555d refactor(chatbot): refatorar conexão com PostgreSQL e melhorar tratamento de mensagens
- Alterado método de obtenção da conexão PostgreSQL para ser assíncrono, melhorando a gestão de conexões.
- Implementada lógica de retry para criação de mensagens e conversas, garantindo maior robustez em caso de falhas.
- Ajustadas chamadas de consulta ao banco de dados para utilizar a nova abordagem de conexão.
- Adicionada nova propriedade `messageBodyForRetry` para facilitar o reenvio de mensagens em caso de erro.
2025-09-25 17:08:40 -03:00
Davidson Gomes
d8268b0eb1 fix(migration): resolve PostgreSQL migration error for Kafka integration
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
- Corrected table reference in migration SQL to align with naming conventions.
- Fixed foreign key constraint issue that caused migration failure.
- Ensured successful setup of Kafka integration by addressing database migration errors.
2025-09-24 13:59:23 -03:00
Davidson Gomes
4585850741 chore(release): bump version to 2.3.5 and update bug report template
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
- Updated package and lock files to version 2.3.5.
- Modified bug report template to reflect the new version number.
- Removed outdated Kafka Docker README file.
2025-09-23 18:42:07 -03:00
Davidson Gomes
6c150eed6d chore(docker): add Kafka and frontend services to Docker configurations
- Introduced Kafka and Zookeeper services in a new docker-compose file for better message handling.
- Added frontend service to both development and production docker-compose files for improved UI management.
- Updated evolution-manager-v2 submodule to the latest commit.
- Updated CHANGELOG for version 2.3.5 release.
2025-09-23 18:40:19 -03:00
Davidson Gomes
78c7b96f0f Merge branch 'release/2.3.4'
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
2025-09-23 11:42:25 -03:00
Davidson Gomes
dfea584aa7 chore(changelog): update CHANGELOG for version 2.3.4 release
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
- Enhanced EvolutionBot functionality with splitMessages and linkPreview support
- Centralized message splitting logic across chatbot services for consistency
- Improved message formatting and delivery capabilities
2025-09-23 11:41:51 -03:00
Davidson Gomes
6c5b056615 chore(changelog): remove empty line in CHANGELOG for consistency 2025-09-23 11:37:48 -03:00
Davidson Gomes
d8b4378163 Merge pull request #1986 from dersonbsb2022/main
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
fix(evolutionbot):  Fixing the correct message sending method so that messages are split.
2025-09-22 08:02:11 -03:00
Davidson Gomes
838cc14531 Merge pull request #1989 from JamsMendez/update-docker-compose
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
fix(docker): change private image to public image in docker-compose
2025-09-21 15:18:13 -03:00
Jose A. Mendez Santiago
878da12fa4 fix(docker): change private image to public image in docker-compose 2025-09-20 22:02:25 -06:00
Anderson Silva
10a2b60595 refactor(chatbot): centralize split logic and ensure linkPreview consistency
- Centralize double-line-break message splitting logic into dedicated helper methods
- Add targeted debug logs for better observability without clutter
- Ensure linkPreview parameter is consistently passed across all chatbot services
- Extract splitMessageByDoubleLineBreaks() and sendSingleMessage() helpers
- Update all chatbot services to explicitly pass linkPreview: true
- Improve code testability and maintainability

Services updated:
- BaseChatbotService: Refactored split logic and added debug logs
- TypebotService: Added linkPreview parameter to all sendMessageWhatsApp calls
- OpenAIService: Added linkPreview parameter to all sendMessageWhatsApp calls
- N8nService: Added linkPreview parameter to sendMessageWhatsApp call
- FlowiseService: Added linkPreview parameter to sendMessageWhatsApp call
- EvoaiService: Added linkPreview parameter to sendMessageWhatsApp call
- DifyService: Added linkPreview parameter to all sendMessageWhatsApp calls
2025-09-20 11:35:15 -03:00
Anderson Silva
b0ca79cd11 fix(evolutionbot): implement splitMessages and linkPreview functionality
- Replace instance.textMessage() with sendMessageWhatsApp() method
- Enable message splitting by double line breaks (\n\n)
- Add proper delay and typing indicators between split messages
- Fix linkPreview parameter passing to base class methods
- Support linkPreview: false/true from webhook response
- Remove unnecessary debug logs for cleaner output

Fixes: EvolutionBot was not respecting splitMessages and linkPreview configurations
2025-09-20 10:57:03 -03:00
Davidson Gomes
71eb189a6d chore(changelog): update CHANGELOG for recent enhancements and fixes
Some checks failed
Security Scan / Dependency Review (push) Has been cancelled
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
- Fixed `instanceName` field error in message creation, resolving Prisma validation issues.
- Enhanced media message processing across chatbot services, improving base64 conversion and media URL handling.
- Resolved ESLint configuration conflicts in Evolution Manager v2, updating rules and fixing code formatting issues.
- Streamlined media message handling and improved data consistency in database operations.
2025-09-18 17:47:54 -03:00
Davidson Gomes
407d254cf7 refactor(chatbot): streamline media message handling across chatbot services
- Removed redundant instance name references in EvolutionStartupService to enhance data consistency.
- Updated media message processing in various chatbot services to utilize base64 and mediaUrl more effectively, ensuring better handling of image messages.
- Improved overall code readability and maintainability by simplifying media handling logic.
2025-09-18 17:46:47 -03:00
Davidson Gomes
5f44da61fb feat(evolution-manager): add evolution-manager-v2 as a submodule and update changelog
- Introduced evolution-manager-v2 as a git submodule for easier access and integration.
- Updated CHANGELOG to reflect the addition of evolution-manager-v2 with details on its features and open-source setup.
- Adjusted media message handling in EvolutionStartupService to use null instead of undefined for base64 and mediaUrl properties, ensuring better data consistency.
2025-09-18 17:00:15 -03:00
Davidson Gomes
41a36bbb19 feat(changelog): update CHANGELOG for version 2.3.4
- Added Apache Kafka integration for real-time event streaming, including a new controller, router, and schema.
- Fixed MySQL schema issues related to default values and added missing relation fields in the Instance model.
- Introduced new environment variables for comprehensive Kafka configuration.
2025-09-18 15:48:27 -03:00
Davidson Gomes
8ab41fcfc9 feat(kafka): add Kafka integration for event streaming
- Introduced Kafka support in the Evolution API, allowing for real-time event streaming and processing.
- Updated environment configuration to include Kafka-related variables.
- Added KafkaController and KafkaRouter for managing Kafka events.
- Enhanced event management to support Kafka alongside existing integrations.
- Updated database schemas and migrations for Kafka integration in both MySQL and PostgreSQL.
- Documented Kafka integration in the README file.
2025-09-18 15:44:56 -03:00
Davidson Gomes
5e08628d89 refactor(eslint): change unused vars rule to error and update error handling in services
- Update ESLint configuration to set `@typescript-eslint/no-unused-vars` from 'warn' to 'error' for stricter linting.
- Refactor error handling in various services to omit error variable in catch blocks for cleaner code.
2025-09-18 14:59:33 -03:00
Davidson Gomes
4726c4727d Merge branch 'release/2.3.3'
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
2025-09-18 14:55:45 -03:00
Davidson Gomes
0787a10f39 chore(dependabot): remove dependabot configuration file
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
2025-09-18 14:55:11 -03:00
Davidson Gomes
5bdd6ad9d8 chore(dependencies): upgrade eslint-plugin-simple-import-sort to version 12.1.1 2025-09-18 14:54:12 -03:00
Davidson Gomes
f602ba343f Merge branch 'hotfix/2.3.3' into develop 2025-09-18 14:49:20 -03:00
Davidson Gomes
9d42ad3495 refactor(eslint): update TypeScript object type usage and adjust linting rules
- Change usage of `Object` to `object` in various files for better type safety.
- Update ESLint configuration to change `@typescript-eslint/no-unused-vars` from 'error' to 'warn' and disable certain rules related to object types.
2025-09-18 14:48:56 -03:00
Davidson Gomes
e4da6a1763 Merge branch 'release/2.3.3' 2025-09-18 14:45:42 -03:00
Davidson Gomes
55125856fe chore(docker): upgrade Node.js version in Dockerfile and update dependencies
- Change base image from node:20-alpine to node:24-alpine in Dockerfile for both builder and final stages.
- Update package dependencies in package.json and package-lock.json, including @aws-sdk/client-sqs, @prisma/client, @sentry/node, multer, pino, and others to their latest versions.
- Adjust GitHub Actions workflows to use updated action versions for better performance and security.
2025-09-18 14:45:02 -03:00
Davidson Gomes
a1281927a8 Merge branch 'release/2.3.3' 2025-09-18 14:17:50 -03:00
Davidson Gomes
250cb61748 chore(changelog): update version date for release 2.3.3 2025-09-18 14:17:39 -03:00
Davidson Gomes
ff9ff60e3b Merge pull request #1955 from ricaelchiquetti/fix/upsert_remote_jid_alt
Fix/Adjust remote message key handling in WhatsApp service to include alternative JID
2025-09-18 09:30:28 -03:00
ricael
c6a7e2368b fix: ajustar a manipulação da chave remota da mensagem no serviço WhatsApp para incluir JID alternativo 2025-09-18 09:22:40 -03:00
Davidson Gomes
deb4494fc0 chore(commitlint): increase body and footer line length limits to 150 characters
Some checks are pending
Check Code Quality / check-lint-and-build (push) Waiting to run
Build Docker image / Build and Deploy (push) Waiting to run
Security Scan / CodeQL Analysis (javascript) (push) Waiting to run
Security Scan / Dependency Review (push) Waiting to run
- Update body-max-line-length and footer-max-line-length in commitlint configuration to allow for longer lines, enhancing readability and accommodating more detailed commit messages.
2025-09-17 16:52:03 -03:00
Davidson Gomes
0a357089b3 chore(commitlint): update line length rules for body and footer to 120 characters
- Adjust body-max-line-length and footer-max-line-length in commitlint configuration to allow for longer lines, improving readability and accommodating more detailed commit messages.
2025-09-17 16:51:46 -03:00
Davidson Gomes
3ddbd6a7fb feat(config): add telemetry and metrics configuration options
- Introduce new environment variables for telemetry and Prometheus metrics in .env.example
- Create example configuration files for Prometheus and Grafana dashboards
- Update main application to utilize new configuration settings for Sentry, audio converter, and proxy
- Enhance channel services to support audio conversion API integration
- Implement middleware for metrics IP whitelisting and basic authentication in routes
2025-09-17 16:50:36 -03:00
Davidson Gomes
81a991a62e docs(agents.md and claude.md): update and expand AI Agent guidelines in AGENTS.md and CLAUDE.md
Revise AGENTS.md to provide comprehensive guidelines for AI agents working with the Evolution API.
Enhance CLAUDE.md with detailed project overview, common development commands, and integration
points. Include architecture patterns, coding standards, and testing strategies for better clarity
and consistency.
2025-09-17 15:54:39 -03:00
Davidson Gomes
a721beda3c chore(rules): update input validation standards to use JSONSchema7 and add commit standards 2025-09-17 15:47:26 -03:00
Davidson Gomes
7088ad05d2 feat: add project guidelines and configuration files for development standards
- Introduce AGENTS.md for repository guidelines and project structure
- Add core development principles in .cursor/rules/core-development.mdc
- Establish project-specific context in .cursor/rules/project-context.mdc
- Implement Cursor IDE configuration in .cursor/rules/cursor.json
- Create specialized rules for controllers, services, DTOs, guards, routes, and integrations
- Update .gitignore to exclude unnecessary files
- Enhance CLAUDE.md with project overview and common development commands
2025-09-17 15:43:32 -03:00
Davidson Gomes
805f40c841 feat: add code quality tools and security policy
- Configure Husky with pre-commit and pre-push hooks
- Add commitlint for conventional commit validation
- Create comprehensive security policy (SECURITY.md)
- Add GitHub Actions for security scanning and dependency review
- Create PR and issue templates for better collaboration
- Add Canny.io references for community feedback
- Fix path traversal vulnerability in /assets endpoint
- Create MySQL schema sync analysis tools
2025-09-17 15:05:17 -03:00
Davidson Gomes
09ee2e6296 feat: integrate Husky and lint-staged for automated code quality checks; update changelog and README for new features 2025-09-17 14:49:26 -03:00
Davidson Gomes
dd931eee36 docs: changelog 2.3.3 2025-09-17 14:38:48 -03:00
Davidson Gomes
55822f9443 style: improve code formatting for better readability in WhatsApp service files 2025-09-17 14:30:27 -03:00
Davidson Gomes
00780157db style(sqs): format messageGroupId assignment for improved readability 2025-09-17 14:27:19 -03:00
Davidson Gomes
b514fab30e fix: address Path Traversal vulnerability in /assets endpoint by implementing security checks 2025-09-17 14:27:19 -03:00
Davidson Gomes
7ba878742e Merge pull request #1897 from nolramaf/feat/validate-video-type-before-uploading-to-s3
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
feat/validate video type before uploading to S3
2025-09-17 14:27:03 -03:00
Davidson Gomes
d998baa839 Merge pull request #1896 from nolramaf/feat/add-global-sqs-mode
feat/add global SQS mode with single-queue-per-event and payload size control
2025-09-17 14:26:15 -03:00
Davidson Gomes
e75dae38ee Merge pull request #1947 from elizandropacheco/feat/prometheus-metrics
Feat/prometheus metrics
2025-09-17 14:25:22 -03:00
Davidson Gomes
1fabb1f3bd Merge pull request #1951 from Nocelli/develop
feat: add extra fields to object sent to Flowise bot
2025-09-17 14:23:52 -03:00
Elizandro Pacheco
edfcb0c082 style(metrics): linted index.router.ts after eslint --fix 2025-09-17 12:05:30 -03:00
Davidson Gomes
827604644b Merge pull request #1918 from ricaelchiquetti/main
feat: implement standardized error handling for WhatsApp API responses
2025-09-17 11:40:23 -03:00
Rafael Nocelli Soares
481e179cc5 feat: add extra fields to object sent to Flowise bot 2025-09-17 10:49:13 -03:00
Davidson Gomes
5a39f1ae49 Merge pull request #1948 from furious/fix/download-media-bad-decrypt
fix: convert mediaKey from media messages to avoid bad decrypt errors
2025-09-17 08:52:50 -03:00
ricael
4378c33f42 Merge branch 'develop' into main_ 2025-09-17 08:51:16 -03:00
ricael
ab4bec3b54 Merge branch 'develop' into main 2025-09-17 08:50:39 -03:00
furious
3eeffe4586 fix: convert mediaKey from media messages to avoid bad decrypt errors 2025-09-16 23:02:36 -03:00
Elizandro Pacheco
0e737d48c1 chore(metrics): use 'unknown' as fallback for clientName label 2025-09-16 19:40:21 -03:00
Elizandro Pacheco
a3223ec890 chore: local compose/image tweaks for testing metrics (not part of PR) 2025-09-16 19:35:23 -03:00
Elizandro Pacheco
875b874a7b feat: add Prometheus-compatible /metrics endpoint (gated by PROMETHEUS_METRICS) 2025-09-16 19:35:23 -03:00
Davidson Gomes
486645fb08 chore: update Baileys dependency to version 7.0.0-rc.3 and improve message key handling in WhatsApp service
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-09-15 16:21:33 -03:00
Davidson Gomes
bfe7030fab docs: add CLAUDE.md for development guidance and project architecture overview 2025-09-10 13:07:41 -03:00
Davidson Gomes
1320ec8d4f chore: update Baileys dependency to version 7.0.0-rc.2 in package-lock.json
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-09-10 10:56:15 -03:00
Davidson Gomes
d31d6fa554 refactor: replace JSON path queries with raw SQL in Baileys and Chatwoot services to improve message retrieval and update logic
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
2025-09-09 16:18:15 -03:00
Davidson Gomes
edbf36019e Merge pull request #1929 from moothz/main
Customizable Websockets Security
2025-09-09 16:06:31 -03:00
moothz
d67eb3202b Fix lint 2025-09-09 15:46:26 -03:00
moothz
0aa6c96765 Customizable Websockets Security
Enables the option to specify safe remote addresses using WEBSOCKET_ALLOWED_HOSTS enviroment variables. Defaults to the secure only localhost.
2025-09-09 14:56:11 -03:00
Davidson Gomes
8619e320bc Merge pull request #1928 from josiasmaceda/hotfix/chatbot-not-return-after-human
fix: allowing the chatbot return after the time expires and after human interaction (stopBotFromMe)
2025-09-09 14:33:20 -03:00
Davidson Gomes
5015cfbc9d Merge pull request #1927 from josiasmaceda/hotfix/change-typebot-status-webhook
fix: integrate Typebot status change events for webhook in chatbot controller e service
2025-09-09 14:31:57 -03:00
Josias Maceda
cf548eedbe fix: lint with npm run lint 2025-09-09 14:19:54 -03:00
Josias Maceda
b9ae40145d fix: the lint with npm run lint 2025-09-09 14:15:16 -03:00
Josias Maceda
bc9724a929 fix: remove abort process when status is paused, allowing the chatbot return after the time expires and after being paused due to human interaction (stopBotFromMe) 2025-09-09 13:54:53 -03:00
Davidson Gomes
21502b996d fix: enhance message content sanitization in Baileys service and improve message retrieval logic in Chatwoot service 2025-09-09 12:50:51 -03:00
Davidson Gomes
d9c04fc866 Merge pull request #1906 from andres99x/enhancmenet/check-chatwoot-cron-id
fix: Prevent Duplicate Cron Jobs for Chatwoot Message Sync
2025-09-09 12:20:27 -03:00
Davidson Gomes
d6a76a096d Merge pull request #1908 from dersonbsb2022/main
feat: implement disable/enable linkPreview support for Evolution Bot
2025-09-09 12:19:57 -03:00
Josias Maceda
0116bc4c9f fix: integrate Typebot status change events for webhook in chatbot controller and service 2025-09-09 11:49:13 -03:00
Davidson Gomes
6da79f0313 chore: update CHANGELOG for Baileys v7.0.0-rc.2 and implement message content sanitization in Baileys service
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
2025-09-08 19:53:52 -03:00
Davidson Gomes
8830f476e8 chore: bump version to 2.3.3 in package-lock.json and update remoteJid handling in Baileys service
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
2025-09-08 15:48:38 -03:00
Davidson Gomes
e864b18561 chore: update .gitignore to include 'Baileys' directory 2025-09-08 15:33:54 -03:00
Davidson Gomes
9cb703a427 Merge pull request #1919 from EvolutionAPI/revert-1732-testmsg
Revert "Ignore events that are not messages (like EPHEMERAL_SYNC_RESPONSE)"
2025-09-08 14:49:20 -03:00
ricael
05fcdd9ffc refactor: melhora na formatação do log de erro da API do WhatsApp 2025-09-08 14:45:33 -03:00
Davidson Gomes
3ecf288daf Revert "Ignore events that are not messages (like EPHEMERAL_SYNC_RESPONSE)" 2025-09-08 14:45:29 -03:00
Davidson Gomes
3989ff928b chore: update CHANGELOG for version 2.3.3 and update baileys dependency to latest commit 2025-09-08 14:44:28 -03:00
ricael
16c0a8033f add stringify 2025-09-08 14:36:09 -03:00
ricael
79438c9445 refactor: lint fix 2025-09-08 09:11:45 -03:00
ricael
10a2c001ab feat: implement standardized error handling for WhatsApp API responses 2025-09-08 08:48:49 -03:00
Marlon Alves
7486d22ed1 feat/change variable messageGroupId 2025-09-05 07:18:07 -03:00
Anderson Silva
4f13a8ac28 style: clean up code formatting for linkPreview implementation
- Remove unnecessary trailing whitespace
- Use shorthand property syntax for linkPreview parameter
- Apply ESLint formatting standards
- Maintain code consistency and readability
2025-09-04 14:35:56 -03:00
Anderson Silva
1be58c8487 refactor: improve linkPreview implementation based on PR feedback
- Default linkPreview to true when not specified for backward compatibility
- Validate linkPreview is boolean before passing to textMessage
- Consolidate debug logs and remove sensitive data from logging
- Sanitize API keys in debug output ([REDACTED])
- Reduce log verbosity while maintaining debugging capability
- Ensure robust fallback behavior for malformed responses

Addresses PR feedback regarding:
- Backward compatibility preservation
- Security considerations in logging
- Input validation and error handling
2025-09-04 12:19:51 -03:00
Andres Pache
613d486fc2 stop tasks with missmatch cronId 2025-09-04 09:03:52 -03:00
Marlon Alves
025b183ebf feat/change variable GROUP_UPDATE to GROUPS_UPDATE 2025-09-04 03:18:35 -03:00
Anderson Silva
ceddace915 chore: remove documentation .md files
- Remove evolution-bot-documentation.md
- Remove evolution-bot-linkpreview-example.md
- Remove send-text-api-documentation.md
- Keep only the core linkPreview implementation
2025-09-03 19:59:24 -03:00
Anderson Silva
02b81beb7a feat: implement linkPreview support for Evolution Bot
- Add linkPreview extraction from webhook/n8n response
- Implement linkPreview parameter in textMessage calls
- Add debug logging for linkPreview functionality
- Support for disabling link previews when linkPreview: false
- Add comprehensive documentation for linkPreview feature

Usage:
- Return { "message": "text", "linkPreview": false } from webhook to disable preview
- Return { "message": "text", "linkPreview": true } from webhook to enable preview
- Omit linkPreview for default WhatsApp behavior
2025-09-03 16:08:15 -03:00
Andres Pache
43cc6d3608 check cronId before executing syncChatwootLostMessages 2025-09-03 12:16:00 -03:00
Marlon Alves
edb4fa3b3e feat/force MessageGroupId 2025-09-03 06:21:24 -03:00
Marlon Alves
17120e91a4 feat/force MessageGroupId 2025-09-03 05:57:18 -03:00
Marlon Alves
23cd6d2fd8 feat/force to save all evolution events in a single SQS queue 2025-09-02 17:44:44 -03:00
Davidson Gomes
c2085b59ea Merge branch 'release/2.3.2'
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-09-02 13:33:39 -03:00
Davidson Gomes
2513f96178 chore: bump version to 2.3.2 in package.json and package-lock.json
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-09-02 13:33:34 -03:00
Davidson Gomes
70a2c18146 Merge branch 'release/2.3.2' 2025-09-02 10:53:10 -03:00
Davidson Gomes
b8953f1431 chore: update CHANGELOG for version 2.3.2
- Added support for socks proxy.
- Included key id in webhook payload for n8n service.
- Enhanced RabbitMQ controller with improved connection management and shutdown procedures.
- Converted outgoing images to JPEG format before sending with Chatwoot.
- Updated baileys dependency to version 6.7.19.
2025-09-02 10:53:00 -03:00
nolramaf
9ab6f9ad76 Update src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-09-01 19:50:08 -03:00
nolramaf
9beb38d807 Update src/config/env.config.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-09-01 19:50:01 -03:00
nolramaf
e48e878b4f Update src/api/integrations/channel/meta/whatsapp.business.service.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-09-01 19:49:55 -03:00
Marlon Alves
293f655274 feat/validate video type before uploading to S3 2025-09-01 19:41:56 -03:00
Marlon Alves
cca929e7fc feat/add global SQS mode with single-queue-per-event and payload size control 2025-09-01 19:18:55 -03:00
Davidson Gomes
a91a4ad19c Merge pull request #1889 from codingbox2022/main
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
update version
2025-09-01 11:00:37 -03:00
Davidson Gomes
00ba227e15 chore: update baileys dependency to version 6.7.19 2025-09-01 10:43:12 -03:00
codingbox2022
c02d37028b Merge branch 'main' into main 2025-08-29 22:08:52 -05:00
Davidson Gomes
14771ab84e Merge pull request #1851 from caiquezanetoni/patch-1
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Update 20250116001415_add_wavoip_token_to_settings_table
2025-08-29 07:17:02 -03:00
Davidson Gomes
20352e77ef Merge pull request #1878 from LuisSantosJS/reconnect-rabbitmq
Reconnect rabbitmq
2025-08-29 07:16:13 -03:00
Davidson Gomes
78f7618d04 Merge pull request #1884 from nestordavalos/feat/whatsapp/convert-to-jpeg
Feat/whatsapp/convert-to-jpeg
2025-08-29 07:14:56 -03:00
nestordavalos
57b19d85d5 feat(whatsapp): Convert outgoing images to JPEG before sending
All images sent via the Baileys integration are now pre-processed and converted to JPEG format using the `sharp` library. This ensures better compatibility and prevents potential issues with unsupported formats.

- Images from URLs are now downloaded via axios before processing, which allows for the use of a proxy.
- The default filename and mimetype are updated to `image.jpg` and `image/jpeg` to reflect the conversion.
2025-08-28 00:17:15 -03:00
luissantosjs
b325500310 improve rabbit controller 2025-08-26 19:15:59 +01:00
luissantosjs
4681576cfc up 2025-08-22 22:49:40 +01:00
luissantosjs
7a99fba556 feat: enhance RabbitMQ controller with improved connection management and shutdown procedures 2025-08-20 12:29:45 +01:00
Caíque Zanetoni Fim
6e652d6ea2 Update migration.sql 2025-08-18 08:43:21 -03:00
Davidson Gomes
33a922995b Merge pull request #1838 from bilaliqbalr/patch-2
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Added key id into webhook payload in n8n service
2025-08-15 12:49:10 -03:00
Bilal Iqbal
74cb65c4ea Added key id into webhook payload in n8n service 2025-08-14 00:51:41 +05:00
Davidson Gomes
f9c4255500 Merge pull request #1809 from neto-developer/patch-1
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
docs(readme): corrigidos badge Docker image no README
2025-08-07 08:22:26 -03:00
Davidson Gomes
af423cef28 Merge pull request #1793 from henrybarreto/feat/add-support-socks-proxy
feat: add support to socks proxy
2025-08-07 08:22:00 -03:00
Davidson Gomes
40ce6b56ca Merge pull request #1790 from henrybarreto/feat/improve-test-proxy-error
feat: enhance logging for proxy testing errors
2025-08-07 08:21:48 -03:00
Neto, Aristides da Silva
4945345519 docs(readme): corrigidos badge Docker image no README
Corrigida formatação do badge Docker image no README
2025-08-05 22:07:20 -03:00
Henry Barreto
ab9e0edad6 feat: enhance logging for proxy testing errors
This commit improves the logging in the testProxy method of the
ProxyController class. Now, when an Axios error occurs, the specific
error message will be logged if available. For unexpected errors, the
error object is included for better insight.

For reference, see the "message" field in the Axios documentation:
[Axios Error Handling](https://axios-http.com/docs/handling_errors).
2025-08-05 07:08:49 -03:00
Henry Barreto
3390958314 feat: add support to socks proxy 2025-08-05 07:08:00 -03:00
Davidson Gomes
a8343a8739 Merge pull request #1802 from frieck/main
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Securing websockets
2025-08-04 19:18:30 -03:00
Davidson Gomes
dab66fc8c8 Merge pull request #1786 from bilaliqbalr/patch-1
Fixed boolean and integer type attributes for MySQL
2025-08-04 19:17:49 -03:00
Davidson Gomes
03a44cf9b2 Merge pull request #1798 from apresentame/fix/webhook_event
Permitir correta utilização da evolution quando mensagens não são persistidas no DB
2025-08-04 18:52:58 -03:00
Felipe Augusto Rieck
fb11f3f99c Code quality 2025-08-04 18:19:14 -03:00
Felipe Augusto Rieck
d4eb61f64d Improving localhost check 2025-08-04 18:14:33 -03:00
Felipe Augusto Rieck
4f043f9576 Securing websockets 2025-08-04 16:34:20 -03:00
William Dumes
79f4a22217 refactor: lint check 2025-08-04 13:56:16 -03:00
William Dumes
20dd1b1660 Merge branch 'develop' of github.com:apresentame/evolution-api into fix/webhook_event 2025-08-04 13:52:07 -03:00
William Dumes
fe8280ab7b Merge branch 'main' of github.com:apresentame/evolution-api into fix/webhook_event 2025-08-01 09:41:28 -03:00
William Dumes
bc11d0f751 fix: corrigido delete de mensagem quando nao salvo no banco de dados 2025-07-31 17:27:06 -03:00
Bilal Iqbal
095e435561 Fixed boolean and integer type attributes 2025-07-31 14:26:05 +05:00
Davidson Gomes
96f4b80d46 Merge branch 'release/2.3.1' into develop
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-07-29 09:20:29 -03:00
Davidson Gomes
9cdb897a0f Merge branch 'release/1.3.1'
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-07-29 09:20:16 -03:00
Davidson Gomes
b5c67774dc chore: remove CONFIG_SESSION_PHONE_VERSION and update related code
- Removed the CONFIG_SESSION_PHONE_VERSION environment variable from the configuration and Docker files.
- Updated the BaileysStartupService to directly fetch the latest WhatsApp Web version without relying on the removed environment variable.
- Adjusted the index router to reflect the changes in the WhatsApp Web version retrieval.
2025-07-29 09:20:08 -03:00
Davidson Gomes
7f8293f4c6 changelog: v2.3.1 2025-07-29 09:16:19 -03:00
William Dumes
a62f9ebe46 chore: voltar porta do dockerfile 2025-07-28 11:19:07 -03:00
William Dumes
69726f0dc2 fix(evo): melhorado controle de recebimento do ack das msgs 2025-07-28 09:24:22 -03:00
William Dumes
6101c8d651 fix: corrigido disparo de eventos quando nao usa a opcao da ENV de salvar mensagens no banco 2025-07-25 17:08:14 -03:00
Davidson Gomes
c66485ef98 Merge pull request #1748 from coreh/fix-url-corruption-querystring
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Avoid corrupting media URLs with query strings
2025-07-25 16:56:06 -03:00
Davidson Gomes
4a25cd1ff7 Merge pull request #1757 from KokeroO/develop
fix: atualizar o handle de erros de eventos
2025-07-25 16:54:28 -03:00
Willian Coqueiro
23f54d1d96 lint 2025-07-25 12:13:56 +00:00
Willian Coqueiro
5191438acf fix: update error handling messages and correct group parameter in createContact method 2025-07-25 12:02:17 +00:00
Marco Buono
96d3ec2017 fix: avoid corrupting URLs with query strings 2025-07-23 16:06:14 -03:00
Davidson Gomes
cf95c027eb chore: update package dependencies and scripts
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
- Changed the `baileys` dependency source from `EvolutionAPI` to `WhiskeySockets`.
- Updated the start and development server scripts to use `tsx` instead of `tsnd`.
- Added `tsx` as a new dependency and removed `ts-node-dev`.
- Updated `music-metadata` to version 11.7.1 and adjusted its dependencies.
- Cleaned up the package-lock by removing unused modules and adding new ones like `fflate` and `uint8array-extras`.
2025-07-22 18:21:46 -03:00
Davidson Gomes
9b7ca4bfb7 Merge pull request #1743 from foqc/foqc/develop
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
Add  endpoint to retrieve chat data by remoteJid
2025-07-21 16:13:59 -03:00
foqc
d490f8f576 feature: run lint to clean up codebase 2025-07-21 12:26:08 -05:00
foqc
68e847d10e feature: add endpoint to retrieve chat data by phone number 2025-07-21 12:21:45 -05:00
Davidson Gomes
b98cd11fb1 Merge pull request #1736 from juniortopanotti/main
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
remove lógica de paginação duplicada no fetchChats que causa resultados vazios quando skip > 0
2025-07-21 13:16:22 -03:00
Davidson Gomes
5386d7171b Merge pull request #1732 from rafwell/testmsg
Ignore events that are not messages (like EPHEMERAL_SYNC_RESPONSE)
2025-07-21 13:15:38 -03:00
Davidson Gomes
f59cae7ee2 Merge pull request #1729 from ricaelchiquetti/main
improv: Ajustado isEmoji para aceitar todos os emojis.
2025-07-21 13:15:17 -03:00
Davidson Gomes
0e358cf9c1 Merge pull request #1696 from foqc/foqc/develop
Preserve alias casing in chat fetch query
2025-07-21 13:14:33 -03:00
Gilberto Topanotti Junior
6954472070 remove lógica de paginação duplicada no fetchChats que causa resultados vazios quando skip > 0
Problema:
O método fetchChats estava aplicando a lógica de paginação duas vezes, causando resultados vazios ao usar o parâmetro skip com valores maiores que 0.
Causa Raiz:
A query SQL já aplica LIMIT e OFFSET corretamente
O código JavaScript então aplica .slice(skip, skip + take) nos resultados já paginados
Este "offset duplo" faz com que o slice tente acessar posições do array que não existem
Exemplo do bug:
Requisição: {"take": 10, "skip": 10}
SQL: LIMIT 10 OFFSET 10 → retorna chats 11-20 (10 itens)
JS: .slice(10, 20) → tenta pegar posições 10-20 de um array com apenas 10 itens
Resultado: [] (array vazio)
Solução:
Removida a lógica de paginação JavaScript redundante (linhas 796-800) já que a query SQL já manipula a paginação corretamente com LIMIT e OFFSET.
Arquivos Alterados:
src/api/services/channel.service.ts
Testes:
 {"take": 10, "skip": 0} - Retorna os primeiros 10 chats
 {"take": 10, "skip": 10} - Retorna chats 11-20 (anteriormente retornava [])
 {"take": 5, "skip": 15} - Retorna chats 16-20 (anteriormente retornava [])
Impacto:
Corrige a funcionalidade de paginação para todos os valores de skip > 0
Mantém compatibilidade com versões anteriores
Sem mudanças que quebrem implementações existentes
2025-07-18 14:20:22 -03:00
Rafael Souza
afd0e01ddb fix lint 2025-07-17 15:59:33 -03:00
Rafael Souza
b3dae7a68e Ignore events that are not messages 2025-07-17 15:40:31 -03:00
Rafael Souza
44d4781f6f Ignore events that are not messages 2025-07-17 15:37:37 -03:00
Rafael Souza
e304b1dcdf Fix erro key 2025-07-17 15:32:25 -03:00
Rafael Souza
f8f2153cb4 Fix erro key 2025-07-17 15:29:04 -03:00
codingbox2022
192c34caa0 Update docker-compose.yaml 2025-07-17 12:47:36 -05:00
Davidson Gomes
cdef7dc9f9 Merge pull request #1728 from KokeroO/develop
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Fix: [Chatwoot] Corrige mensagens editas
2025-07-17 11:55:55 -03:00
ricael
85798b209c improv: remover o emojiRefex() da função isEmoji. 2025-07-17 09:43:52 -03:00
ricael
71ebecbed3 improv: ajustado a validação aceitar todos os emojis. 2025-07-17 09:17:06 -03:00
Willian Coqueiro
419300b31f refactor: simplify edited message check in BaileysStartupService 2025-07-17 02:24:21 +00:00
Davidson Gomes
9fd40a411a Merge pull request #1726 from Santosl2/feat/add-async-lock
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run
feat: add BaileysMessageProcessor for improved message handling
2025-07-16 19:24:23 -03:00
Davidson Gomes
d98fa5259e Merge branch 'develop' into feat/add-async-lock 2025-07-16 19:22:44 -03:00
Santosl2
05886ec684 feat: enhance message processing with retry logic for error handling 2025-07-15 21:41:25 -03:00
Santosl2
89d4d341f6 feat: add BaileysMessageProcessor for improved message handling and integrate rxjs for asynchronous processing 2025-07-15 21:35:25 -03:00
foqc
1ca829c00b feature: run lint to clean up codebase 2025-07-15 16:40:17 -05:00
Davidson Gomes
e321609b93 refactor: Simplify conditional check for contact updates in ChatwootService
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
2025-07-14 14:52:02 -03:00
Davidson Gomes
196617507e Merge pull request #1700 from guilherme-aguilar/guilheme_aguilar/develop
feat(database): add pgbouncer support and optimize postgres config
2025-07-14 14:51:49 -03:00
Davidson Gomes
6da71f5161 Merge pull request #1683 from pauloboc/develop
added missing migrations in mysql prisma
2025-07-14 14:51:21 -03:00
Davidson Gomes
5d0278a589 Merge branch 'develop' into foqc/develop 2025-07-14 14:46:36 -03:00
Davidson Gomes
2fb3eac383 Merge pull request #1715 from AlexisJusviack/fix/getBase64-template-support
Fix: Support media extraction from templateMessage in getBase64FromMediaMessage
2025-07-14 14:44:43 -03:00
Davidson Gomes
4a5696eda9 Merge pull request #1704 from rafwell/develop
Throw exception if download media fail
2025-07-14 14:44:29 -03:00
Davidson Gomes
11520481ba Merge pull request #1705 from KokeroO/develop
fix: Tratar conversas @lid no inicio do recebimento dos eventos e novo erro da libsignal
2025-07-14 14:43:57 -03:00
Davidson Gomes
95a53d33ef Merge pull request #1701 from leonardocintra/patch-1
Update README.md - 2025
2025-07-14 14:43:20 -03:00
Davidson Gomes
d458c978f3 Merge branch 'develop' into develop 2025-07-14 14:42:18 -03:00
AlexisJusviack
bd35d7977c Fix: Support media extraction from templateMessage in getBase64FromMediaMessage
### Fix: Add support for templateMessage media in getBase64FromMediaMessage

#### What this does
Adds support to download media from `templateMessage` structures in `getBase64FromMediaMessage`, by checking for `hydratedTemplate` and `hydratedFourRowTemplate`.

#### Why it's needed
Currently, media inside templates (e.g. `imageMessage`, `videoMessage`, `documentMessage`) is not processed by the method, which leads to errors or media being skipped.

#### How it works
If a `templateMessage` is detected, the code looks into the inner hydrated template and assigns the correct `mediaMessage` and `mediaType`. Then it proceeds as usual with the download logic.

#### Example message
```json
{
  "message": {
    "templateMessage": {
      "hydratedTemplate": {
        "imageMessage": {
          "mimetype": "image/jpeg",
          "fileLength": 123456,
          "url": "https://..."
        }
      }
    }
  }
}
2025-07-11 23:50:58 -03:00
guilherme
e92961e7b0 feat(database): add psql_bouncer support and simplify postgresql config
- Add new psql_bouncer database provider option
- Update database scripts to handle psql_bouncer provider
- Comment out pgbouncer service in docker-compose
- Simplify postgresql schema by removing directUrl
- Add new psql_bouncer-schema.prisma file
- Update .env.example with psql_bouncer configuration
- Modify runWithProvider.js to handle psql_bouncer migrations
2025-07-10 01:08:08 -03:00
Rafael Souza
f11d490f7a Remove package-lock.json do .gititnore 2025-07-09 18:56:32 -03:00
Willian Coqueiro
37319966db Remove redudantent code 2025-07-09 18:42:35 +00:00
Willian Coqueiro
630f5c5624 fix:
- [Baileys] Trocar @lids em remoteJid por senderPn em todos os serviços;
 - [Baileys] Adicionar valor @lid recebido em remoteJid para previousRemoteJid (Posteriormente utilizasse em ChatwootService);
 - Minors fixes;
2025-07-09 18:35:57 +00:00
Leonardo Nascimento Cintra
3e690fe9e2 Update README.md - 2025 2025-07-08 20:00:42 -03:00
guilherme
09429e68fe docs: update database name in .env.example from evolution to evolution_db 2025-07-08 18:09:59 -03:00
Rafael Souza
9acccf723d Throw exception if download media fail 2025-07-08 17:43:21 -03:00
guilherme
3b920f93c5 feat(database): add pgbouncer support and optimize postgres config
- Add pgbouncer service to handle connection pooling
- Update database connection URIs to support direct and pooled connections
- Optimize postgres configuration with better memory settings
- Update prisma schema to support directUrl connection
2025-07-08 17:14:37 -03:00
foqc
85936dcaed feature: Correctly map SQL query results by enforcing quoted column aliases (update missing mappings) 2025-07-07 17:40:30 -05:00
foqc
333ef3eeb8 feature: Correctly map SQL query results by enforcing quoted column aliases 2025-07-07 17:31:49 -05:00
Paulo Ferreira
8dd51b0302 added missing migrations in mysql prisma 2025-07-03 15:20:03 -03:00
Davidson Gomes
e6ec706a38 Merge pull request #1665 from pauloboc/fix-prisma-type-mysql
Fix prisma type mysql
2025-07-02 11:22:48 -03:00
Davidson Gomes
53101d4571 Merge pull request #1664 from pauloboc/fix-setup-mysql
(mysql): remove out-of-order wavoipToken migration
2025-07-01 08:15:26 -03:00
Davidson Gomes
c7b5abce6e Merge pull request #1670 from Santosl2/fix/typebot-variables
fix: correçao do typebot não conseguir ouvir mensagens de input
2025-07-01 08:14:28 -03:00
Santosl2
5b1b5ff9d2 fix: bind applyFormatting method in processMessages to maintain context 2025-06-29 20:23:31 -03:00
codingbox2022
505490d237 Update docker-compose.yaml 2025-06-28 22:36:21 -05:00
codingbox2022
675745ae3c Update docker-compose.yaml 2025-06-28 22:28:42 -05:00
codingbox2022
6dfbfe2d83 Update docker-compose.yaml 2025-06-28 22:27:42 -05:00
codingbox2022
1c247498d8 Update docker-compose.yaml 2025-06-28 22:25:44 -05:00
codingbox2022
419324837c Update docker-compose.yaml 2025-06-28 22:05:12 -05:00
codingbox2022
17f97fb051 Update docker-compose.yaml 2025-06-28 22:03:45 -05:00
codingbox2022
f7e7a6c901 Update docker-compose.yaml 2025-06-28 22:02:34 -05:00
codingbox2022
b35b33ca50 Update docker-compose.yaml 2025-06-28 22:00:52 -05:00
Paulo Ferreira
3efe69ada3 fix(prisma) Mysql: update data types for N8n, N8nSetting, Evoai, and EvoaiSetting models 2025-06-28 09:34:52 -03:00
Paulo Ferreira
287c679ce4 (mysql): remove out-of-order wavoipToken migration
Delete prisma/mysql-migrations/1707735894523_add_wavoip_token_to_settings_table, which executes before the initial Setting table is created and breaks fresh MySQL installs.

The later migration 20250214181954_add_wavoip_token_column, line 145, already adds the column correctly, so keeping only that directory guarantees a clean deploy.
2025-06-28 09:27:13 -03:00
Davidson Gomes
918697866f fix(package-lock): update baileys dependency to latest commit hash 2025-06-27 09:59:40 -03:00
Davidson Gomes
3c917af602 Merge pull request #1660 from KokeroO/develop
fix(whatsapp-baileys): Verifica eventos com falhas e fallback para erro ao baixar mídias
2025-06-27 09:55:22 -03:00
KokeroO
52798fd761 fix(whatsapp-baileys): adjust indentation and access modifier for getBase64FromMediaMessage method 2025-06-27 09:29:12 -03:00
KokeroO
34446d188e fix(whatsapp-baileys):
- Implement broken event checking before duplicate message checking. (Do not process failed events).
- Implement error handling when downloading media with a fallback mechanism.
2025-06-27 09:03:32 -03:00
Davidson Gomes
ef31b6de1f Merge pull request #1655 from KokeroO/develop
fix/references-instanceName-typebot
2025-06-26 17:10:58 -03:00
KokeroO
d7afe5d7ab fix(typebot): update instance query to use instance name instead of instance ID 2025-06-26 14:53:54 -03:00
Davidson Gomes
72fb2f408b feat(rabbitmq): implement robust connection handling with reconnection logic and error logging 2025-06-26 14:25:37 -03:00
KokeroO
e4f7856ca9 fix(typebot): update instance query to use instanceName instead of instanceId 2025-06-26 14:05:28 -03:00
Davidson Gomes
e86b6463fd Merge pull request #1652 from KokeroO/patch-1
Corrige ref. instance typebot.controller.ts
2025-06-26 11:49:41 -03:00
Willian Coqueiro
0302944654 Corrige ref. instance typebot.controller.ts 2025-06-26 11:42:27 -03:00
Davidson Gomes
1b0d81b022 Merge pull request #1641 from caduzin02/patch-1
Create railway.json
2025-06-25 16:32:30 -03:00
Davidson Gomes
854d357518 chore(package-lock): update Baileys dependency to version 6.7.18 2025-06-25 16:25:16 -03:00
caduzin02
6e8da4a8dc Create railway.json 2025-06-24 11:02:00 -03:00
Davidson Gomes
e92e98dd22 chore: optimize Dockerfile by using npm ci for dependency installation and streamlining file copy operations 2025-06-23 16:55:04 -03:00
Davidson Gomes
cdd2e59755 chore: update CHANGELOG for version 2.3.1 to include fix for S3 media upload 2025-06-23 16:51:54 -03:00
Davidson Gomes
1a1d9fc957 refactor: add validation for media content in Evolution and Business services to enhance error handling 2025-06-23 16:42:29 -03:00
Davidson Gomes
8ea4d65bc2 refactor: enhance media handling in Baileys service with validation for valid media content 2025-06-23 16:42:24 -03:00
Davidson Gomes
af713dee55 chore: update Dockerfile to use npm run build instead of npm run build:docker 2025-06-23 16:00:01 -03:00
Davidson Gomes
ee9ccb55ca chore: update version to 2.3.1 in Dockerfile, package.json, and package-lock.json 2025-06-23 15:41:49 -03:00
Davidson Gomes
977f686233 chore: update CHANGELOG for version 2.3.1 and fix package.json formatting 2025-06-23 15:38:54 -03:00
Davidson Gomes
a38caeaf5f chore(package-lock): update Baileys dependency to version 6.7.18 2025-06-23 15:36:54 -03:00
Davidson Gomes
873fdcb22a Merge pull request #1633 from VCalazans/FIX/ISSUE-28
🐛 fix: Phone number as message ID for Evo AI #ISSUE 28
2025-06-23 15:35:56 -03:00
Davidson Gomes
2e077a77ef Merge pull request #1626 from fernandeshenrique15/main
add unreadMessages in the response
2025-06-23 15:35:44 -03:00
Davidson Gomes
4be818a436 Merge pull request #1605 from ToniShelby/patch-2
Update Dockerfile
2025-06-23 15:35:33 -03:00
Davidson Gomes
a7badb9af5 Merge pull request #1624 from matheusfterra/main
Correção do envio de variáveis pelo typeboy
2025-06-23 15:35:20 -03:00
Davidson Gomes
ba5fb567eb Merge branch 'develop' into patch-2 2025-06-23 15:34:54 -03:00
Davidson Gomes
1070caf131 Merge pull request #1609 from KokeroO/feat/merge-contacts-lid-in-message-upsert
feat: Adiciona mesclagem de contatos @lid no Chatwoot
2025-06-23 15:32:46 -03:00
Davidson Gomes
9766e10ce9 Merge pull request #1623 from skarious/main
Update Dockerhub Repository and Delete Config Session Variable
2025-06-23 15:32:00 -03:00
Davidson Gomes
cc5612822f Merge pull request #1635 from autonomaia/patch-8
fix: corrige versão inválida do swagger-ui-express
2025-06-23 15:30:58 -03:00
autonomaia
83c1040114 fix: corrige versão inválida do swagger-ui-express 2025-06-22 22:10:51 -03:00
Victor Calazans
b4d1148d6a 🐛 fix: Phone number as message ID for Evo AI 2025-06-22 09:40:14 -03:00
Henrique Fernandes Neto
bd94423e5b add unreadMessages in the response 2025-06-19 16:30:57 -03:00
Matheus Terra
94670cbca3 Merge pull request #1 from matheusfterra/codex/corrigir-erro-ao-processar-mensagens-com-variáveis
Fix Typebot formatting function
2025-06-19 12:45:33 -03:00
Matheus Terra
bda3f5f146 Fix applyFormatting context in Typebot service 2025-06-19 12:45:09 -03:00
Ron Schneider
7724fe3a4f Merge branch 'main' into main 2025-06-19 02:11:50 -03:00
Ron Schneider
8b5f49592a Update evolution_api_v2.yaml
Update EvolutionApi DockerHub Repository and Delete Config Session Variable
2025-06-19 02:02:59 -03:00
Willian Coqueiro
6c0082cd7a feat: adicionar funcionalidade de mesclagem de contatos no Chatwoot 2025-06-17 22:33:51 +00:00
ToniShelby
3391b2ce4b Update Dockerfile 2025-06-17 16:33:50 +01:00
Davidson Gomes
39606240da Merge branch 'release/2.3.0' 2025-06-17 09:25:38 -03:00
Davidson Gomes
f4fbc4afc6 chore(changelog): remove fixed issue with @lid in chatwoot from CHANGELOG 2025-06-17 09:25:19 -03:00
Davidson Gomes
70905e7338 chore(changelog): update version date for 2.3.0 release 2025-06-17 09:20:12 -03:00
Davidson Gomes
07cccb7c7f Merge pull request #1599 from splusoficial/develop
fix: ajuste na validacao dos bots e pausar sessao
2025-06-17 08:52:47 -03:00
Davidson Gomes
5f0862a759 test: disable webhook https test 2025-06-16 15:27:16 -03:00
Joao Vitor
029d68e2cd fix: ajuste na validacao dos bots e pausar sessao 2025-06-15 18:24:34 -03:00
Davidson Gomes
a1fae85531 Merge pull request #1594 from KokeroO/feat/improves-and-adjusts-treatment-lid-numbers
refactor(chatwoot): Melhora e ajusta tratamento de números @lid
2025-06-13 17:54:09 -03:00
Willian Coqueiro
1afa8df556 refactor(chatwoot): simplify findContact method and update contact creation logic 2025-06-13 19:36:13 +00:00
Davidson Gomes
bfb044b234 feat(whatsapp): enhance contact handling and configuration logic
- Added support for `lid` in WhatsApp numbers router to improve contact identification.
- Updated the contact retrieval logic to accept an object with `phone_number` and `identifier` for better clarity and consistency.
- Enhanced error handling and logging in the Chatwoot service for improved traceability during contact creation and updates.
- Implemented automatic search for the latest WhatsApp version if the CONFIG_SESSION_PHONE_VERSION variable is not set, ensuring users have the most up-to-date integration.
2025-06-13 14:58:01 -03:00
Davidson Gomes
ae99ec7a0e feat(whatsapp): implement fetchLatestWaWebVersion utility and update version fetching logic
- Added a new utility function `fetchLatestWaWebVersion` to retrieve the latest WhatsApp Web version.
- Updated the Baileys service and router to utilize the new function instead of the deprecated `fetchLatestBaileysVersion`, ensuring accurate version information is fetched for WhatsApp integration.
- This change enhances the reliability of version management in the application.
2025-06-13 13:14:35 -03:00
Davidson Gomes
22c379aa36 chore(env): comment out WhatsApp Web version in example configuration
- Updated the .env.example file to comment out the CONFIG_SESSION_PHONE_VERSION variable, indicating it is not currently set. This change helps clarify the configuration options available for users.
2025-06-13 12:34:45 -03:00
Davidson Gomes
62c00c3db2 feat(router): update whatsappWebVersion to fetch latest Baileys version
- Modified the root route to fetch the latest WhatsApp web version from Baileys if not set in the environment configuration.
- This enhancement ensures that clients receive the most up-to-date version information in the API response.
2025-06-13 12:03:24 -03:00
Davidson Gomes
afc2927837 feat(IsOnWhatsapp): add optional lid field and update related logic
- Introduced a new optional `lid` field in the IsOnWhatsapp model to enhance data tracking.
- Updated migration script to add the `lid` column to the database.
- Modified OnWhatsAppDto to include the `lid` property for better integration with WhatsApp user data.
- Enhanced the WhatsApp Baileys service to handle `lid` numbers separately and improve user verification logic.
- Updated cache handling functions to support the new `lid` field for consistent data management.
2025-06-13 11:52:32 -03:00
Davidson Gomes
c17b48bca0 fix(chatwoot.service): improve number retrieval logic for message senders
- Enhanced the logic for retrieving sender numbers by introducing a new method that prioritizes senderPn, followed by participant and remoteJid.
- This change ensures more reliable identification of message senders across different scenarios.
2025-06-13 09:10:29 -03:00
Davidson Gomes
534c54a171 fix(chatwoot.service): enhance contact retrieval logic and normalize identifiers
- Updated contact retrieval to handle cases where the identifier is not found, specifically for @lid scenarios.
- Introduced a new method to normalize contact identifiers, prioritizing senderLid and participantLid.
- Improved logging for better traceability during contact lookups and conversation handling.
2025-06-13 08:28:09 -03:00
Davidson Gomes
8603e6def0 feat(router): add whatsappWebVersion to response object
- Included `whatsappWebVersion` in the response object to provide the version of the WhatsApp web session from the environment configuration.
- This addition enhances the API's response with relevant session information for clients.
2025-06-12 18:08:18 -03:00
Davidson Gomes
bcf2febf48 refactor(whatsapp.business.service): replace hardcoded token with class property
- Updated the token retrieval in the BusinessStartupService to use a class property instead of a hardcoded environment variable.
- This change enhances flexibility and maintainability of the service configuration.
2025-06-12 17:32:00 -03:00
Davidson Gomes
a02ecc88f5 refactor(whatsapp.business.service): enhance media handling and audio processing
- Updated media message preparation to conditionally include filename and caption based on media type.
- Improved error handling in media ID retrieval and audio processing methods.
- Refactored audio processing to support file uploads and URL handling more effectively.
- Enhanced logging for better error tracking during media operations.
2025-06-12 17:28:02 -03:00
Davidson Gomes
bc451e8493 feat(Typebot): add splitMessages and timePerChar fields to Typebot models
- Introduced `splitMessages` and `timePerChar` fields in the Typebot and TypebotSetting models with default values.
- Created a migration script to update the database schema accordingly.
- Updated audio message handling to prepend `[audio]` to transcriptions for better clarity in message context.
2025-06-12 13:24:25 -03:00
Davidson Gomes
1eb2c848f7 fix(chatwoot.service): add isLid parameter to service methods for enhanced functionality
- Introduced a new boolean parameter `isLid` in relevant methods to improve the handling of conversation data.
- Updated conditionals to incorporate `isLid` for more precise data management.
- Ensured backward compatibility by maintaining existing functionality while enhancing the service's capabilities.
2025-06-12 12:02:38 -03:00
Davidson Gomes
7cfc359be9 chore: update package-lock.json and refactor WhatsApp Baileys service
- Added new dependency `audio-decode` version 2.2.3.
- Introduced `@eshaz/web-worker` version 1.2.2 with its metadata.
- Refactored `userDevicesCache` initialization and various object destructuring for improved readability in `whatsapp.baileys.service.ts`.
- Streamlined multiple object property assignments for better code clarity.
- Removed deprecated `@typescript-eslint/project-service` and related packages from package-lock.json.
2025-06-12 12:01:01 -03:00
Davidson Gomes
421e762c2d fix(chatwoot.service): Ensure conversation checks are robust before toggling status
- Added null checks for conversation object in reopenConversation mode and when finding unresolved conversations.
- Improved logging for better debugging of conversation retrieval.
2025-06-12 11:18:59 -03:00
Davidson Gomes
9e1f9cbb83 Merge pull request #1574 from edisonmartinsmkt/develop
feat(audio): support LPCM and fix waveform distortion
2025-06-08 20:59:46 -03:00
edisoncm-ti
44e0ff2250 feat(audio): support LPCM and fix waveform distortion 2025-06-08 20:41:59 -03:00
Davidson Gomes
614ad7cbdf Merge pull request #1556 from splusoficial/develop
fix: adjustment in audio transcription with official api
2025-06-06 23:10:57 -03:00
Joao Vitor
77b3b331f8 fix: adjustment in audio transcription with official api 2025-06-05 20:31:11 -03:00
Davidson Gomes
e469dc132f Merge pull request #1536 from Daquisu/fix-fetchStatusMessage-params
Update `fetchStatusMessage` to handle empty offset / page
2025-06-03 12:40:14 -03:00
Daquisu
fa14abac5a Update fetchStatusMessage to handle empty offset / page 2025-06-01 15:22:01 -06:00
Ron Schneider
9db56560e4 Merge pull request #1 from skarious/skarious-patch-1
CONFIG_SESSION_PHONE_VERSION Updated
2025-05-29 14:06:12 -03:00
Ron Schneider
786e57603f CONFIG_SESSION_PHONE_VERSION Updated
CONFIG_SESSION_PHONE_VERSION updated
2025-05-29 14:05:42 -03:00
Davidson Gomes
a53e0a8694 Merge pull request #1513 from samuelterra22/patch-1
fix: change service image version and change to latest config session phone version
2025-05-28 13:53:17 -03:00
Davidson Gomes
16e4bba108 chore: update dependencies in package-lock.json and package.json
This commit updates several dependencies in the package-lock.json and package.json files to their latest versions. Key changes include:
- Upgraded various @typescript-eslint packages to version 8.33.0, ensuring compatibility and access to the latest features and fixes.
- Updated the baileys package from version 6.7.17 to 6.7.18, incorporating the latest improvements.
- Bumped the pino package version from 9.6.0 to 9.7.0 for enhanced performance and stability.
- Updated the process-warning package from version 4.0.1 to 5.0.0, which may include important updates and fixes.
- Adjusted the protobufjs package version from 7.5.2 to 7.4.0, reflecting the latest changes.

These updates contribute to improved performance, security, and maintainability of the codebase.
2025-05-28 11:44:17 -03:00
Davidson Gomes
bd19fff264 Merge branch 'develop' into patch-1 2025-05-28 11:01:17 -03:00
Samuel Terra
94285ecb90 fix: change service image version and change to latest config session phone version 2025-05-28 09:22:38 -03:00
Davidson Gomes
3500fbe27f Merge pull request #1508 from gomessguii/develop
refactor: improve chatbot integrations
2025-05-27 18:03:44 -03:00
Guilherme Gomes
cb76381466 refactor: reorder parameters and simplify EvolutionBot DTO
This commit refines the EvolutionBot integration by reordering constructor parameters for consistency and removing unused properties from the EvolutionBotDto and EvolutionBotSettingDto classes. Key changes include:
- Adjusted the parameter order in the EvolutionBotService constructor for improved clarity.
- Streamlined the EvolutionBotDto and EvolutionBotSettingDto by eliminating unnecessary fields.

These updates enhance the maintainability and readability of the EvolutionBot integration.
2025-05-27 17:52:45 -03:00
Guilherme Gomes
98502f6555 fix: resolve build errors and audio transcription issues across chatbot services
- Add YAML file loader to tsup.config.ts to fix build compilation errors
- Fix OpenAI speechToText method signature across all chatbot services
- Correct DifyService constructor parameter order in server.module.ts and channel.service.ts
- Add missing OpenAI service dependency injection to EvoaiService
- Standardize audio transcription logic in FlowiseService to match N8N implementation
- Fix speechToText calls in WhatsApp Baileys and Evolution channel services
- Ensure consistent error handling and parameter passing for audio processing

This resolves the "Cannot read properties of undefined" errors and ensures
all chatbot integrations (OpenAI, N8N, Flowise, EvoAI, Dify, EvolutionBot)
properly handle audio message transcription using OpenAI Whisper.
2025-05-27 17:46:29 -03:00
Guilherme Gomes
3fc77e4c76 refactor: update asset references in index.html and replace CSS/JS files
This commit updates the asset references in the index.html file to point to new CSS and JS files. Key changes include:
- Replaced the old JavaScript file `index-mxi8bQ4k.js` with `index-D-oOjDYe.js`.
- Updated the CSS file reference from `index-DNOCacL_.css` to the new `index-CXH2BdD4.css`.
- Removed the old CSS and JS files to clean up the codebase.

These updates ensure that the application uses the latest styles and scripts, contributing to improved performance and maintainability.
2025-05-27 17:37:01 -03:00
Guilherme Gomes
19e291178c refactor: streamline integration checks and parameter handling in chatbot controllers
This commit refines the Flowise and Typebot integrations by simplifying the integration enablement checks in their respective controllers. Key changes include:
- Consolidated the integration checks in the createBot method of FlowiseController and startBot method of TypebotController for improved readability.
- Removed unnecessary line breaks to enhance code clarity.

These updates contribute to a cleaner and more maintainable codebase for chatbot integrations.
2025-05-27 17:26:00 -03:00
Guilherme Gomes
7682a679d1 refactor: enhance Dify integration with improved validation and message processing
This commit refines the Dify integration by updating the controller and service logic for better functionality and maintainability. Key changes include:
- Added Dify-specific validation in the createBot method to prevent duplicate entries.
- Simplified comments for clarity and removed unused methods in DifyController.
- Enhanced message processing in DifyService to handle audio messages more effectively and improve error handling.
- Updated DifyDto and DifySettingDto to streamline properties and improve clarity.

These updates contribute to a more robust and maintainable Dify integration.
2025-05-27 17:04:35 -03:00
Guilherme Gomes
97ca23a7b0 refactor: enhance Evoai integration with improved validation and message handling
This commit refines the Evoai integration by updating the service and controller logic for better functionality and maintainability. Key changes include:
- Added the `openaiService` as a parameter in the EvoaiService constructor for improved dependency management.
- Enhanced the createBot method in EvoaiController to include EvoAI-specific validation and duplicate checks.
- Updated EvoaiDto and EvoaiSettingDto to remove unnecessary comments and add a fallback property.
- Refined the message processing logic in EvoaiService to handle audio messages more effectively and improve logging clarity.
- Adjusted the schema for Evoai settings to rename `evoaiIdFallback` to `botIdFallback` for better clarity.

These updates contribute to a more robust and maintainable Evoai integration.
2025-05-27 16:00:32 -03:00
Guilherme Gomes
95bd85b6e3 refactor: update Flowise integration for improved configuration and validation
This commit refines the Flowise integration by enhancing configuration management and validation logic. Key changes include:
- Reordered parameters in the FlowiseService constructor for consistency.
- Updated FlowiseController to utilize the configService for integration enablement checks.
- Simplified FlowiseDto and FlowiseSettingDto by removing unused properties.
- Enhanced validation logic in flowise.schema.ts to include new fields.
- Improved error handling in the createBot method to prevent duplicate entries.

These updates contribute to a more robust and maintainable Flowise integration.
2025-05-27 15:49:15 -03:00
Guilherme Gomes
64fc7a05ac refactor: improve session handling and validation in N8n integration
This commit enhances the N8n integration by refining session management and validation logic. Key changes include:
- Added error handling for session creation failures in the BaseChatbotService.
- Removed unused methods and properties in N8nService and N8nDto to streamline the codebase.
- Updated N8n schema to enforce required fields and improve validation checks.
- Simplified message processing logic to utilize base class methods, enhancing maintainability.

These improvements contribute to a more robust and efficient N8n integration.
2025-05-27 15:10:47 -03:00
Guilherme Gomes
39aaf29d54 refactor: enhance OpenAI controller and service for better credential management
This commit refactors the OpenAIController and OpenAIService to improve credential handling and error management. Key changes include:
- Added checks to prevent duplicate API keys and names during bot creation.
- Updated the getModels method to accept an optional credential ID for more flexible credential usage.
- Enhanced error handling with specific BadRequestException messages for better clarity.
- Removed unused methods and streamlined the speech-to-text functionality to utilize instance-specific settings.

These improvements enhance the maintainability and usability of the OpenAI integration.
2025-05-27 14:32:10 -03:00
Guilherme Gomes
22e99f7934 refactor: simplify TypebotController and TypebotService methods
This commit refactors the TypebotController and TypebotService to streamline the processTypebot method, aligning it with the base class pattern. It reduces complexity by consolidating parameters and improving readability. Additionally, it updates the TypebotDto and TypebotSettingDto to remove unused properties, enhancing code clarity and maintainability.
2025-05-27 13:07:15 -03:00
Davidson Gomes
dd0dfd447c Merge pull request #1504 from KokeroO/develop
fix: Melhora o método createConversation (evita conversas criadas duplicadas Chatwoot)
2025-05-27 08:11:34 -03:00
Willian Coqueiro
fb18267ac5 fix: eslint 2025-05-27 02:10:15 +00:00
Willian Coqueiro
fc5965938e fix: improve createConversation method with caching and locking mechanisms 2025-05-27 01:31:06 +00:00
Davidson Gomes
623efd86a2 Merge pull request #1498 from thrsouza/main
Inclusão do parâmetro frame_max para compatibilidade com RabbitMQ 4.1+
2025-05-25 11:10:40 -03:00
Thiago Souza
3297364c10 fix: update RabbitMQ frame_max parameter for 4.1+ compatibility
Updates the minimum frame_max value from 4096 to 8192 to meet the requirements
of RabbitMQ 4.1+ servers. This resolves connection failures with newer RabbitMQ
versions while maintaining backwards compatibility with older versions.
2025-05-25 03:08:12 -03:00
Davidson Gomes
373a531e88 fix: update logging and message handling in EvoaiService
This commit modifies the logging messages in the `EvoaiService` to use the correct service name "EvoAI" instead of "Dify" for better clarity. Additionally, it refines the message handling logic by changing the way message IDs are generated and updating the payload structure sent to the API. The extraction of the message from the response artifacts has also been improved to ensure that the correct message is retrieved from the response data.

Changes include:
- Updated logging statements to reflect the correct service name.
- Changed the message ID generation to use a shorter UUID substring.
- Adjusted the payload structure to include `contextId` and `messageId`.
- Enhanced message extraction logic from the response artifacts.

These changes enhance the clarity of logs and improve the robustness of message handling in the service.
2025-05-23 20:37:01 -03:00
Davidson Gomes
e081533f02 fix: remove unused Auth import from Dify and N8n services
This commit removes the unused `Auth` import from both `dify.service.ts` and `n8n.service.ts`. This change helps to clean up the code and improve readability by eliminating unnecessary dependencies.
2025-05-23 20:09:36 -03:00
Davidson Gomes
17fd407d8d Merge pull request #1494 from KokeroO/develop
fix: melhora a formatação e tratamento de erros na função getExistingSourceIds
2025-05-23 10:43:27 -03:00
Willian Coqueiro
0cdc67effe fix: eslint 2025-05-23 02:40:05 +00:00
Willian Coqueiro
ddaf32be76 fix: melhora a formatação e tratamento de erros na função getExistingSourceIds 2025-05-23 02:18:13 +00:00
Willian Coqueiro
0b2d8a752f fix: melhora o tratamento de erros e otimiza a consulta de IDs de origem no Chatwoot 2025-05-23 02:13:46 +00:00
Davidson Gomes
9cda6a2f99 Merge pull request #1493 from oriondesign2015/develop
corrige estrutura de if/else e bloco try/catch em chatwoot-import-helper.ts
2025-05-22 21:57:33 -03:00
OrionDesign
d2263af3e8 fix: corrige estrutura de if/else e bloco try/catch em chatwoot-import-helper.ts
Esta PR corrige problemas de sintaxe no arquivo chatwoot-import-helper.ts, especificamente:
- Ajusta a estrutura do bloco if/else no método getExistingSourceIds, evitando erro de compilação do TypeScript.
- Garante que o bloco catch esteja corretamente posicionado dentro do método, retornando null em caso de erro.
- Mantém a lógica original do método, apenas corrigindo a sintaxe para permitir a compilação e execução correta do projeto.
Essas correções eliminam o erro de build relacionado ao TypeScript e melhoram a robustez do código ao tratar exceções de forma adequada.
2025-05-22 18:51:28 -03:00
Davidson Gomes
0239638232 Merge pull request #1490 from KokeroO/develop
fix: Corrige o PR1481
2025-05-22 17:08:43 -03:00
Willian Coqueiro
3459d61eff fix: Corrige o PR1481 2025-05-22 20:03:32 +00:00
Davidson Gomes
5330121c49 Merge pull request #1486 from oriondesign2015/develop
fix: Corrige envio da apiKey da instância nos payloads do Flowise e do Dify
2025-05-22 11:24:20 -03:00
OrionDesign
53c1c218c4 fix: Corrige envio da apiKey da instância no payload do Dify
Corrige o envio da apiKey no payload do Dify para usar a apiKey específica da instância ao invés da apiKey global do sistema.
2025-05-22 11:04:13 -03:00
OrionDesign
06378e5d6b fix: Corrige envio da apiKey da instância no payload do Flowise
Corrige o envio da apiKey no payload do Flowise para usar a apiKey específica da instância ao invés da apiKey global do sistema.
2025-05-22 11:03:22 -03:00
Davidson Gomes
6a83e89394 Merge pull request #1485 from oriondesign2015/develop
fix: Corrige envio da apiKey da instância nos payloads do Evolution Bot e N8N
2025-05-22 11:02:21 -03:00
OrionDesign
d24540d6dd fix: Corrige envio da apiKey da instância no payload do N8N
Corrige o envio da apiKey no payload do N8N para usar a apiKey específica da instância ao invés da apiKey global do sistema.
2025-05-22 10:57:41 -03:00
OrionDesign
2af7b24013 fix: Corrige envio da apiKey da instância no payload do Evolution Bot
Corrige o envio da apiKey no payload do Evolution Bot para usar a apiKey específica da instância ao invés da apiKey global do sistema.
2025-05-22 10:56:54 -03:00
Davidson Gomes
6f47a54fae Merge pull request #1483 from KokeroO/develop
chore: possibilita o envio de medias do tipo [svg, tiff] vindas do Chatwoot
2025-05-22 07:03:41 -03:00
Davidson Gomes
edde059fa1 Merge pull request #1484 from oriondesign2015/develop
fix: melhora consistência e formatação dos chatbots (N8N e Evolution Bot)
2025-05-22 06:58:21 -03:00
OrionDesign
dcb09b87fe fix: corrige comportamento de sessão pausada no N8N
Corrige o problema onde o N8N reativava automaticamente a sessão após receber uma mensagem quando estava pausado. Agora, quando uma sessão está pausada, o bot ignora completamente as mensagens recebidas até que a sessão seja explicitamente reativada através do endpoint de mudança de status.
2025-05-22 01:08:48 -03:00
OrionDesign
bbf142cf39 fix: corrige comportamento de sessão pausada no Evolution Bot
Corrige o problema onde o Evolution Bot reativava automaticamente por qualquer mensagem do usuario quando a sessão estava pausada. Agora, quando uma sessão está pausada, o bot ignora completamente as mensagens recebidas até que a sessão seja explicitamente reativada.
2025-05-22 01:01:51 -03:00
OrionDesign
da51b6bd76 fix: corrige processamento de mensagens subsequentes no Evolution Bot
Corrige o problema onde o Evolution Bot não processava mensagens subsequentes após a primeira resposta. A correção permite que o bot continue respondendo a todas as mensagens enquanto a sessão estiver ativa, melhorando a continuidade da conversa.
2025-05-22 00:54:37 -03:00
Willian Coqueiro
8b15c11817 chore: adiciona suporte para extensão de arquivo .tif no envio de documentos 2025-05-22 03:38:57 +00:00
Willian Coqueiro
272a4de236 chore: possibilita o envio de medias do tipo svg e tiff vindas do Chatwoot 2025-05-22 03:29:16 +00:00
OrionDesign
65111481b9 fix: remove quebras de linha extras nas mensagens do N8n
Corrige o problema de formatação nas mensagens do N8n onde quebras de linha extras estavam sendo adicionadas antes e depois das mídias (imagens, vídeos, etc). Agora o texto é enviado mantendo apenas as quebras de linha intencionais.
2025-05-22 00:17:06 -03:00
Willian Coqueiro
0ca109e9d6 chore: possibilita o envio de medias do tipo .svg 2025-05-22 03:02:04 +00:00
Davidson Gomes
5b817028a9 refactor(chatbot): enhance EvoaiService with OpenAI integration
- Integrated OpenAI service into the EvoaiService to streamline audio message transcription.
- Updated the constructor to initialize OpenaiService, allowing for direct transcription of audio messages.
- Refactored audio message handling to utilize the OpenAI service for improved reliability and maintainability.
- Adjusted the processing logic to handle transcription results more effectively, ensuring fallback content is provided when transcription fails.

This commit focuses on enhancing the EvoaiService's capabilities by leveraging OpenAI for audio transcription, improving overall service functionality and code structure.
2025-05-21 22:27:59 -03:00
Davidson Gomes
6a0fc19702 refactor(chatbot): integrate OpenAI service into chatbot implementations
- Updated various chatbot services (Typebot, Dify, EvolutionBot, Flowise, N8n) to include the OpenAI service for audio transcription capabilities.
- Modified constructors to accept OpenaiService as a dependency, enhancing the ability to transcribe audio messages directly within each service.
- Refactored the handling of `keywordFinish` in multiple controllers and services, changing its type from an array to a string for consistency and simplifying logic.
- Removed redundant audio transcription logic from the base service, centralizing it within the OpenAI service to improve maintainability and reduce code duplication.

This commit focuses on enhancing the chatbot services by integrating OpenAI's transcription capabilities, improving code structure, and ensuring consistent handling of session keywords.
2025-05-21 22:17:10 -03:00
Davidson Gomes
9cedf31eed feat(env): enhance webhook configuration and SSL support
- Added new environment variables for SSL configuration, including `SSL_CONF_PRIVKEY` and `SSL_CONF_FULLCHAIN`, to support secure connections.
- Introduced additional webhook configuration options in the `.env.example` file, such as `WEBHOOK_REQUEST_TIMEOUT_MS`, `WEBHOOK_RETRY_MAX_ATTEMPTS`, and related retry settings to improve webhook resilience and error handling.
- Updated the `bootstrap` function in `main.ts` to handle SSL certificate loading failures gracefully, falling back to HTTP if necessary.
- Enhanced error handling and logging in the `BusinessStartupService` to ensure better traceability and robustness when processing messages.

This commit focuses on improving the security and reliability of webhook interactions while ensuring that the application can handle SSL configurations effectively.
2025-05-21 17:55:00 -03:00
Davidson Gomes
f9567fbeaa refactor(chatbot): unify keywordFinish type and enhance session handling
- Changed the type of `keywordFinish` from an array to a string in multiple DTOs and controller interfaces to simplify data handling.
- Updated the `BaseChatbotService` to include logic for updating session status to 'opened' and managing user responses more effectively.
- Refactored the media message handling in the `BaseChatbotService` to streamline the process and improve readability.
- Enhanced error logging across various services to ensure better traceability during operations.

This commit focuses on improving the structure and consistency of chatbot integrations while ensuring that session management is robust and user-friendly.
2025-05-21 17:02:24 -03:00
Davidson Gomes
d673c83a93 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2025-05-21 15:14:50 -03:00
Davidson Gomes
e16bb0e580 style(whatsapp): format code for consistency
- Adjusted spacing in destructuring assignments for `remoteJid` in multiple locations to enhance code readability and maintain consistency with coding standards.
- Removed unnecessary blank lines to streamline the code structure.

This commit focuses on improving the overall style of the `whatsapp.baileys.service.ts` file without altering any functionality.
2025-05-21 15:14:41 -03:00
Davidson Gomes
09120aa026 Merge pull request #1482 from gomessguii/fix/message-query
Refatoração da funcionalidade de chatbots (em andamento)
2025-05-21 15:14:25 -03:00
Davidson Gomes
fbfa364df9 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2025-05-21 15:01:22 -03:00
Davidson Gomes
624b37e2aa fix(media): improve media download handling for base64 conversion
- Enhanced the logic for converting media messages to base64 by adding a retry mechanism for downloading media if the initial buffer is not available.
- This change ensures that media messages are reliably converted to base64 format, improving the robustness of media handling in the WhatsApp integration service.
- Updated error logging to capture issues during the media conversion process.
2025-05-21 15:01:17 -03:00
Davidson Gomes
fcde1f9acc Merge pull request #1481 from AlexSzefezuk/fix-chatwoot-import
Fix-chatwoot-import
2025-05-21 13:54:51 -03:00
Davidson Gomes
cc01787501 Merge pull request #1473 from KokeroO/develop
fix: Deadlock errors and undefined arguments
2025-05-21 13:52:57 -03:00
Guilherme Gomes
c30bae4c3a refactor(openai): improve service initialization and streamline audio transcription handling
- Updated OpenaiService and related classes to enhance the initialization process by ensuring the correct order of parameters.
- Simplified audio message handling by consolidating transcription logic and improving error handling.
- Refactored the OpenaiController to utilize the new structure, ensuring better integration with the base chatbot framework.
- Enhanced logging for better traceability during audio processing and API interactions.
2025-05-21 12:16:12 -03:00
Alex Szefezuk
2545013040 fix: enable sourceId exists in a conversation 2025-05-21 10:36:26 -03:00
Willian Coqueiro
c53a96e757 Fix suggestions 2025-05-20 13:07:28 +00:00
Willian Coqueiro
a2d8642e1c fix: Corrige processamento de documentos sem filename.
## Erros:
- Cannot read properties of null (reading 'fileName')
2025-05-19 23:21:01 +00:00
Willian Coqueiro
9c530c69cf fix: Evita tentar processar media messageContextInfo e disparar um erro generico. 2025-05-19 23:18:23 +00:00
Willian Coqueiro
348a4ff251 fix: Corrige problemas com deadlocks
## Erros:
- code: "40P01", message: "deadlock detected".
- Argument status is missing.
2025-05-19 23:14:57 +00:00
Willian Coqueiro
fc00916345 fix: Corrige o erro Unable to fit integer value '1747658857155' into an INT4 (32-bit signed integer.
## Solução
Após analise dos valores recebidos e seguindo a logica em outras partes também, se confirma que o valor de entrada é de timestamp em ms.
2025-05-19 23:05:11 +00:00
Guilherme Gomes
69b4f1aa02 feat(chatbot): implement base chatbot structure and enhance integration capabilities
- Introduced a base structure for chatbot integrations, including BaseChatbotController and BaseChatbotService.
- Added common DTOs for chatbot settings and data to streamline integration processes.
- Updated existing chatbot controllers (Dify, Evoai, N8n) to extend from the new base classes, improving code reusability and maintainability.
- Enhanced media message handling across integrations, including audio transcription capabilities using OpenAI's Whisper API.
- Refactored service methods to accommodate new message structures and improve error handling.
2025-05-17 16:22:13 -03:00
Davidson Gomes
7cccda10bb Merge pull request #1456 from thiagoomatheus/main
Fixes issue #879
2025-05-16 13:38:30 -03:00
Davidson Gomes
33c808b195 Merge pull request #1457 from gomessguii/fix/message-query
feat(channel): enhance pushName logic for messages
2025-05-16 12:02:31 -03:00
Guilherme Gomes
d3ee370bdc feat(channel): enhance pushName logic for messages
- Updated the pushName selection to differentiate between group and individual messages.
- Added conditional logic to display the chat name for group messages and the sender's name for individual messages.
2025-05-16 11:33:52 -03:00
thiagoomatheus
7e5740b462 fix(media): allow multiples files with same name 2025-05-15 22:37:55 -03:00
Davidson Gomes
0b33a76394 changelog v2.3.0 2025-05-15 18:49:35 -03:00
Davidson Gomes
6a0b024b13 Merge pull request #1453 from gomessguii/fix/evoai-migration
feat(evoai): add Evoai and EvoaiSetting tables with foreign key const…
2025-05-15 18:20:09 -03:00
Guilherme Gomes
fda6b0d50e feat(evoai): add Evoai and EvoaiSetting tables with foreign key constraints
- Created the Evoai and EvoaiSetting tables in the PostgreSQL migration.
- Defined primary keys and added foreign key constraints to link with the Instance table.
- Included unique index on instanceId for EvoaiSetting to ensure data integrity.
2025-05-15 18:19:23 -03:00
Davidson Gomes
9ec6847683 Merge pull request #1452 from gomessguii/feature/new-manager-version
feat: updated manager to the last version with suport to n8n and EvoA…
2025-05-15 18:12:38 -03:00
Guilherme Gomes
c745fbad64 feat: updated manager to the last version with suport to n8n and EvoAI chatbot integrations 2025-05-15 18:09:23 -03:00
Davidson Gomes
40ea8bf356 Merge pull request #1451 from gomessguii/feature/evoai-chatbot
feat(evoai): add EvoAI integration with models, services, and routes
2025-05-15 15:50:12 -03:00
Guilherme Gomes
0699ad4bb0 fix(evoai): update EvoAI service initialization to include configService
- Modified the EvoaiService instantiation in the server module to include configService for enhanced configuration management.
2025-05-15 15:46:13 -03:00
Guilherme Gomes
70a4fe8f6e feat(evoai): enhance media message handling and transcription capabilities
- Added support for audio message detection and transcription using OpenAI's Whisper API.
- Integrated media downloading for both audio and image messages, with appropriate error handling.
- Updated logging to redact sensitive information from payloads.
- Modified existing methods to accommodate the new message structure, ensuring seamless integration with EvoAI services.
2025-05-15 15:42:17 -03:00
Guilherme Gomes
71124755b0 feat(evoai): add EvoAI integration with models, services, and routes
- Introduced Evoai and EvoaiSetting models in both MySQL and PostgreSQL schemas.
- Implemented EvoaiController and EvoaiService for managing EvoAI bots.
- Created EvoaiRouter for handling API requests related to EvoAI.
- Added DTOs and validation schemas for EvoAI integration.
- Updated server module and chatbot controller to include EvoAI functionality.
- Configured environment settings for EvoAI integration.
2025-05-15 11:54:11 -03:00
Davidson Gomes
a1cc504777 Merge pull request #1449 from gomessguii/feature/enhance-message-fetching
feat(whatsapp): enhance message fetching and processing logic
2025-05-14 21:44:39 -03:00
Davidson Gomes
0fd2e04286 Merge pull request #1448 from gomessguii/feature/n8n-chatbot
Add N8n integration with models, services, and routes
2025-05-14 21:44:25 -03:00
Guilherme Gomes
4f2b0c42f3 Merge pull request #2 from EvolutionAPI/develop
Develop
2025-05-14 21:35:36 -03:00
Guilherme Gomes
401b0359cd Merge pull request #1 from EvolutionAPI/develop
Develop
2025-05-14 21:32:41 -03:00
Davidson Gomes
b1f3c5cc5f Merge pull request #1450 from gomessguii/fix/npm-install-action
fix: remove postinstall script from package.json to fix GitHub Action
2025-05-14 21:29:57 -03:00
Guilherme Gomes
362736ea71 refactor(whatsapp): format userDevicesCache initialization for improved readability 2025-05-14 21:27:23 -03:00
Guilherme Gomes
2544c10592 fix: remove postinstall script from package.json to fix GitHub Action 2025-05-14 21:22:52 -03:00
Guilherme Gomes
383805aa95 feat(whatsapp): enhance message fetching and processing logic
- Added a new method `fetchMessages` to retrieve messages based on various query parameters.
- Improved handling of `pushName` for messages, ensuring proper assignment based on participant information.
- Refactored user devices cache initialization for better readability.
- Cleaned up commented-out code related to message recovery.
2025-05-14 21:12:45 -03:00
Guilherme Gomes
71101807bb Refactor N8n integration: update schema exports, improve import order, and enhance service logic
- Added export for N8n schema in chatbot.schema.ts.
- Improved import order in n8n.dto.ts and n8n.router.ts for better readability.
- Refactored variable declarations in n8n.service.ts for consistency and clarity.
2025-05-14 20:50:48 -03:00
Guilherme Gomes
38f089f04c Add N8n integration with models, services, and routes
- Introduced N8n and N8nSetting models in both MySQL and PostgreSQL schemas.
- Implemented N8nController and N8nService for managing N8n bots.
- Created N8nRouter for handling API requests related to N8n.
- Added DTOs and validation schemas for N8n integration.
- Updated server module and chatbot controller to include N8n functionality.
- Configured environment settings for N8n integration.
2025-05-14 20:47:23 -03:00
Davidson Gomes
6d63f2fb6e Merge pull request #1420 from luiis716/main
Findchat group name treatment
2025-05-13 06:28:21 -03:00
Davidson Gomes
bb0b9b94ff Merge branch 'develop' into main 2025-05-13 06:28:07 -03:00
luiis716
a449fdf0ef Findchat group name treatment 2025-05-12 16:14:59 -03:00
Davidson Gomes
ec9de49647 Merge pull request #1435 from edisonmartinsmkt/fix/audio-caption-fallback
fix(chatwoot): only fallback audio caption when audioMessage exists
2025-05-10 19:14:41 -03:00
edisoncm-ti
a7a9de2903 fix: only fallback caption when audioMessage exists 2025-05-10 16:20:05 -03:00
Davidson Gomes
99b0c86278 Merge pull request #1422 from icaro-andrade/patch-2
Update package.json
2025-05-10 13:07:39 -03:00
Davidson Gomes
e6a72bd829 Merge pull request #1406 from Faelst/hotfix/issues-1385
fix: when you set jpegThumbnail, image not appear on app mobile
2025-05-10 13:07:06 -03:00
Davidson Gomes
341a0d884f Merge pull request #1332 from theeusmartins/main
Defininando TTL no userDivicesCache igual usado no Baileys
2025-05-10 11:26:23 -03:00
Davidson Gomes
383bac090a Merge pull request #1434 from edisonmartinsmkt/fix/group-audio-caption
fix(chatwoot): avoid "undefined" caption on group audio messages
2025-05-10 11:25:14 -03:00
edisoncm-ti
60a58ca037 fix: not show undefined in caption for received audio messages in group chats 2025-05-10 11:12:44 -03:00
Davidson Gomes
e5989f3d47 Merge pull request #1433 from paulocoutinhox/fix-mysql-wavoip-token
fix mysql wavoip token
2025-05-10 10:32:12 -03:00
Davidson Gomes
bff3bf564b Merge pull request #1415 from victoreduardo/victoreduardos/fix-conversation-not-found
fix: Erro na criação de conversation quando já existe uma conversation de outro inbox para o mesmo usuário
2025-05-10 10:31:06 -03:00
Davidson Gomes
c74eee8e52 Merge pull request #1414 from onerrogus/fix_link_preview
Corrigir utilização do linkPreview no WhatsApp Business API
2025-05-10 10:30:54 -03:00
Davidson Gomes
d1a28ea4f7 Merge pull request #1318 from victoreduardo/victoreduardos/jwt-webhook
Tornando Webhook mais seguro com JWT token
2025-05-10 10:28:07 -03:00
Davidson Gomes
d2f1985913 Merge pull request #1425 from edisonmartinsmkt/develop
fix(audio): ensure full WhatsApp compatibility for audio conversion
2025-05-10 08:33:28 -03:00
Paulo Coutinho
90e27cc7d8 fix mysql wavoip token 2025-05-10 03:53:35 -03:00
edisoncm-ti
c4ddfe6804 style: fix linting issues with Prettier 2025-05-07 18:18:47 -03:00
edisoncm-ti
aaa103a842 fix(audio): ensure full WhatsApp compatibility for audio conversion (libopus, 48kHz, mono) 2025-05-07 13:41:09 -03:00
icaro-andrade
b2809b6f3e Update package.json 2025-05-06 19:33:46 -03:00
luiis716
d52256718d Findchat group name treatment
ajusta para endpoint puxa o nome do grupo correntemente quando for grupo usando nomenclatura @g.us
2025-05-03 14:55:07 -03:00
Victor Eduardo
8f0ede4207 fix: preventing use conversation from other inbox for the same user 2025-05-03 09:56:28 -03:00
Victor Eduardo
95827a2d70 lint 2025-05-03 09:42:18 -03:00
Victor Eduardo
b064e512e2 Merge branch 'develop' into victoreduardos/jwt-webhook 2025-05-03 09:40:37 -03:00
OnerRogus
db5f0d0891 fix: corrigido erro que não exibia o preview das urls quando utilizado o whatsapp business api 2025-05-02 15:32:47 -03:00
Davidson Gomes
ccbd866e42 Merge pull request #1384 from leandrosroc/develop
fix(api): modifica fetchChats para trazer mensagens de contatos não salvos
2025-04-30 06:15:42 -03:00
Rafael Silverio
dc67039b39 fix: when you set jpegThumbnail, image not appear on app mobile 2025-04-29 14:54:42 -03:00
Leandro Santos Rocha
eeedfb0e2a fetchContacts - nestordavalos 2025-04-22 16:12:47 -03:00
Leandro Santos Rocha
3ab75faff7 fix lint 2025-04-21 00:42:33 -03:00
Leandro Santos Rocha
095754d173 perf(api): otimiza paginação em fetchChats usando LIMIT/OFFSET no SQL 2025-04-21 00:38:25 -03:00
Leandro Rocha
b94b452597 fix(api): modifica fetchChats para trazer mensagens de contatos não salvos
- Muda tabela base da consulta de Contact para Message
- Altera INNER JOIN para LEFT JOIN entre Message e Contact
- Usa COALESCE para campos que podem estar vazios
- Adiciona flag isSaved para identificar contatos salvos/não salvos
- Preserva toda funcionalidade de filtros existente

Resolve issue #1376
2025-04-21 00:30:48 -03:00
Davidson Gomes
2ded19752f Merge pull request #1366 from adaptwebtech/hotfix_chatname
Corrigindo um bug ao atualizar o push name no evento MESSAGES_UPSERT e MESSAGES_UPDATE
2025-04-14 20:06:23 -03:00
pedro-php
4c8c7ee19b lint fixes 2025-04-09 15:15:48 -03:00
pedro-php
8c6f95fbef Fixing chatname on the events message.upsert and message.update in order to return always the chatname from the user correctly 2025-04-09 14:55:22 -03:00
Davidson Gomes
402b37d7b4 Merge pull request #1351 from ricocorreia1/main
Correção para quando enviar uma localização.
2025-04-08 19:10:38 -03:00
Davidson Gomes
09f79c94be Merge pull request #1362 from Deyvi-dev/develop
feat(s3): add S3_SKIP_POLICY env variable to disable setBucketPolicy
2025-04-08 10:51:52 -03:00
Davidson Gomes
7c7dca9da9 Merge pull request #1354 from jeffersonfelixdev/hotfix/issue-1348
Hotfix - shell injection vulnerability
2025-04-08 10:51:35 -03:00
deyvi-dev
1d2e029b54 feat(s3): add S3_SKIP_POLICY env variable to disable setBucketPolicy for incompatible providers 2025-04-07 20:23:33 -03:00
Jefferson Felix
3f8d89e970 fix: remove wildcard 2025-04-02 12:04:07 -03:00
Jefferson Felix
abda9e2113 docs: update CHANGELOG.md 2025-04-02 11:55:53 -03:00
Jefferson Felix
2a020928e8 fix: change execSync to execFileSync 2025-04-02 11:55:23 -03:00
ricocorreia1
b436e5b0b0 quando localização, conversão de degreesLatitude para string, o parametro content é do tipo string nas chamadas de findBotByTrigger() em chatbot.controller. 2025-04-01 23:26:46 -03:00
Davidson Gomes
9889035ddc Merge pull request #1344 from alvestassio/fix/multiple-files-sent-via-whatsapp
Adicionando um timestamp ao filename para possibilitar enviar o mesmo arquivo mais de uma vez na mesma conversa.
2025-03-30 12:09:01 -03:00
Davidson Gomes
07ce09d8e2 Merge pull request #1322 from marceloapd/fix/animated-stickers
Fix/animated stickers
2025-03-30 12:08:15 -03:00
Davidson Gomes
0d2a7ad50b Merge pull request #1343 from adaptwebtech/new_feature_add_send_update_message_webhook
Adicionando um novo webhook no endpoint de updateMessage
2025-03-30 12:08:03 -03:00
pedro-php
7e8044a777 lint changes 2025-03-28 11:10:48 -03:00
pedro-php
645f305cd6 fixing build error on prisma 2025-03-28 11:08:38 -03:00
pedro-php
829032dc08 lint changes 2025-03-28 10:58:32 -03:00
pedro-php
3d40b0850b lint changes 2025-03-28 10:57:59 -03:00
pedro-php
17bd108251 treating errors gracefully 2025-03-28 10:56:19 -03:00
pedro-php
f695e8bdc9 merging with develop 2025-03-28 10:36:34 -03:00
Tassio Alves
bf59ff1287 [FIX] Run lint 2025-03-27 14:36:39 -04:00
Tassio Alves
ce1680f515 [FIX] Adding a timestamp to the filename to make it possible to send the same file more than once in the same conversation. 2025-03-27 10:46:13 -04:00
pedro-php
119ceba1ca Adding a new webhook that triggers when a message is updated by the user 2025-03-27 11:13:22 -03:00
Marcelo Assis
9710fbdac4 remove animated to webp 2025-03-26 13:09:08 -03:00
Marcelo Assis
658dae0b59 lint fix 2025-03-26 10:45:09 -03:00
Davidson Gomes
b89f1144b4 Merge pull request #1334 from adaptwebtech/fix_and_add_name_to_find_chats_and_paginate_get_contacts_and_get_chats
Corrigindo um bug no endpoint de findChats e permitindo paginação nos endpoints de findChats e findContacts
2025-03-26 10:34:56 -03:00
Pedro Afonso
d196590862 Update src/api/services/channel.service.ts
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-03-25 11:17:46 -03:00
pedro-php
c5c354ffe7 fix_and_add_name_to_find_chats_and_paginate_get_contacts_and_get_chats 2025-03-25 10:52:19 -03:00
Matheus Martins Piedade
36757dddc2 Defininando TTL no userDivicesCache igual usado no Baileys 2025-03-24 15:15:45 -03:00
Marcelo Assis
027401b839 fix: normalize file extension checks for case insensitivity in sticker conversion 2025-03-20 19:13:19 -03:00
Marcelo Assis
6e7dd51679 fix: preserve animation in GIF and WebP stickers 2025-03-20 19:00:02 -03:00
Marcelo Assis
f8b1c6e0fa fix: preserve animation in GIF and WebP stickers 2025-03-20 18:37:58 -03:00
Victor Eduardo
cee2bc4d71 sending JWT token when sending webhook if jwt_key exists in webhook header record 2025-03-19 18:04:42 -03:00
Davidson Gomes
043df62a8f Merge pull request #1304 from rafwell/main
Add eventos referente a instancia que estavam faltando
2025-03-14 14:33:41 -03:00
Rafael Souza
53ae521863 Add eventos referente a instancia que estavam faltando 2025-03-10 18:11:03 -03:00
Davidson Gomes
13bdbc268c Merge pull request #1290 from jrCleber/main
Corrige validação de URL para permitir localhost e endereços IP
2025-03-06 16:59:48 -03:00
Davidson Gomes
ea9c3fbbe0 Merge pull request #1287 from pedroepif/main
fix: adjusting cloud api send audio and video
2025-03-06 16:53:05 -03:00
Cleber Wilson
22a958616d basic regex for url 2025-03-06 16:17:42 -03:00
Davidson Gomes
32cde710b8 feat: Enhance WebSocket authentication and connection handling
- Add robust authentication mechanism for WebSocket connections
- Implement API key validation for both instance-specific and global tokens
- Improve connection request handling with detailed logging
- Refactor WebSocket controller to support more secure connection validation
2025-03-06 09:17:43 -03:00
Pedro Epifanio
d9aa111800 fix: lint 2025-03-06 08:59:45 -03:00
Pedro Epifanio
fb41ab14e8 fix: adding media verification 2025-03-05 20:01:14 -03:00
Pedro Epifanio
5998fcf940 fix: adjustin cloud api send audio and video 2025-03-05 19:54:34 -03:00
Davidson Gomes
2198a86ae4 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2025-02-25 15:44:42 -03:00
Davidson Gomes
8a54efe11c feat: Add NATS integration and update Baileys service
- Create Nats table in PostgreSQL migration
- Disable message recovery logic in Baileys service
- Remove console log in instance creation route
2025-02-25 15:42:40 -03:00
Davidson Gomes
4fadf64bae Merge pull request #1264 from ygorsantana/fix/expiration-useless
Fix: Expiration being useless on awaitUser false
2025-02-22 21:03:05 -03:00
Ygor Santana
2f1df734e0 style: run lint 2025-02-22 14:17:37 -03:00
Ygor Santana
247c39fe39 fix: expiration time being useless when not awaitUser 2025-02-22 14:16:08 -03:00
Davidson Gomes
ada63b58af Merge pull request #1251 from fernandoralha/hotfix/sqs-event
fix: Refactor SQS controller to correct bug in sqs events by instance
2025-02-21 19:31:29 -03:00
Davidson Gomes
5192f49a4f Merge pull request #1259 from julianoaj/develop
 Feat: Remover a reação de uma mensagem.
2025-02-21 19:24:39 -03:00
julianoaj
48b5fd41e0 🐛 Fix: Linting requirements 2025-02-20 17:25:39 -03:00
julianoaj
5720bdc0ef Remove reaction from a message 2025-02-20 16:54:29 -03:00
Alison Juliano
ab2364b9a3 Merge pull request #1 from julianoaj/fix-1234-migration-wavoipToken-create
🐛 Corrige problema na API relacionado à migration. Fixes #1234
2025-02-18 13:36:21 -03:00
“fernandoralha”
278add6b11 fix: Refactor SQS controller to correct bug in sqs events by instance
- Implement dynamic queue creation based on enabled events - Add method to list existing queues for an instance - Improve error handling and logging for SQS operations - Remove unused queue removal methods - Update set method to handle queue creation/deletion on event changes - Add comments for future feature of forced queue deletion
2025-02-17 21:22:59 -03:00
Davidson Gomes
8f632a6f5c Merge pull request #1244 from AndersonSilvaCavalcante/hotfix/missing-wavoipToken-mysql
hotfix(migration): add missing wavoipToken column in MySQL schema
2025-02-16 13:04:29 -03:00
Anderson Cavalcante
a4ac798b43 hotfix(migration): add missing wavoipToken column in MySQL schema 2025-02-14 15:26:07 -03:00
Davidson Gomes
fc513f1d1d Merge pull request #1240 from ygorsantana/fix/list-response-message
fix: change mediaId optional chaining and list response message text obtain
2025-02-14 13:05:34 -03:00
Ygor Santana
6f1667abb5 style: run lint 2025-02-14 12:58:46 -03:00
Davidson Gomes
98b8419b8d Merge pull request #1237 from GrimBit1/main
Refactor Editing Message events and update message handler
2025-02-14 12:09:27 -03:00
Ygor Santana
59479f9a21 fix: obtain mediaUrl not defined 2025-02-13 22:35:09 -03:00
Ygor Santana
ff77bc018a fix: change mediaId optional chaining and list response message text obtain 2025-02-13 21:54:09 -03:00
Aditya Nandwana
33f7f2932d Implement message update handling in BaileysStartupService 2025-02-13 11:07:18 +05:30
Aditya Nandwana
c939ed2337 Enhance message editing validation in BaileysStartupService 2025-02-13 10:39:29 +05:30
Davidson Gomes
a49c97996c Merge pull request #1235 from julianoaj/fix-1234-migration-wavoipToken-create
🐛 Fix: Add migration for missing wavoipToken column in MySQL build env (#1234)
2025-02-12 18:23:35 -03:00
julianoaj
da72edfb03 🐛 Corrige problema na API relacionado à migration. Fixes #1234
Corrige problema na API relacionado à migration. Fixes #1234
2025-02-12 16:14:21 -03:00
Davidson Gomes
b51526aff3 Merge pull request #1226 from Desarrollo-TMS/fix-csat-chatwoot
fix: chatwoot csat creating new conversation in another language
2025-02-11 12:14:50 -03:00
Alexis Hernandez
b93ee2e023 fix: chatwoot csat creating new conversation in another language 2025-02-11 08:20:36 -04:00
Davidson Gomes
b58d9e957f Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2025-02-10 12:53:06 -03:00
Davidson Gomes
e5137e1aac Merge pull request #1221 from mbap-dev/fix-audio
Fix audio send duplicate from chatwoot.
2025-02-10 12:52:48 -03:00
mbap-dev
6b120e5da2 Fix audio send duplicate from chatwoot. 2025-02-09 20:12:40 -03:00
Davidson Gomes
342dacc398 Merge pull request #1217 from Desarrollo-TMS/feat-message-location
feat: add message location support whatsapp meta
2025-02-07 16:57:45 -03:00
Alexis Hernandez
d75c37e233 feat: add message location support meta 2025-02-07 13:04:36 -04:00
Davidson Gomes
36df38d78b Merge pull request #1215 from rafwell/main
Fix instance creation on v2.2.3
2025-02-07 12:34:32 -03:00
Davidson Gomes
68c6ad4f91 Merge pull request #1211 from joaosouz4dev/main
feat: notconvertsticket for animated stickers
2025-02-07 11:38:00 -03:00
Davidson Gomes
8685f2fdc4 Merge pull request #1214 from wayre/develop
Adicionado suporte para obter Catálogos e Coleções no WhatsApp Business
2025-02-07 11:19:11 -03:00
Rafael Souza
5a50381a8e Fix table name 2025-02-07 10:07:38 -03:00
Rafael Souza
736ca5e4b6 Fix case in table name 2025-02-07 09:52:08 -03:00
Wayre Avelar
6c1355b64b feat: Criado um novo grupo de rotas (business) para tratar dos catalogos de produtos e Coleções evitando alterações desnecessárias em arquivos do repositório 2025-02-07 00:56:49 -03:00
João Victor Souza
95401cf9b0 fix: rollback deploy_database.sh 2025-02-06 18:05:31 -03:00
João Victor Souza
0c5d28bb6c Merge branch 'main' of https://github.com/EvolutionAPI/evolution-api 2025-02-06 18:02:36 -03:00
João Victor Souza
0d1e7c08c9 feat: sendsticket notconvertsticket 2025-02-06 17:56:21 -03:00
Davidson Gomes
d665474404 feat: Add NATS integration support to the event system
- Added NATS package to dependencies
- Created Prisma schema models for NATS configuration
- Implemented NATS controller, router, and event management
- Updated instance controller and event manager to support NATS
- Added NATS configuration options in environment configuration
- Included NATS events in instance validation schema
2025-02-05 17:05:29 -03:00
Davidson Gomes
9a72b90ab2 refactor: Make RabbitMQ prefix key optional in configuration 2025-02-04 17:57:21 -03:00
Davidson Gomes
b143363c5d Merge pull request #1201 from wayre/catalogProducts
Feat: Adicionei suporte para obter o Catálogos de Produtos e as Coleções de Produtos para a versão 2.2.3
2025-02-04 09:59:59 -03:00
Wayre Avelar
56a8e09ba8 chore: eslint applied 2025-02-04 09:04:41 -03:00
Davidson Gomes
023e030802 Merge pull request #1195 from GrimBit1/main
Refactor edit and delete message functionality in BaileyStartupService
2025-02-04 06:22:49 -03:00
Wayre Avelar
e27db0612f feat: Add support to get Catalogs and Collections with new routes: '{{baseUrl}}/chat/fetchCatalogs' and '{{baseUrl}}/chat/fetchCollections' 2025-02-04 03:51:47 -03:00
Davidson Gomes
e51b6e9270 fix: improve message deduplication and edited message handling in Baileys service
- Refactor edited message detection logic
- Prevent duplicate message processing for edited messages
- Optimize message key caching mechanism
2025-02-03 17:19:07 -03:00
Davidson Gomes
867e8493aa fix: added cache to identify duplicated messages on events
- Update Docker image repository to evoapicloud/evolution-api
- Modify contact email to contato@evolution-api.com
- Update Docker Compose, Dockerfile, and workflow files
- Add Docker image badge to README
- Include additional content creator in README
- Implement message deduplication cache in Baileys service
2025-02-03 15:37:11 -03:00
Davidson Gomes
8135994340 Merge tag '2.2.3' into develop
v
2025-02-03 11:52:51 -03:00
Davidson Gomes
427c994993 Merge branch 'release/2.2.3' 2025-02-03 11:52:49 -03:00
Davidson Gomes
da74611769 version: 2.2.3 2025-02-03 11:52:37 -03:00
Aditya Nandwana
91e7a32209 Refactor createJid method in BaileysStartupService 2025-02-03 14:24:27 +05:30
Aditya Nandwana
4137984b5d Refactor message deletion in BaileysStartupService 2025-02-03 11:44:41 +05:30
Aditya Nandwana
96821f5d9a Refactor BaileysStartupService updateMessage method 2025-02-03 11:43:53 +05:30
Davidson Gomes
3c2ea5c67c feat: Re-enable group metadata caching in Baileys service
- Restore group metadata caching mechanisms
- Uncomment cache-related methods for group updates and participants
- Implement conditional group metadata retrieval based on cache configuration
2025-02-02 16:42:17 -03:00
Davidson Gomes
4a5d7a91e2 chore: Update Baileys package to latest commit hash 2025-02-02 11:39:45 -03:00
Davidson Gomes
9109b140a9 Merge pull request #1192 from tonimoreiraa/fix-dify-truncated-messages
fix(dify-service): Truncated messages (agent bot)
2025-02-01 16:11:07 -03:00
Davidson Gomes
ff5a8adc71 Merge pull request #1190 from GrimBit1/main
Fix Message deletion in Whatsapp Bailey Service
2025-02-01 16:08:56 -03:00
Davidson Gomes
b09638600e chore: Upgrade Baileys to version 6.7.12
- Update Baileys package to latest version
- Bump package version to 2.2.3
2025-02-01 15:39:14 -03:00
Toni Moreira
fc84e0f327 fix: dify truncated messages 2025-02-01 11:47:50 -03:00
Aditya Nandwana
c1494ca035 Refactor logical message deletion in BaileysStartupService 2025-02-01 16:09:08 +05:30
Davidson Gomes
7ea46a05ca version: 2.2.3 2025-01-31 17:45:09 -03:00
Davidson Gomes
f8f1cbf4a2 fix: Disable group metadata caching in Baileys service
- Remove group metadata caching mechanisms
- Modify group-related cache update methods
- Simplify group metadata retrieval process
2025-01-31 17:44:44 -03:00
Davidson Gomes
79b1c6bb1c feat: Add configurable file/cache storage for authentication state
- Update Baileys package to version 6.7.10
- Implement conditional storage mechanism for authentication state
- Add support for file-based or Redis cache storage based on environment configuration
- Re-enable previously commented out file handling utility functions
2025-01-31 17:38:42 -03:00
Davidson Gomes
169d2f797b Merge tag '2.2.2' into develop
v
2025-01-31 07:14:30 -03:00
Davidson Gomes
db9cdbfc38 Merge branch 'release/2.2.2' 2025-01-31 07:14:29 -03:00
Davidson Gomes
6afcc958c5 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2025-01-31 07:13:54 -03:00
Davidson Gomes
2166aad1d3 Merge tag '2.2.2' into develop
v
2025-01-31 07:13:30 -03:00
Davidson Gomes
14fea2f5e0 Merge branch 'release/2.2.2' 2025-01-31 07:13:25 -03:00
Davidson Gomes
9122dae262 version: 2.2.2 2025-01-31 07:13:10 -03:00
Davidson Gomes
96549664c9 Merge pull request #1179 from MarceloSoaresJr/develop
bugfix: SQL query column quoting in ChannelStartupService
2025-01-28 18:41:14 -03:00
Davidson Gomes
fa19c7fa89 feat(rabbitmq): Add prefix key configuration for queue names 2025-01-28 18:01:28 -03:00
Marcelo Soares
503728e1e7 fix: SQL query column quoting in ChannelStartupService 2025-01-27 17:42:04 -03:00
Davidson Gomes
f11e3247f0 Merge tag '2.2.1' into develop
* Retry system for send webhooks
* Message filtering to support timestamp range queries
* Chats filtering to support timestamp range queries

* Correction of webhook global
* Fixed send audio with whatsapp cloud api
* Refactor on fetch chats
* Refactor on Evolution Channel
2025-01-22 14:39:40 -03:00
Davidson Gomes
7f10a0eecd Merge branch 'release/2.2.1' 2025-01-22 14:39:27 -03:00
Davidson Gomes
a1085b4a4d version: 2.2.1 2025-01-22 14:38:50 -03:00
Davidson Gomes
b1b2d18e5d Remove redundant migration cleanup step for wavoip_token in PostgreSQL migration file. This change simplifies the migration process by eliminating unnecessary deletion of previous migration records, ensuring a cleaner migration history. 2025-01-22 12:01:17 -03:00
Davidson Gomes
37a9e316a8 Refactor database migrations and schema for Chat and Setting tables
- Removed the unique constraint on `remoteJid` and `instanceId` in the `Chat` model to prevent potential migration failures due to existing duplicates.
- Deleted the old migration file for adding `wavoipToken` to the `Setting` table and created a new migration that includes a check for the column's existence before adding it, ensuring smoother migration processes.
- Updated migration logic to clear previous migrations related to `wavoip_token` to maintain a clean migration history.
2025-01-22 11:58:34 -03:00
Davidson Gomes
f340f7716f Remove unused dependencies from ChannelController to streamline integration logic 2025-01-22 11:14:05 -03:00
Davidson Gomes
dab843f118 changelog 2025-01-22 11:09:29 -03:00
Davidson Gomes
f7db442a94 Refactor Instance Management with Additional Profile Information
- Added new fields `ownerJid`, `profileName`, and `profilePicUrl` to the Instance DTO for improved user identification and personalization.
- Updated InstanceController to include the new profile information in instance data handling.
- Enhanced WAMonitoringService to utilize the additional profile fields, improving the context of instance data during monitoring operations.
2025-01-22 11:09:05 -03:00
Davidson Gomes
3a04f7587e Refactor Evolution Channel with new instance management and media handling features
- Added `setInstance` method to manage instance details and trigger events for instance creation.
- Refactored `connectToWhatsapp` to improve error handling and streamline connection logic.
- Enhanced `sendMessageWithTyping` to support various message types including buttons and lists, and integrated file handling for media messages.
- Updated `processAudio` to handle audio conversion using an external API, improving audio processing capabilities.
- Introduced new methods for sending button messages and handling audio messages, enhancing user interaction features.
- Improved contact update logic to ensure accurate data synchronization with the database and external services.
2025-01-22 11:06:10 -03:00
Davidson Gomes
666c0b514d Chats filtering to support timestamp range queries
- Introduced a new `timestampFilter` to allow filtering messages based on `messageTimestamp` within specified `gte` and `lte` ranges.
- Updated SQL query logic in `ChannelStartupService` to incorporate the timestamp filtering, improving message retrieval accuracy.
2025-01-22 10:22:09 -03:00
Davidson Gomes
ab5eb80edd Refactor JID creation and fetch chats
- Introduced a new utility function `createJid` to standardize JID creation across the application, replacing the previous method in `ChannelStartupService`.
- Updated multiple services to utilize the new `createJid` function for improved consistency and maintainability.
- Added a `cleanMessageData` method in `ChannelStartupService` to sanitize message objects before processing.
- Updated CHANGELOG to reflect the refactor on chat fetching logic and the introduction of the new JID utility.
2025-01-22 10:16:48 -03:00
Davidson Gomes
b0219e5e5a Update version to 2.2.1, enhance database migration, and update dependencies
- Updated version labels in Dockerfile and package-lock.json to 2.2.1.
- Added a new column `wavoipToken` to the `Setting` table in the PostgreSQL migration.
- Implemented a cleanup step to remove duplicate records in the `Chat` table before creating a unique index.
- Upgraded various package dependencies to their latest versions for improved functionality and security.
2025-01-21 17:39:03 -03:00
Davidson Gomes
d7b4965d60 Update CHANGELOG for version 2.2.1
- Added features: retry system for sending webhooks and enhanced message filtering to support timestamp range queries.
- Fixed issues: corrected global webhook handling and resolved audio sending problems with WhatsApp Cloud API.
2025-01-21 17:32:24 -03:00
Davidson Gomes
cfe6bd9ae0 Refactor instance deletion logic and enhance WhatsApp connection updates
- Updated the `deleteInstance` method to allow logout for instances in 'connecting' or 'open' states, improving instance management.
- Enhanced the `BaileysStartupService` to include additional profile information (wuid, profileName, profilePictureUrl) in connection update webhooks.
- Removed redundant webhook data sending logic, streamlining connection state updates for better performance.
- Adjusted settings schema to ensure required fields are properly validated.
2025-01-17 17:54:18 -03:00
Davidson Gomes
ac58f58bbc Update package version to 2.2.1 in package.json 2025-01-17 16:07:03 -03:00
Davidson Gomes
cb08f6b152 Refactor WebhookController to implement retry logic for webhook requests
- Introduced a new `retryWebhookRequest` method to handle retries for failed webhook requests, allowing up to 10 attempts with a delay of 30 seconds between each.
- Updated error logging to provide detailed information on each retry attempt, including the attempt number and error details.
- Enhanced existing webhook request handling to utilize the new retry logic, improving reliability in sending webhook data.
- Modified error messages to be more informative, indicating when all retry attempts have failed.
2025-01-17 16:06:23 -03:00
Davidson Gomes
a817d62067 Enhance message filtering in ChannelStartupService to support timestamp range queries
- Added support for filtering messages based on a timestamp range in the `ChannelStartupService`.
- Introduced a `timestampFilter` object to handle `gte` and `lte` conditions for `messageTimestamp`.
- Updated message count queries to include the new timestamp filtering logic.
2025-01-16 17:40:19 -03:00
Davidson Gomes
540467293c Enhance settings and integrate Baileys controller for WhatsApp functionality
- Added `wavoipToken` field to `Setting` model in both MySQL and PostgreSQL schemas.
- Updated `package.json` and `package-lock.json` to include `mime-types` and `socket.io-client` dependencies.
- Introduced `BaileysController` and `BaileysRouter` for handling WhatsApp interactions.
- Refactored media type handling to use `mime-types` instead of `mime` across various services.
- Updated DTOs and validation schemas to accommodate the new `wavoipToken` field.
- Implemented voice call functionalities using the Wavoip service in the Baileys integration.
- Enhanced event handling in the WebSocket controller to support new features.
2025-01-16 11:58:33 -03:00
Davidson Gomes
616ae0a7eb Update ESLint configuration, Dockerfile, and package dependencies; add GitHub Actions workflow for code quality checks
- Changed ESLint parser options to use 'module' as source type.
- Updated Dockerfile to remove force flag from npm install command.
- Upgraded 'mime' package from version 3.0.0 to 4.0.0 in package.json.
- Added '@types/mime' as a development dependency.
- Updated TypeScript configuration to use 'CommonJS' module format.
- Introduced a new GitHub Actions workflow for checking code quality, including linting and build checks.
2025-01-09 17:04:33 -03:00
Davidson Gomes
d598c4ed0b Update ESLint configuration, Dockerfile, and package dependencies; refactor bot trigger logic
- Updated ESLint configuration to use TypeScript project references and adjusted parser options.
- Modified Dockerfile to include OpenSSL in both builder and final stages.
- Changed `mime` package version from `^4.0.6` to `^3.0.0` in `package.json` and updated TypeScript ESLint packages to `^6.21.0`.
- Refactored `findBotByTrigger` function to remove unnecessary settings repository parameter.
- Adjusted bot trigger logic in multiple controller files to streamline function calls.
2025-01-09 12:57:21 -03:00
Davidson Gomes
ca451bfacc Merge pull request #1126 from jesus-chacon/update_chats
Fix: cuid security deprecation, update libs, lint and improve chat DB update
2025-01-07 13:06:23 -03:00
Davidson Gomes
f971f388d5 Merge pull request #1134 from Allyson-Santana/bugfix/import-prisma-type
bugfix: import prisma types
2025-01-07 13:05:22 -03:00
Jesus
236b0f9b26 Fix import prisma types 2025-01-07 08:59:51 +01:00
Jesus
0f2498bbaa Fix prettier errors 2025-01-07 08:50:34 +01:00
Jesus
2816a16387 Added lock and update some libs 2025-01-07 08:50:24 +01:00
Jesus
a82669b6fa Improve chat update and fix unread messages 2025-01-07 08:25:37 +01:00
Jesus
72a33ae59f fix: lint and prettify 2025-01-07 08:25:37 +01:00
Jesus
425d340956 Fix: cuid security deprecacion 2025-01-07 08:25:37 +01:00
Jesus
f2872cf59a Update several libs 2025-01-07 08:25:37 +01:00
Allyson Santana
1773f2738e bugfix: import prisma types 2025-01-06 18:31:40 -03:00
Davidson Gomes
18626c9846 Merge pull request #1131 from FaelN1/develop
fix: include filename in media message payload for WhatsApp Business
2025-01-06 12:20:19 -03:00
Davidson Gomes
6212ee3eb0 Merge pull request #1125 from fmorett/patch-1
fix cannot read null of mentioned
2025-01-06 12:18:56 -03:00
Davidson Gomes
8c877029e5 Merge pull request #1124 from ScrashOff/fix/instance-creation-webhook-and-chatwoot-settings
fix: instance create w/webhook and chatwoot settings
2025-01-06 12:18:25 -03:00
Davidson Gomes
0000c1c05c Merge pull request #1121 from EdmilsonSantana/fix/upgrade_prima_to_6_1_0
fix: upgrade Prisma packages to 6.1.0 to resolve an issue in Alpine images
2025-01-06 12:17:29 -03:00
Davidson Gomes
16daf9be8f Merge pull request #1119 from MarksonSolutions/develop
send audio using sendWhatsAppAudio route, wabussines
2025-01-06 12:17:12 -03:00
Rafael Nicolas Barbosa Moreira
e0c960cc54 chore: remove redundant comment about filename condition 2025-01-03 16:35:14 -03:00
Rafael Nicolas Barbosa Moreira
08ceb803c8 fix: conditionally include filename for non-image media 2025-01-03 16:33:34 -03:00
Rafael Nicolas Barbosa Moreira
6b72550286 fix: include filename in media message payload for WhatsApp Business 2025-01-03 15:56:39 -03:00
Fabio Moretti
df0990df0f fix cannot read null of mentioned 2024-12-28 02:15:26 +01:00
Fellipe "ScrashOff
60c9e231be fix: instance create w/webhook and chatwoot settings 2024-12-27 16:58:15 -03:00
João Victor Souza
2fb6318011 feat: updates api evolution for docker 2024-12-27 10:40:04 -03:00
EdmilsonSantana
070159568e fix: upgrading prisma packages to 6.1.0 to fix a issue in alpine images 2024-12-26 07:59:54 -03:00
MarksonSolutions
bfba702fde send audio using sendWhatsAppAudio route, wabussines 2024-12-20 16:00:15 -04:00
Davidson Gomes
d5c2cfb4f9 Merge pull request #1103 from roberto0arruda/fix/sentry-auto-instrument-express
chore: improve instrumentSentry.ts import before another import
2024-12-11 15:38:24 -03:00
Roberto Arruda
cdab5e2ae8 chore: improve instrumentSentry.ts import before another import
Signed-off-by: Roberto Arruda <roberto0arruda@hotmail.com>
2024-12-10 12:13:42 -04:00
Davidson Gomes
682eaa995f Merge pull request #1088 from joaosantanadev/develop
[FIX]Correction of webhook global
2024-11-27 12:10:52 -03:00
Davidson Gomes
62ea22a06a Merge pull request #1076 from verbeux-ai/main
[FIX] Fixando label handler e chats
2024-11-27 12:10:31 -03:00
joaosantanadev
370025b8f9 Correction of webhook global 2024-11-25 12:59:48 -03:00
Pedro Ivo
5d13f7055b Merge remote-tracking branch 'refs/remotes/evo/develop'
# Conflicts:
#	prisma/mysql-schema.prisma
#	src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
2024-11-22 10:11:50 -03:00
Davidson Gomes
c4e87c160e Merge pull request #1078 from Richards0nd/feature/windows-commands-support
Adaptação de scripts e comandos para compatibilidade com Windows
2024-11-21 14:51:14 -03:00
Davidson Gomes
ee8e937fad Merge pull request #1073 from lucastononro/fix-prisma-p1001-dockercompose
Update docker-compose and .env.example
2024-11-21 14:49:10 -03:00
Davidson Gomes
d5a7e03ec2 Merge pull request #1012 from yousseefspires/fix/chats-messages
Add unique in Chat by instance/remotejid
2024-11-21 14:48:40 -03:00
Davidson Gomes
52b6b61ac9 Merge pull request #1071 from AlanCezarAraujo/fix/openai-audio
Correção de envio de áudio para OpenAI via Cloud API
2024-11-21 14:46:51 -03:00
Pedro Ivo
6e6711a5af fix: get instance id in right place on handle label 2024-11-19 10:26:01 -03:00
Pedro Ivo
013fa9dc08 fix: join is considering instance id 2024-11-19 10:17:49 -03:00
Pedro Ivo
a42bc988ec fix: add/remove saving on db and improve add query for startup case 2024-11-19 10:15:08 -03:00
Richards0n
3582cd38fb Add Windows support for database migration commands in package.json 2024-11-18 20:07:08 -03:00
Richards0n
bfd8c08987 Add Windows support for database deployment and improve error handling in runWithProvider.js 2024-11-18 20:01:10 -03:00
Pedro Ivo
ecbbc5b090 fix: avoid concurrency cases in label handler 2024-11-17 20:04:27 -03:00
Lucas Tonon
b7e15be418 Update docker-compose and .env.example
Error:

Database URL: 
Environment variables loaded from .env
Prisma schema loaded from prisma/postgresql-schema.prisma
Datasource "db": PostgreSQL database "evolution", schema "public" at "localhost:5432"
Error: P1001: Can't reach database server at localhost:5432

Fix:

Update `docker-compose.yaml` and `.env.example` files to configure PostgreSQL service and connection URI.

* **docker-compose.yaml**
  - Add `listen_addresses=*` command to the `postgres` service.
  - Add environment variables: `POSTGRES_USER=user`, `POSTGRES_PASSWORD=pass`, `POSTGRES_DB=evolution`, `POSTGRES_HOST_AUTH_METHOD=trust`.

* **.env.example**
  - Update `DATABASE_CONNECTION_URI` to `postgresql://user:pass@postgres:5432/evolution?schema=public`.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/EvolutionAPI/evolution-api?shareId=XXXX-XXXX-XXXX-XXXX).
2024-11-17 11:36:12 -03:00
Alan Cezar
1d5508736e corrigido o envio de áudio para OpenAI 2024-11-15 17:57:38 -03:00
Pedro Ivo
cefe3ef6c3 fix: chats must be unique 2024-11-15 17:38:26 -03:00
Davidson Gomes
09a33a423e Merge pull request #1070 from help-corretora/main
Quando a conversa está aberta e o cliente manda mensagem, o status da conversa muda para pendente.
2024-11-15 10:59:10 -03:00
Help Corretora
e092a80aeb Merge pull request #1 from vitor-help/main
erro, colocando mensagens em pendente
2024-11-14 20:50:58 -03:00
Vitor
99a533afc1 o chat está colocando a conversa como pendente quando o cliente manda mensagem, esse código visa corrigir isso. 2024-11-14 20:48:47 -03:00
Davidson Gomes
b603021f56 Merge pull request #1067 from Alexandre-Prado/fix-chatbots-send-message
fix: esvazia textBuffer dos chatbots no sendMessageWhatsapp quando splitMessages é true
2024-11-14 18:37:07 -03:00
Davidson Gomes
7bf0fd1c36 Merge pull request #1058 from Richards0nd/newPhoneNumberContent
Correção: Número de telefone apresentado no nome do contato (CW Service)
2024-11-14 18:36:43 -03:00
Davidson Gomes
52cf4fa8b8 Merge pull request #1069 from AlanCezarAraujo/fix/whatsapp-images
Correção de Imagens no Cloud API
2024-11-14 18:36:24 -03:00
Alan Cezar
ef7574273c message recorded for no media messages 2024-11-14 09:11:21 -03:00
Alan Cezar
d797d8177c added isMediaMessage method 2024-11-14 09:10:11 -03:00
Alan Cezar
e7ed1446ee saved base64 file in memory 2024-11-14 09:09:27 -03:00
Alan Cezar
5eaabfb1eb fixed messageId 2024-11-14 09:08:52 -03:00
Alan Cezar
59383d5944 fixed remoteJid 2024-11-14 09:08:23 -03:00
Alan Cezar
d87d7c0775 fixed image mime type 2024-11-14 09:07:57 -03:00
Alexandre Prado
753f4ba141 fix: chatbots send message text buffer 2024-11-14 02:25:15 -03:00
Richards0n
7ef8afa9b3 Refactor phone number formatting in ChatwootService to improve parsing logic 2024-11-11 16:57:04 -03:00
Richardson Douglas
c5fd81ddbf Merge pull request #1 from Richards0nd/develop
Develop
2024-11-11 16:49:17 -03:00
Davidson Gomes
8f855b4bfd Merge pull request #1046 from rafwell/fixMessageStatus
Fix Message.Status as String
2024-11-11 15:44:25 -03:00
Davidson Gomes
084be1cee2 Merge pull request #1044 from Richards0nd/newPhoneNumberContent
Adiciona o número de telefone do remetente nas mensagens recebidas do WhatsApp antes do nome do contato (GRUPOS)
2024-11-11 15:44:05 -03:00
Davidson Gomes
997aceeebf Merge pull request #1038 from fmedeiros95/develop
Ajuste nos tipos de mensagem respondidas
2024-11-11 15:43:49 -03:00
Rafael Souza
c8410bd146 Fix Message.Status as String 2024-11-08 07:15:23 -03:00
Richards0n
3d51b45e2b feat: format participant phone number in messages 2024-11-08 00:25:00 -03:00
Felipe Medeiros
50d84d1a08 Merge branch 'EvolutionAPI:develop' into develop 2024-11-05 17:17:15 -03:00
Felipe Medeiros
fd1f08a41e feat: handle quoted messages in WhatsApp integration 2024-11-05 17:16:41 -03:00
Davidson Gomes
8dc27919b1 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2024-11-02 08:13:04 -03:00
Davidson Gomes
6591a67ab6 feat: sh local install 2024-11-02 08:12:30 -03:00
Davidson Gomes
08192a03ca Merge pull request #1023 from adriel12319/main
Fix Ios Response Button
2024-11-01 16:10:07 -03:00
Adriel Santos Araujo
8f86c9d758 Update getConversationMessage.ts 2024-10-31 23:19:17 -03:00
Adriel Santos Araujo
0e5f9e3b77 Update getConversationMessage.ts 2024-10-31 22:52:45 -03:00
Davidson Gomes
1665654676 feat: typebot send list 2024-10-29 19:30:17 -03:00
Davidson Gomes
133eddd742 docker-compose 2024-10-29 18:22:45 -03:00
Davidson Gomes
c55312d206 feat: typebot send list 2024-10-29 17:51:06 -03:00
Davidson Gomes
52216ec08e fix: receive buttons and list response in integrations 2024-10-29 16:11:53 -03:00
Davidson Gomes
7a01cdf0ef fix: receive buttons and list response in integrations 2024-10-29 16:11:29 -03:00
Davidson Gomes
65a9c78d86 feat: typebot send buttons 2024-10-29 16:03:00 -03:00
yousseefs
f6ccd58dee some fixs 2024-10-29 18:43:31 +00:00
Davidson Gomes
fbccf2eb2a feat: send pix button 2024-10-29 10:00:32 -03:00
Davidson Gomes
23640a71b8 fix: fetch instances 2024-10-29 07:43:48 -03:00
Davidson Gomes
fce3e55e91 feat: send pix button 2024-10-29 07:36:24 -03:00
Davidson Gomes
9f39ec2110 feat: send ptv message 2024-10-28 18:02:42 -03:00
Davidson Gomes
89c4c194df Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop 2024-10-28 18:02:24 -03:00
Davidson Gomes
a4e7baa41c feat: send ptv message 2024-10-28 18:02:17 -03:00
Davidson Gomes
e22ff6c0d9 Merge pull request #1009 from yousseefspires/fix/chats-messages
fix: received messages but chat doesnt exists
2024-10-28 17:42:44 -03:00
yousseefs
11d31123ac fix: received messages but chat doesnt exists 2024-10-28 20:23:20 +00:00
Davidson Gomes
0fdc47e8f0 Merge pull request #1001 from robjean9/patch-1
FIX: Update instance.controller.ts to filter by instanceName
2024-10-28 11:13:51 -03:00
Robson Jean Penteado
60db8081bd FIX: Update instance.controller.ts to filter by instanceName
This commit should fix the filter by instanceName
2024-10-24 09:49:43 -03:00
Davidson Gomes
37b003f169 Merge pull request #1000 from fmedeiros95/develop
remove o arquivo public/images/cover (1).png:Zone.Identifier
2024-10-24 09:05:10 -03:00
Felipe Medeiros
891c3eb5d3 remove o arquivo 2024-10-24 08:52:56 -03:00
Davidson Gomes
3b99699f1a fix: var API_AUDIO_CONVERTER with default value 2024-10-22 11:29:43 -03:00
Davidson Gomes
e1de70542b feat: convert audio with api 2024-10-22 09:43:58 -03:00
Davidson Gomes
c10680df41 brand 2024-10-21 18:53:21 -03:00
Davidson Gomes
171f460f3b fix: ignoreJids in integrations dont work 2024-10-21 13:52:08 -03:00
Davidson Gomes
6d0ad5f3db feat: convert audio with api 2024-10-21 12:04:38 -03:00
Davidson Gomes
f34115fdcb feat: convert audio with api 2024-10-21 11:59:45 -03:00
Davidson Gomes
f9705c07dc feat: convert audio with api 2024-10-21 11:59:20 -03:00
Davidson Gomes
e986768716 feat: convert audio with api 2024-10-21 11:39:21 -03:00
Davidson Gomes
34769e2293 fix: receive medias on chatwoot 2024-10-18 19:49:14 -03:00
Davidson Gomes
5401ecd2c4 fix: send buttons cloud api oficial 2024-10-18 19:23:15 -03:00
Davidson Gomes
84451ba3e0 fix: receive messages on chatwoot 2024-10-18 17:43:43 -03:00
Davidson Gomes
bc751bbb6b feat: send list and buttons 2024-10-18 15:38:23 -03:00
Davidson Gomes
da77af5bd1 feat: send list and buttons 2024-10-18 15:34:22 -03:00
Davidson Gomes
1787238c63 feat: send list and buttons 2024-10-18 15:33:21 -03:00
Davidson Gomes
c4bcd1fafe Merge pull request #991 from rafaelsantana6/fix-fetch-instances
feat: add support for fetching multiple instances by key
2024-10-18 10:55:52 -03:00
Rafael Santana
ecd4b913b6 feat: add support for fetching multiple instances by key
This commit adds a new feature to fetch instances by key in the InstanceController. If the provided key does not match the environment key, the controller will search for instances with the matching token. If instances are found, the names are extracted and passed to the waMonitor to retrieve instance information.

Also, update the waMonitor's instanceInfo method to accept an array of instance names instead of a single name.

Fixes #990
2024-10-17 16:42:52 -05:00
Davidson Gomes
1aeda4e1f4 fix: ads messages in chatwoot 2024-10-17 17:40:37 -03:00
Davidson Gomes
fb1eed8beb Merge pull request #988 from Richards0nd/otimization_index_querys
Add indexes to improve performance in Evolution
2024-10-17 12:06:22 -03:00
Richards0n
287f387e82 refactor: Add indexes to improve performance in ChatwootService 2024-10-17 11:50:28 -03:00
Davidson Gomes
b18e83d293 Merge pull request #986 from deivisonrpg/refactor-onSendMessageError
refactor: Remove unnecessary code for handling contact not in WhatsApp and onSendMessageError
2024-10-17 10:17:32 -03:00
Davidson Gomes
968cc25d37 Merge pull request #983 from Richards0nd/fix
refactor: Update content_attributes in ChatwootService
2024-10-17 10:17:03 -03:00
Deivison Lincoln
b38f3cdddf Alterada outras traduções cw.message.numbernotinwhatsapp 2024-10-16 15:46:13 -03:00
Deivison Lincoln
a6fb8cbd30 refactor: Remove unnecessary code for handling contact not in WhatsApp
The code changes in `whatsapp.baileys.service.ts` remove the unnecessary code that handles the case when a contact is not in WhatsApp. The code was previously sending a notification to Chatwoot, but it is no longer needed. This change improves the code by removing unnecessary complexity.
2024-10-16 15:31:54 -03:00
Richards0n
aa8396d437 refactor: Update content_attributes in ChatwootService
This commit refactors the code in ChatwootService to update the content_attributes when replyToIds are present. Instead of directly spreading the replyToIds object, the code now converts it to a JSON string and appends it to the data object.

Refactor the code to improve readability and maintainability.
2024-10-15 18:01:57 -03:00
Davidson Gomes
ec2b7f94f8 Merge pull request #981 from yousseefspires/feat/delete-messages
feat: add logical or permanent message deletion based on env config
2024-10-15 17:44:15 -03:00
yousseefs
45acc6d281 feat: add logical or permanent message deletion based on env config 2024-10-15 20:10:59 +01:00
Davidson Gomes
b324e22d57 Merge pull request #977 from FelipeWayne/v2.0.0
(whatsapp.baileys.service.ts): adiciona novos campos de grupo na integração do WhatsApp
2024-10-14 08:04:27 -03:00
Davidson Gomes
001f4d3ca5 Merge pull request #972 from jesus-chacon/bugs/fix_last_message_fetch_chats_json
Fix last message fetch chats json
2024-10-14 08:04:12 -03:00
Felipe Augusto
aa18d13e21 (whatsapp.baileys.service.ts): adiciona novos campos de grupo na integração do WhatsApp
A inclusão dos campos isCommunity, isCommunityAnnounce e linkedParent na integração do WhatsApp permite que o serviço manipule informações adicionais sobre grupos. Isso melhora a funcionalidade e a flexibilidade do serviço, possibilitando um melhor gerenciamento e interação com grupos comunitários no WhatsApp.
2024-10-12 15:36:51 -03:00
Jesus
fa759f5da1 Fix lastMessage info for fetch chats query 2024-10-12 01:24:01 +02:00
Davidson Gomes
3af8f968c2 Add support for splitMessages and timePerChar in Integrations 2024-10-11 18:52:56 -03:00
Davidson Gomes
d8061346da update manager 2024-10-11 11:26:37 -03:00
Davidson Gomes
84df14ef93 changelog 2024-10-11 10:57:43 -03:00
Davidson Gomes
f5baced024 Merge pull request #971 from jesus-chacon/bugs/fix_fetch_chats_query
Fix fetch chats query
2024-10-11 10:56:07 -03:00
Davidson Gomes
0987fda327 Merge pull request #970 from jesus-chacon/bugs/mark_as_read_fromMe_and_groups
Mark as read from me and groups
2024-10-11 10:54:54 -03:00
Jesus
5b91648d5c Resolve read messages from groups and fromMe 2024-10-11 15:11:35 +02:00
Davidson Gomes
d50da79f22 feat: Add support for splitMessages and timePerChar in Integrations 2024-10-11 07:45:50 -03:00
Davidson Gomes
29e2cfaf96 feat: pusher event integration 2024-10-11 07:01:38 -03:00
Jesus
8ab8961e91 Fix fetch chats query 2024-10-11 08:19:51 +02:00
Davidson Gomes
f38f3e5ba5 Merge pull request #958 from jesus-chacon/features/last_message_in_chat
Added last message to fetch chats
2024-10-10 14:55:29 -03:00
Davidson Gomes
c29d20ea40 Merge pull request #967 from joaosouz4dev/v2.0.0
fix: migration update after alter
2024-10-10 14:18:55 -03:00
João Victor Souza
e19ee05e9f fix: migration update after alter 2024-10-10 13:41:07 -03:00
Davidson Gomes
68ccfb0517 Merge pull request #959 from yousseefspires/add-contextinfo-findMessages
Add ContextInfo to return in FindMessages
2024-10-09 17:07:42 -03:00
Davidson Gomes
7cb5d10fc9 Merge pull request #957 from fmedeiros95/v2.0.0
Escutar a configuração do webhook para midias recebidas
2024-10-09 17:03:41 -03:00
Youssef
ab0fedf484 Merge pull request #1 from yousseefspires/add-contextinfo-findMessages
Add ContextInfo to return in FindMessages
2024-10-08 16:41:22 +01:00
Youssef
5fcdf5aeaf Update channel.service.ts 2024-10-08 16:39:18 +01:00
Jesus
394c091810 Fix parse multiples messages updates and creates 2024-10-08 17:15:53 +02:00
Jesus
73e732bf24 Added last message to fetch chats 2024-10-08 12:51:34 +02:00
Jesus
c6ee463dae Improve update messages status 2024-10-08 12:51:10 +02:00
Jesus
cada7be1e5 Add last_message to fetchChats query 2024-10-08 08:47:08 +02:00
Jesus
eb456f6a88 Fix unreadMessages for fetchChats query 2024-10-08 08:08:33 +02:00
Felipe Medeiros
7adab5c1c0 Escutar a configuração do webhook para midias recebidas 2024-10-07 19:14:21 -03:00
Davidson Gomes
f5f778ecbe feat: Added unreadMessages to chats 2024-10-07 13:45:19 -03:00
Davidson Gomes
f2bb01a640 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-10-07 13:37:56 -03:00
Davidson Gomes
2f1ba83546 Merge pull request #954 from jesus-chacon/features/unread_messages
Added unreadMessages to chats
2024-10-07 13:37:50 -03:00
Jesus
10aeeebb53 Fix and improve fetch chats 2024-10-07 18:03:27 +02:00
Jesus
96e1802148 Fix update message condition 2024-10-07 17:54:25 +02:00
Jesus
27dc49f2c3 Fix unread for chat creation 2024-10-07 17:41:43 +02:00
Jesus
edb3875b91 Added unreadMessages to chats 2024-10-07 17:39:00 +02:00
Davidson Gomes
ac3b18678e Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-10-07 11:07:42 -03:00
Davidson Gomes
49edd174a9 Merge pull request #953 from fmedeiros95/v2.0.0
refactor: remove a função "offerCall" do controller sendMessage
2024-10-07 11:07:29 -03:00
Felipe Medeiros
4d33ad3aef Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-10-07 11:05:43 -03:00
Felipe Medeiros
3511082511 Merge branch 'v2.0.0' of https://github.com/fmedeiros95/evolution-api into v2.0.0 2024-10-07 11:05:20 -03:00
Felipe Medeiros
23abcbecd3 refactor: remove a função "offerCall" do controller sendMessage 2024-10-07 11:05:17 -03:00
Davidson Gomes
87fe8c2b3c Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-10-07 11:02:13 -03:00
Davidson Gomes
eee43bb073 Merge pull request #952 from fmedeiros95/v2.0.0
Adiciona a função de fake call
2024-10-07 11:02:06 -03:00
Felipe Medeiros
51a3710b46 Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-10-07 10:55:41 -03:00
Felipe Medeiros
0aa8150070 Update dependency: baileys
The package.json file was updated to use the latest version of the baileys dependency from the EvolutionAPI repository.
2024-10-07 10:55:21 -03:00
Felipe Medeiros
8e8a3db529 Merge branch 'v2.0.0' of https://github.com/fmedeiros95/evolution-api into v2.0.0 2024-10-07 10:49:55 -03:00
Felipe Medeiros
bcf59a2015 feat: adiciona controlador de chamadas
Adiciona o controlador de chamadas para oferecer chamadas falsas.

- Adiciona o arquivo `call.controller.ts` com a classe `CallController` que possui o método `offerCall` para oferecer chamadas falsas.
- Adiciona o arquivo `call.dto.ts` com as classes `Metadata` e `OfferCallDto` para definir os dados da chamada.
- Atualiza o arquivo `sendMessage.dto.ts` removendo a classe `OfferCallDto`.
- Atualiza o arquivo `whatsapp.baileys.service.ts` importando a classe `OfferCallDto` corretamente e atualizando o método `offerCall` para receber os parâmetros corretos.
- Adiciona o arquivo `call.router.ts` com a classe `CallRouter` para lidar com as rotas relacionadas a chamadas.
- Atualiza o arquivo `index.router.ts` para incluir as rotas relacionadas a chamadas.
2024-10-07 10:49:51 -03:00
Davidson Gomes
e66f877b4c fix: migrations 2024-10-07 10:49:26 -03:00
Davidson Gomes
aac8d446b4 changelog 2024-10-07 10:42:01 -03:00
Davidson Gomes
a0a62b997c Merge pull request #951 from lucas-tomasi/patch-1
Fix duplicate file upload
2024-10-07 10:41:10 -03:00
Felipe Medeiros
070840d364 Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-10-07 01:33:13 -03:00
Felipe Medeiros
0af00582f0 refactor: simplifica a lógica de terminação de chamada 2024-10-07 01:30:03 -03:00
Felipe Medeiros
b80b203670 feat: adiciona a funcionalidade de fake call 2024-10-07 01:13:02 -03:00
Davidson Gomes
29a1d99d05 fix: Fixed prefilledVariables in startTypebot 2024-10-06 20:05:14 -03:00
Lucas Tomasi
2e43683835 Fix duplicate file upload
Currently, we face an issue when a file with the same name is uploaded more than once:
1.⁠ ⁠It results in a unique key error in the database.
2.⁠ ⁠If the file is sent to S3, it overwrites the old file.

To resolve this problem, I've implemented a solution where we concatenate the message ID to the filename. This approach ensures uniqueness for each uploaded file, even if users upload files with identical names multiple times in a chat.


This change allows normal users to upload files with the same name multiple times in a chat without encountering errors or unintended file overwrites.
2024-10-06 15:42:17 -03:00
Davidson Gomes
ebbba7b7e9 version: 2.1.2 2024-10-06 10:10:00 -03:00
Davidson Gomes
c823f84c70 fix: status on send message 2024-10-06 10:04:02 -03:00
Davidson Gomes
0f7c2437bc fix: status on send message 2024-10-06 09:58:57 -03:00
Davidson Gomes
1f6473cfd5 version: 2.1.2 2024-10-06 09:47:42 -03:00
Davidson Gomes
db7428abd9 Merge pull request #949 from nestordavalos/v2.0.0
fix: Corrected audio file handling in WhatsApp
2024-10-06 09:27:27 -03:00
nestordavalos
59af93251d fix: Corregir manejo de archivo de audio en WhatsApp 2024-10-06 01:16:08 -03:00
nestordavalos
83567d6466 fix: Corrected audio file handling in WhatsApp
An error in the WhatsApp audio message handler has been fixed. The system now checks if the file has a valid buffer before sending it. Additionally, validation has been added to verify if the audio is a valid URL or Base64. If these conditions are not met, an error message is shown, and a BadRequestException is thrown.
2024-10-05 22:49:30 -04:00
Davidson Gomes
d7ddb99fb0 fix: Fixed bot fallback not working on integrations 2024-10-04 19:08:23 -03:00
Davidson Gomes
2d732c8071 fix: Does not search message without chatwoot Message Id for reply 2024-10-04 18:52:56 -03:00
Davidson Gomes
0d2125ddff fix: Does not search message without chatwoot Message Id for reply 2024-10-04 18:52:32 -03:00
Davidson Gomes
0791e1afe9 fix: Fixed bug when send message when dont have mentionsEveryOne on payload 2024-10-04 18:33:08 -03:00
Davidson Gomes
fcfa96d97d fix: Fixed bug when send message when dont have mentionsEveryOne on payload 2024-10-04 18:33:01 -03:00
Davidson Gomes
01ae55f02a fix: Fixed getBase64FromMediaMessage with convertToMp4 2024-10-04 18:27:25 -03:00
Davidson Gomes
97f633a69a fix: fixed issue of always creating a new label when saving chatwoot 2024-10-04 17:51:47 -03:00
Davidson Gomes
5c046d51c5 fix: fixed issue of always creating a new label when saving chatwoot 2024-10-04 17:51:32 -03:00
Davidson Gomes
487d8b93fb fix: startTypebot with startSession = true 2024-10-04 17:40:38 -03:00
Davidson Gomes
db065ab942 fix: send media message in chatwoot 2024-10-04 17:14:12 -03:00
Davidson Gomes
373268c938 fix: send message to group without no cache (local or redis) 2024-10-04 16:23:09 -03:00
Davidson Gomes
fcc26f931e Merge pull request #947 from oismaelash/v2.0.0
fix: send message to group without no cache (local or redis)
2024-10-04 16:19:34 -03:00
oismaelash
2037e78045 fix: send message to group without no cache (local or redis) 2024-10-04 16:05:49 -03:00
Davidson Gomes
161abf1d03 feat: send media with form-data 2024-10-04 14:55:21 -03:00
Davidson Gomes
ec2d7e349f feat: send media with form-data 2024-10-04 14:45:16 -03:00
Davidson Gomes
44e152bea2 license: license terms updated 2024-10-04 13:27:46 -03:00
Davidson Gomes
9083bf44fe readme 2024-10-04 12:55:00 -03:00
Ismael Ash
7b41d333d7 Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-10-04 06:18:31 -03:00
oismaelash
0a4b8d202a fix: transform any string on number to Lower Case, for not show reading id of undefined 2024-10-04 00:41:19 -03:00
Davidson Gomes
d84713f6ca license: license terms updated 2024-10-03 18:14:52 -03:00
Davidson Gomes
d1bc0e6150 fix: adjusts on prisma connections 2024-10-03 17:59:40 -03:00
Davidson Gomes
14d10c00ec chore: chatwoot verbose logs 2024-10-03 17:40:21 -03:00
Davidson Gomes
88c1830bf5 fix: timeout error on send status message 2024-10-03 17:22:52 -03:00
Davidson Gomes
23549e3c1f chore: update baileys version 2024-10-03 16:56:13 -03:00
Davidson Gomes
1ded6c81ad chore: Set the maximum number of listeners that can be registered for events 2024-10-03 16:46:50 -03:00
Davidson Gomes
7ca9bff6e0 fix: mexico number 2024-10-03 16:36:42 -03:00
Davidson Gomes
4fa3c50138 fix: mexico number 2024-10-03 16:36:28 -03:00
Davidson Gomes
14df0b368b changelog 2024-10-03 16:34:32 -03:00
Davidson Gomes
8dee8a1ec0 Merge pull request #944 from oismaelash/v2.0.0
fix: buildkey function in hSet and hDelete
2024-10-03 16:33:47 -03:00
Ismael Ash
acad895c9d Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-10-03 15:09:53 -03:00
oismaelash
49327593a9 fix: buildkey function in hSet and hDelete 2024-10-03 14:44:46 -03:00
Davidson Gomes
567152184c fix: openai setting when send a message with chatwoot 2024-10-03 14:28:47 -03:00
Davidson Gomes
0d8982395f fix: openai setting when send a message with chatwoot 2024-10-03 14:28:31 -03:00
Davidson Gomes
479dc12f28 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-10-03 14:24:29 -03:00
Davidson Gomes
182c5fc25e change version 2024-10-03 14:23:10 -03:00
Davidson Gomes
f16e9bc60f changelog 2024-10-03 08:38:13 -03:00
Davidson Gomes
10174069e0 Merge pull request #937 from oismaelash/v2.0.0
update: docker with expose port and localcache hGet and hSet return null
2024-10-03 08:35:17 -03:00
Davidson Gomes
e146921e53 Merge pull request #936 from vagners2/v2.0.0-fix-migrations
fix: add migration field message status
2024-10-03 08:34:58 -03:00
Davidson Gomes
449a3b2252 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-10-03 08:33:31 -03:00
Davidson Gomes
efbb32ff0c fix: fetch status message 2024-10-03 08:32:45 -03:00
oismaelash
0ad330bdb3 add: hDelete on LocalCache 2024-10-02 15:15:12 -03:00
oismaelash
9a6d4a8e44 add: hGet and hSet on LocalCache 2024-10-02 14:55:34 -03:00
oismaelash
0b40583fa8 fix: environment variables with optional #1 2024-10-02 12:39:11 -03:00
oismaelash
fe4a439fde fix: environment variables with optional 2024-10-02 12:24:33 -03:00
oismaelash
58a8d92c37 DATABASE_PROVIDER default is posttgresql #1 2024-10-02 01:33:20 -03:00
oismaelash
185fb587e0 DATABASE_PROVIDER default is posttgresql 2024-10-02 01:25:40 -03:00
oismaelash
5829762f91 update: docker with expose port and localcache hGet and hSet return null 2024-10-02 00:13:00 -03:00
vagnersantos
af56b06f50 fix: add migration field message status 2024-10-01 15:11:36 -03:00
Davidson Gomes
168c5f18d8 Merge pull request #926 from lopesfontana/v2.0.0-contacts_pushName
V2.0.0 contacts push name
2024-09-28 07:32:20 -03:00
Andre Fontana
510eaf1141 Adjust contact pushName. Not save when in message.upsert and the pushName is from the instance name 2024-09-27 15:03:17 -03:00
Andre Fontana
1e5d62c777 Adjust contact pushName. Not save when in message.upsert and the pushName is from the instance name 2024-09-27 15:01:35 -03:00
Andre Fontana
ca2387cc70 Adjust contact pushName. Not save when in message.upsert and the pushName is from the instance name 2024-09-27 14:49:58 -03:00
Davidson Gomes
0ff421121f Merge pull request #918 from judsonjuniorr/fix/validate-message-before-sending-chatwoot
Fix/validate message before sending chatwoot
2024-09-27 14:02:58 -03:00
Davidson Gomes
8789f9bc97 Merge pull request #917 from judsonjuniorr/feat/sync-lost-messages-chatwoot
feat: Sync lost messages on chatwoot
2024-09-27 14:01:41 -03:00
Davidson Gomes
d535bc4ea2 Merge pull request #906 from fmedeiros95/v2.0.0
feat: adiciona o status da mensagem no retorno da função "prepareMessage"
2024-09-27 14:00:20 -03:00
Judson Cairo
f35f8dd7e0 feat: Update the cw message with the wpp time 2024-09-27 13:56:52 -03:00
Judson Cairo
f9726863ef feat: Update chatwoot source ID and status after sent 2024-09-27 09:40:18 -03:00
Judson Cairo
49ceb44102 fix: Validate if chatwoot connection is available 2024-09-25 13:07:20 -03:00
Judson Cairo
f54a00a07f fix: Validate if source id already exists in chatwoot
Check if message is already saved before sending it
2024-09-25 11:56:51 -03:00
Judson Cairo
e241cf4ee0 feat: Sync lost messages on chatwoot
Runs the sync method every 30min
2024-09-25 11:48:19 -03:00
Felipe Medeiros
59fac8bc4a Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-09-23 20:54:31 -03:00
Felipe Medeiros
68b5d8db4d feat: adiciona o status da mensagem no retorno da função "prepareMessage" 2024-09-22 17:48:16 -03:00
Davidson Gomes
4ca141b4f4 version: 2.1.1 2024-09-22 10:32:00 -03:00
Davidson Gomes
d3b229c6a1 fix: settings on dify, flowise and openai 2024-09-22 10:11:31 -03:00
Davidson Gomes
ffac87835b fix: settings on dify, flowise and openai 2024-09-22 10:10:36 -03:00
Davidson Gomes
726b0dcbb2 changelog 2024-09-22 09:06:10 -03:00
Davidson Gomes
5ebebbf211 fix: chatbot integrations send media and links 2024-09-22 08:53:10 -03:00
Davidson Gomes
3527e662e1 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-09-21 18:53:59 -03:00
Davidson Gomes
2b3062222a changelog 2024-09-21 18:53:44 -03:00
Davidson Gomes
495b50f933 Merge pull request #904 from olaronymax/patch-1
Visualização Única no ChatWoot
2024-09-21 18:44:14 -03:00
OlaRonyMax
ae69eb0bce Visualização única no ChatWoot
Permite receber imagens e vídeos de visualização unica direto no  ChatWoot
2024-09-21 16:26:35 -03:00
Davidson Gomes
cecbf59f46 clear console logs 2024-09-21 13:42:23 -03:00
Davidson Gomes
d3f90a7abd fix: chatwoot integration 2024-09-21 13:41:51 -03:00
Davidson Gomes
4e4caab970 fix: chatwoot integration 2024-09-21 12:34:40 -03:00
Davidson Gomes
154dd4e9ba Merge pull request #902 from fmedeiros95/v2.0.0
refactor: padroniza tratamento de mensagens no Baileys
2024-09-20 18:44:05 -03:00
Felipe Medeiros
79170b8f01 refactor: padroniza as mensagens salvas no banco 2024-09-20 18:41:01 -03:00
Davidson Gomes
adfe2977ef Merge pull request #901 from fmedeiros95/v2.0.0
refactor: simplifica e padroniza envio de mensagens no Baileys
2024-09-20 17:46:39 -03:00
Felipe Medeiros
92373812c1 refactor: simplifica função sendMessage no Baileys
- Remove lógica duplicada de salvar mensagens no banco de dados e upload de mídia para o S3
- Padroniza o retorno da função, utilizando "messageRaw"
- Simplifica a validação da instância
- Elimina a verificação de configuração do S3 para envio de mídias
2024-09-20 17:37:37 -03:00
Felipe Medeiros
0544d80cbd refactor: padroniza retorno da função sendMessage no Baileys
Ajusta o retorno da função "sendMessage" para usar a variável "messageRaw" em vez de "messageSent", garantindo consistência no retorno.
2024-09-20 17:32:39 -03:00
Davidson Gomes
76fe717076 Merge pull request #894 from judsonjuniorr/fix/typebot-settings-for-ignore-jid
Fix ignoreJids on typebot
2024-09-19 12:54:33 -03:00
Judson Cairo
aeb422b3f7 Fix ignoreJids on typebot 2024-09-18 21:47:37 -03:00
Davidson Gomes
17313d45f9 Merge pull request #886 from judsonjuniorr/fix/instance-validation
Validate if instance exists before deleting it
2024-09-17 07:28:27 -03:00
Judson Cairo
6b447c654f Fix instance validation condition 2024-09-16 10:36:27 -03:00
Judson Cairo
ff98d0724e Validate if instance exists before deleting it 2024-09-12 18:43:29 -03:00
Davidson Gomes
9a1d5664c9 Merge pull request #883 from vidz1979/debounce-message-break
Debounce message break
2024-09-12 15:08:52 -03:00
Davidson Gomes
f5fbf73139 Merge pull request #882 from FaelN1/v2.0.0
refactor: refatora tratamento do tipo de mensagem para interativas, de botão e de contato
2024-09-12 15:07:43 -03:00
Davidson Gomes
ade5f8d122 Merge pull request #880 from joaosouz4dev/v2.0.0
fix: clean instance without chatwoot
2024-09-12 15:04:53 -03:00
Junior Vidotti
7fa41a4d4c removed docker-compose version as long it is obsolete 2024-09-11 22:18:30 +00:00
Junior Vidotti
c8b36a2401 reversed settings 2024-09-11 22:00:57 +00:00
Junior Vidotti
9fcb1e8829 reversed settings 2024-09-11 22:00:23 +00:00
Junior Vidotti
83f87bc1c5 debounce message break 2024-09-11 21:58:46 +00:00
Rafael Nicolas Barbosa Moreira
55a3e59fa5 refactor: refatora tratamento do tipo de mensagem para interativas, de botão e de contato 2024-09-11 17:31:10 -03:00
Davidson Gomes
2947269c4e Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-09-11 17:20:20 -03:00
Davidson Gomes
599560bdd7 fix: It is now possible to send images via the Evolution Channel 2024-09-11 17:20:07 -03:00
João Victor Souza
a84bc18dea Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0 2024-09-11 11:04:37 -03:00
João Victor Souza
918cf295ad fix: clean instance without chatwoot 2024-09-11 11:03:38 -03:00
Davidson Gomes
1ef379baf7 Merge pull request #878 from diegomustafamarino/v2.0.0
Update Facebook / Instagram ADS for whatsapp integration
2024-09-11 09:40:07 -03:00
Diego Marino
d183990732 Update getConversationMessage.ts 2024-09-10 22:55:03 -03:00
Davidson Gomes
9f30c7b160 changelog 2024-09-09 10:43:00 -03:00
Davidson Gomes
bfcf99bba0 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-09-09 10:12:19 -03:00
Davidson Gomes
80ae86b298 fix: chatwoot screen 2024-09-09 10:12:10 -03:00
Davidson Gomes
63dac9d04f Merge pull request #869 from fmedeiros95/v2.0.0
feat: adds headers to the instance's webhook registration
2024-09-07 10:28:03 -03:00
Felipe Medeiros
65c6ecff88 feat: adiciona headers no cadastro de webhook da instância 2024-09-06 20:46:10 -03:00
Davidson Gomes
c20a3b643f fix: no response evolution bot 2024-09-05 20:52:46 -03:00
Davidson Gomes
a9e4860a77 Merge pull request #868 from judsonjuniorr/v2-fix-chatwoot-quote
Fix chatwoot not mentioning the quoted message
2024-09-05 09:31:32 -03:00
Judson Cairo
16a0e6b18e Fix chatwoot not mentioning the quoted message 2024-09-05 09:28:57 -03:00
Davidson Gomes
49410d7d5e Merge pull request #866 from EvolutionAPI/revert-862-v2-fix-chatwoot-reply-quote
Revert "V2 fix chatwoot reply quote"
2024-09-05 09:26:44 -03:00
Davidson Gomes
ff78954383 Revert "V2 fix chatwoot reply quote" 2024-09-05 09:26:33 -03:00
Davidson Gomes
2c7288e888 Merge pull request #865 from judsonjuniorr/v2-rabbitmq-exchange-name
Use exchange name from .env
2024-09-05 09:20:55 -03:00
Davidson Gomes
a97a01e0aa Merge pull request #864 from judsonjuniorr/v2-on-whatsapp-return
Fix on whatsapp number return
2024-09-05 09:20:29 -03:00
Davidson Gomes
18ccccf344 Merge pull request #862 from judsonjuniorr/v2-fix-chatwoot-reply-quote
V2 fix chatwoot reply quote
2024-09-05 09:18:00 -03:00
Judson Cairo
65debe5a95 Use exchange name from .env 2024-09-04 17:09:42 -03:00
Judson Cairo
672bdc1cc7 Fix on whatsapp number return 2024-09-04 17:05:07 -03:00
Judson Cairo
71289fb919 Fix chatwoot not mentioning the quoted message 2024-09-04 15:38:11 -03:00
Judson Cairo
b93725dd32 Merge branch 'v2.0.0' into v2 2024-09-04 13:24:12 -03:00
Davidson Gomes
2784b907b0 fix: use chatwoot with evolution channel 2024-09-03 17:23:18 -03:00
Davidson Gomes
25daec9f41 fix: use chatwoot with evolution channel 2024-09-03 17:23:05 -03:00
Davidson Gomes
849d5f79dc fix: sentry version 2024-09-03 16:53:23 -03:00
Davidson Gomes
73727da867 fix: upload media s3 on waba 2024-09-03 14:41:39 -03:00
Davidson Gomes
401770be1c Merge pull request #852 from paulillo/fix-wpp-biz-api-upload-media-s3
Fix wpp biz api upload media s3
2024-09-03 14:40:50 -03:00
Davidson Gomes
acd4100b23 fix: fixed bugs in the frontend, on the event screens 2024-09-03 13:09:42 -03:00
Júlio Paulillo
b0aa299850 Hotfixes attribution 2024-09-03 12:25:02 -03:00
Júlio Paulillo
1db339c65f Declares instanceDto.chatwootAutoCreate 2024-09-03 12:13:30 -03:00
Júlio Paulillo
fed49c2072 Fixes wrong message type lookup 2024-09-02 20:39:11 -03:00
Davidson Gomes
5f86f01e3a Merge pull request #849 from robsoncombr/v2.0.0-robsoncombr-fix-missing-autoCreate
v2.0.0-robsoncombr-fix-missing-autoCreate
2024-09-02 09:38:41 -03:00
Davidson Gomes
951da04373 Merge pull request #839 from judsonjuniorr/v2-is-on-whatsapp-cache
Save is on whatsapp on the database
2024-09-02 09:37:25 -03:00
Judson Cairo
1161a8a0e2 Await chatwoot creation and change log to error 2024-09-01 16:46:09 -03:00
Judson Junior
2cb68b38a9 Merge pull request #20 from robsoncombr/v2.0.0-robsoncombr-fix-missing-autoCreate
v2.0.0-robsoncombr-fix-missing-autoCreate
2024-09-01 16:42:26 -03:00
Robson Martins
265cba9e3e v2.0.0-robsoncombr-fix-missing-autoCreate 2024-08-31 23:32:15 -03:00
Judson Junior
f17bb4ec42 Merge pull request #19 from EvolutionAPI/v2.0.0
changelog
2024-08-31 21:35:52 -03:00
Judson Cairo
4cdf76f381 Refactor database table name for IsOnWhatsapp 2024-08-30 16:37:20 -03:00
Davidson Gomes
f0840e07fe changelog 2024-08-30 11:38:41 -03:00
Judson Junior
47d56f9c52 Merge pull request #18 from judsonjuniorr/v2-is-on-whatsapp-cache
V2 is on whatsapp cache
2024-08-30 10:38:55 -03:00
Judson Junior
ed5ff089c5 Merge pull request #17 from EvolutionAPI/v2.0.0
V2.0.0
2024-08-30 10:32:44 -03:00
Davidson Gomes
256bd3ef73 Merge pull request #838 from judsonjuniorr/v2-fix-cache-errors
Validate if cache exists before accessing it
2024-08-30 09:39:13 -03:00
Davidson Gomes
09eaba99c0 Merge pull request #836 from chatwoot-br/next
feat: Define a global proxy to be used if the instance does not have one
2024-08-30 09:38:57 -03:00
Judson Cairo
a57842519b Change tables & columns maps 2024-08-29 15:45:42 -03:00
Judson Cairo
011bef3daf Testing docker-compose 2024-08-29 15:12:36 -03:00
Judson Cairo
2fc0815e14 Removed empty lines on cacheengine 2024-08-29 15:12:01 -03:00
Judson Cairo
5ac98f7278 Add typescript path to vscode settings 2024-08-29 15:11:50 -03:00
Judson Cairo
8b5ca0c9c4 Add DIRECT_URI on env and prisma 2024-08-29 15:10:04 -03:00
Judson Cairo
c63cb23433 Create bun.lockb 2024-08-29 15:09:46 -03:00
Judson Cairo
41342f39de Removed redis cache from is on whatsapp 2024-08-28 17:29:01 -03:00
Judson Cairo
49806cf47e Avoid duplicate search
If already found on redis ignore database
2024-08-28 13:33:33 -03:00
Judson Cairo
7468ae9169 Removed unused variable from .env 2024-08-28 13:30:11 -03:00
Judson Cairo
7a76600cd6 Added redis cache for on whatsapp & TTL on .env 2024-08-28 12:11:32 -03:00
Judson Cairo
ce6438b9a8 Save is on whatsapp on the database 2024-08-28 11:19:47 -03:00
Judson Cairo
a19343d3e1 Validate if cache exists before accessing it 2024-08-28 09:59:40 -03:00
@milesibastos
0989f8a3ad feat: Define a global proxy to be used if the instance does not have one 2024-08-27 21:01:48 -03:00
Davidson Gomes
3b9761992a Merge pull request #832 from deivisonrpg/change-cache-logs-level
[Proposta] Alterar level dos logs do cache para verbose
2024-08-27 17:32:42 -03:00
Deivison Lincoln
b19c5375e5 [Proposta] Alterar level dos Logs do cache para verbose 2024-08-27 14:01:26 -03:00
Davidson Gomes
cb865bf5a0 Merge pull request #826 from yantxs/adjust-redis-compose
add network on redis docker compose
2024-08-27 08:37:42 -03:00
Davidson Gomes
bb89816ca6 Merge pull request #825 from yantxs/fix-dify-chunks
Fixed integration with Dify agents
2024-08-27 08:37:28 -03:00
Yan Teixeira
c7281cbdea add network on redis docker compose 2024-08-27 01:40:24 -03:00
Yan Teixeira
a44aa1f646 remove whitespaces 2024-08-27 01:34:25 -03:00
Yan Teixeira
d712cbc467 fix agents dify integration 2024-08-27 01:20:02 -03:00
Davidson Gomes
fc786c54f5 changelog 2024-08-26 15:35:39 -03:00
Davidson Gomes
b8d6e55fba fix: change answer to message on Evolution Bot 2024-08-26 15:32:44 -03:00
Davidson Gomes
d776770d09 refactor: evolution bot 2024-08-25 10:22:22 -03:00
Davidson Gomes
8b7ff37261 changelog 2024-08-24 14:58:14 -03:00
Davidson Gomes
c531906de2 fix: duplicated bot when use startTypebot 2024-08-24 14:57:54 -03:00
Davidson Gomes
e8fa952de5 fix: update description on chatbots 2024-08-24 14:36:00 -03:00
Davidson Gomes
d7049e798c changelog 2024-08-24 13:32:47 -03:00
Davidson Gomes
238c332df5 fix: get integrations sessions by type 2024-08-24 13:20:30 -03:00
Davidson Gomes
aeea61ef4b fix: get integrations sessions by type 2024-08-24 13:18:58 -03:00
Davidson Gomes
a90617fa0c fix: dockerfile 2024-08-24 08:39:33 -03:00
Davidson Gomes
a9c737da3f fix: chatbot services 2024-08-24 08:01:42 -03:00
Davidson Gomes
25959ad143 fix: manager 2024-08-24 07:50:31 -03:00
Davidson Gomes
c00f46b105 changelog 2024-08-24 07:48:51 -03:00
Davidson Gomes
2344dfc22f fix: chatbot services 2024-08-24 07:44:23 -03:00
Davidson Gomes
25cbe3a035 license: change in license to apache-2.0 2024-08-24 07:27:06 -03:00
Davidson Gomes
b546e56eea Merge pull request #814 from diegomustafamarino/v2.0.0
Receive data from Meta ADS ( facebook, instagram ), excluding Chatwoot that already haves.
2024-08-24 07:21:40 -03:00
Diego Marino
aa79409d44 Implement externalAdReplyBody for Meta Ads
Receive Instagram/Facebook Ads messages for recognizing in messages to use in Dify(example).
2024-08-23 21:35:41 -03:00
Diego Marino
f6b3612c3d Merge remote-tracking branch 'upstream/v2.0.0' into v2.0.0 2024-08-23 21:25:10 -03:00
Davidson Gomes
5d6a34ad3f fix: websocket emit 2024-08-23 16:57:44 -03:00
Davidson Gomes
1b9fec6c27 fix: s3 saving media sent from me 2024-08-23 15:48:34 -03:00
Davidson Gomes
e809f38865 fix: fixed send messages in groups 2024-08-23 15:36:59 -03:00
Davidson Gomes
0fca8c0746 fix: set events 2024-08-23 14:56:33 -03:00
Davidson Gomes
d7b3230db9 break change: fix breakchange events in manager 2024-08-23 14:30:48 -03:00
Davidson Gomes
fcdee75f39 fix: set webhook 2024-08-23 14:24:32 -03:00
Davidson Gomes
ca503b49c6 changelog 2024-08-23 14:13:54 -03:00
Davidson Gomes
1f0a5a2e09 fix: fixed proxy config in manager 2024-08-23 14:05:48 -03:00
Davidson Gomes
6a62ae85fc refactor: integration folders and fix manager bugs 2024-08-23 13:46:51 -03:00
Davidson Gomes
beafc62403 refactor: integration folders 2024-08-23 13:20:18 -03:00
Davidson Gomes
a08ca7a67d Merge pull request #812 from stenioanibal/v2.0.0
Simplify events structure - V2.0.0
2024-08-23 11:54:17 -03:00
Stênio Aníbal
9418faff30 Merge branch 'ev2' into v2.0.0 2024-08-23 11:41:28 -03:00
Stênio Aníbal
99161de094 Fix intrinsic type issues on chatbot controllers 2024-08-23 11:41:14 -03:00
Davidson Gomes
c3c1ffe7e5 fix: manager translate 2024-08-23 11:10:55 -03:00
Stênio Aníbal
03c32de743 Merge branch 'ev2' into v2.0.0 2024-08-23 10:56:17 -03:00
Stênio Aníbal
05ee65f422 Simplify events structure and fix minor issues 2024-08-23 10:53:31 -03:00
Davidson Gomes
6328c64192 fix: messageType null 2024-08-23 08:35:00 -03:00
Davidson Gomes
fcc4fc2665 fix: dockerfile 2024-08-23 08:07:04 -03:00
Davidson Gomes
a83a358620 refactor: channel integration folders 2024-08-23 07:55:26 -03:00
Davidson Gomes
fff11ea452 fix: update baileys version 2024-08-22 23:08:42 -03:00
Diego Marino
9099adf363 Merge remote-tracking branch 'upstream/v2.0.0' into v2.0.0 2024-08-22 21:33:55 -03:00
Davidson Gomes
e77a974b59 fix: whatsapp web version on .env 2024-08-22 20:18:50 -03:00
Davidson Gomes
0e9cd21981 feat: evolution channel in instance create 2024-08-22 19:49:51 -03:00
Davidson Gomes
2196f65b7a fix: dify agent integration 2024-08-22 18:15:30 -03:00
Davidson Gomes
e9f4477d11 feat: flowise integration 2024-08-21 17:33:45 -03:00
Davidson Gomes
0e6a78d011 feat: flowise integration 2024-08-21 17:21:23 -03:00
Davidson Gomes
61523c0a79 feat: generic chatbot 2024-08-21 16:37:24 -03:00
Davidson Gomes
891d00ccba changelog 2024-08-21 16:22:56 -03:00
Davidson Gomes
e0ac6ab5d5 Merge pull request #803 from stenioanibal/v2.0.0
Improvements for events management and Chatwoot integration - V2.0.0
2024-08-21 16:21:31 -03:00
Davidson Gomes
52234089e4 feat: generic chatbot 2024-08-21 15:37:13 -03:00
Davidson Gomes
1ebd6f79c2 feat: generic chatbot 2024-08-21 15:36:54 -03:00
Stênio Aníbal
beb7942d7c Merge branch 'ev2' into v2.0.0 2024-08-21 15:02:52 -03:00
Stênio Aníbal
cca063dfed Fix not found event message for the event services 2024-08-21 15:02:40 -03:00
Davidson Gomes
16bc363d5f refactor: openai services 2024-08-21 14:58:48 -03:00
Stênio Aníbal
4aac2da253 Merge branch 'ev2' into v2.0.0 2024-08-21 14:56:55 -03:00
Stênio Aníbal
0aeecde847 Add BOT_CONTACT env option to Chatwoot 2024-08-21 14:56:41 -03:00
Stênio Aníbal
912df56c55 Remove event emit from channel service preventing exceptions 2024-08-21 14:56:12 -03:00
Stênio Aníbal
6585e8f0c2 Fix events structure to prevent "Instance not found" exception 2024-08-21 14:55:18 -03:00
Davidson Gomes
1bf76ecb94 refactor: dify services 2024-08-21 14:48:59 -03:00
Davidson Gomes
35bde8498b feat: generic chatbot 2024-08-21 14:42:26 -03:00
Davidson Gomes
9a09a6662a Merge pull request #802 from judsonjuniorr/v2-webhook-fix
Fix webhook validation
2024-08-21 14:01:17 -03:00
Davidson Gomes
73d65b0eb6 Merge branch 'v2.0.0' into v2-webhook-fix 2024-08-21 14:01:09 -03:00
Davidson Gomes
e7d971867b refactor: chatbot integration 2024-08-21 13:52:09 -03:00
Davidson Gomes
9209c9992d refactor: event integration 2024-08-21 13:47:41 -03:00
Davidson Gomes
edeb1efd2a refactor: chatbot integration 2024-08-21 13:37:22 -03:00
Judson Cairo
dcef6919cb Fix webhook validation 2024-08-21 11:04:18 -03:00
Stênio Aníbal
475fced33b Merge branch 'ev2' into v2.0.0 2024-08-21 10:45:12 -03:00
Davidson Gomes
8876797172 refactor: openai integration 2024-08-21 09:29:49 -03:00
Davidson Gomes
b58ad83c12 Merge pull request #800 from dev-luizf/fix/manage-webhook
Fix webhook creation
2024-08-21 07:23:04 -03:00
Diego Marino
839fe74a2c Put Meta Data in Message
Add externalAdReplyBody in Message for controlling ADS replies.
2024-08-20 22:50:25 -03:00
dev-luizf
68f57aa507 fix: fix webhook integration 2024-08-20 18:48:17 -03:00
Davidson Gomes
583ce33868 refactor: channel controller 2024-08-20 18:47:24 -03:00
Davidson Gomes
3b39f13180 refactor: adjusts in module init 2024-08-20 18:41:12 -03:00
Davidson Gomes
2ec0b842c1 refactor: integrations folder 2024-08-20 16:22:02 -03:00
Davidson Gomes
884362e70c refactor: channel folder 2024-08-20 15:49:32 -03:00
Davidson Gomes
df77aadd04 refactor: event folder 2024-08-20 15:36:55 -03:00
Davidson Gomes
7b79591e42 refactor: event folder 2024-08-20 15:27:32 -03:00
Davidson Gomes
64ed0faa83 refactor: integrations router folder structure 2024-08-20 13:13:49 -03:00
Davidson Gomes
d68d42b984 refactor: integrations folder structure 2024-08-20 12:27:04 -03:00
Davidson Gomes
1673132c3e Merge pull request #798 from stenioanibal/v2.0.0
Finish WebSocket refactor - V2.0.0
2024-08-20 11:40:19 -03:00
Stênio Aníbal
ec9e227413 Merge branch 'ev2' into v2.0.0 2024-08-20 11:26:34 -03:00
Stênio Aníbal
82634c0cb2 Merge websocket new events to the defaults 2024-08-20 11:26:05 -03:00
Davidson Gomes
8b5b4994f2 Merge pull request #789 from stenioanibal/v2.0.0
V2.0.0 - Refactor websocket structure
2024-08-20 11:19:36 -03:00
Davidson Gomes
ff52be5ac5 chore: adjusts in env for manager 2024-08-20 08:56:30 -03:00
Davidson Gomes
e555bc3930 feat: translation in manager: English, Portuguese, Spanish and French 2024-08-20 07:36:12 -03:00
Davidson Gomes
046c64c65d feat: translation in manager: English, Portuguese, Spanish and French 2024-08-20 07:29:14 -03:00
Davidson Gomes
9ae5255d5f fix: send pushName for openai assistant 2024-08-19 11:25:42 -03:00
Davidson Gomes
87a5663da7 Merge pull request #790 from judsonjuniorr/v2-advanced-operators-triggers
Advanced operators trigger for OpenAI/Dify/Typebot
2024-08-19 11:14:08 -03:00
Davidson Gomes
5300c345d9 Merge pull request #796 from matheusmaiberg/v2.0.0
feat: adicionada capacidade de OpenAI para interpretar o contexto de contatos de maneira mais precisa & adicionado informacoes do contato (remoteJid, pushName) no body da function
2024-08-19 11:13:45 -03:00
Matheus Almeida
0cfd143db0 feat: adicionada capacidade de OpenAI para interpretar o contexto de contatos de maneira mais precisa 2024-08-17 23:03:55 -03:00
Judson Cairo
fcd038924d Advanced operators trigger fro OpenAI/Dify/Typebot 2024-08-17 08:32:05 -03:00
Stênio Aníbal
cb36f04534 Remove unused import and bad additional websocket event 2024-08-16 18:31:02 -03:00
Stênio Aníbal
fbff945d5b Merge branch 'ev2' into v2.0.0 2024-08-16 17:46:14 -03:00
Stênio Aníbal
dc04eb16fc Refactor websocket structure 2024-08-16 17:45:09 -03:00
Davidson Gomes
a77fa414e5 changelog 2024-08-16 17:07:34 -03:00
Davidson Gomes
0dbb5f53f1 changelog 2024-08-16 16:24:34 -03:00
Davidson Gomes
b921a4d324 feat: IA send images and Sentry implemented 2024-08-16 11:31:46 -03:00
Davidson Gomes
3ef80bd6c5 feat: openai send images 2024-08-16 07:23:34 -03:00
Davidson Gomes
fb93c890ca feat: dify send images 2024-08-15 20:24:57 -03:00
Davidson Gomes
19f0296718 fix: chatwoot translations and s3 region 2024-08-15 15:41:30 -03:00
Davidson Gomes
38ec114fff Merge pull request #779 from fabioselau077/bugfix/s3_upload_files
[v2] - Região no S3 e fix do size no uploadFile
2024-08-15 15:34:34 -03:00
Davidson Gomes
212d09ef5a Merge pull request #780 from judsonjuniorr/V2-fix-chatwoot-translations
Fixed chatwoot translation files on build
2024-08-15 15:33:46 -03:00
Judson Cairo
a679776f89 Fixed chatwoot translation files on build 2024-08-15 15:32:17 -03:00
Davidson Gomes
00cb80f173 fix: docker 2024-08-15 14:05:52 -03:00
Davidson Gomes
60eb923f64 chore: Update tsup configuration
Modified: tsup.config.ts

This commit updates the tsup configuration file. The changes made aim to improve the project's build process and optimize the bundle size. No new functionality or bug fixes are introduced in this commit.
2024-08-15 14:00:24 -03:00
Davidson Gomes
975f41d58e fix: migrations 2024-08-15 13:13:08 -03:00
Davidson Gomes
285a950c67 changelog 2024-08-15 12:31:47 -03:00
Davidson Gomes
c4f91ead54 changelog 2024-08-15 12:31:12 -03:00
Davidson Gomes
785a72cbc8 feat: openai now identifies images 2024-08-15 12:29:08 -03:00
Fabio
b475d1d5ea set region from env and fix size in uploadFile 2024-08-15 11:26:30 -04:00
Stênio Aníbal
000d8fd436 Merge branch 'ev2' into v2.0.0 2024-08-15 11:49:42 -03:00
Davidson Gomes
061696e140 feat: dify now identifies images 2024-08-15 11:12:07 -03:00
Stênio Aníbal
16b910f955 Merge branch 'ev2' into v2.0.0 2024-08-15 10:12:44 -03:00
Davidson Gomes
376cafa350 Merge pull request #773 from judsonjuniorr/V2-integration-unification
V2 integration unification
2024-08-14 18:36:27 -03:00
Judson Cairo
448aefb989 Typo fix 2024-08-14 17:50:11 -03:00
Judson Cairo
1059c92583 Unification of integrations, Typebot & OpenAI & Dify 2024-08-14 17:47:31 -03:00
Judson Cairo
b68814795d Fixed mime types version 2024-08-14 17:41:25 -03:00
Stênio Aníbal
2772c2f31f Merge branch 'ev2' into v2.0.0 2024-08-14 17:02:40 -03:00
Davidson Gomes
360f8066a7 fix: crypto.randumUUID is not a function on Manager 2024-08-14 16:01:14 -03:00
Davidson Gomes
b3991cf6bb feat: Added ignoreJids in chatwoot settings 2024-08-14 14:59:47 -03:00
Davidson Gomes
daa4c76967 update package.json 2024-08-14 11:36:54 -03:00
Davidson Gomes
790b13f123 changelog 2024-08-14 11:34:28 -03:00
Davidson Gomes
b08287f568 changelog 2024-08-14 11:32:53 -03:00
Davidson Gomes
1d31f533f4 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-08-14 11:28:33 -03:00
Davidson Gomes
881a011493 chore: Deprecate buttons and list in new Baileys version
Updated CHANGELOG.md, package.json, src/api/dto/chat.dto.ts, and src/api/services/channels/whatsapp.baileys.service.ts to deprecate buttons and list due to the new Baileys version. This change improves compatibility and maintainability of the codebase.
2024-08-14 11:27:54 -03:00
Stênio Aníbal
707ac9db2c Fix cors settings for websocket when it's set for any origin 2024-08-14 10:36:48 -03:00
Stênio Aníbal
e385932bbc add jetbrains related files to gitignore 2024-08-14 10:30:29 -03:00
Davidson Gomes
78da13fcab Merge pull request #759 from judsonjuniorr/V2-duplicated-label-creation
Changed labels to be unique on the same instance
2024-08-13 15:56:24 -03:00
Davidson Gomes
7f83263b63 Merge pull request #758 from judsonjuniorr/v2-instance-cleanup
Remove instance from redis even if using database
2024-08-13 15:55:45 -03:00
Davidson Gomes
04f6e11cbd fix: adjusts in migrations 2024-08-13 13:15:13 -03:00
Judson Cairo
f0a6fb111e Removed console.log 2024-08-13 10:23:39 -03:00
Judson Cairo
48febec36a Changed labels to be unique on the same instance 2024-08-12 21:35:31 -03:00
Judson Cairo
041b3c5e1f Remove instance from redis even if using database 2024-08-12 21:03:51 -03:00
Davidson Gomes
dbb6ea9147 fix: adjusts 2.0.9 2024-08-12 13:24:19 -03:00
Davidson Gomes
6800b63945 Merge pull request #750 from judsonjuniorr/v2-path-mappings
V2 Path mapping & deps fix & bundler changed to tsup
2024-08-12 09:43:08 -03:00
Davidson Gomes
b3dacdb1e6 Merge pull request #749 from judsonjuniorr/v2-database-scripts
Improve database scripts to retrieve the provider from env file
2024-08-12 09:41:56 -03:00
Davidson Gomes
404edaa4e1 Merge pull request #747 from judsonjuniorr/v2-update-contacts-database
V2 update contacts database
2024-08-12 09:41:18 -03:00
Davidson Gomes
367d44a4d3 Merge pull request #746 from judsonjuniorr/v2-save-chat-name
V2 save chat name
2024-08-12 09:40:51 -03:00
Judson Cairo
32e58debc6 Path mapping & deps fix & bundler changed to tsup 2024-08-11 20:47:17 -03:00
Judson Cairo
66ae86b6f5 Improve database scripts to retrieve the provider from env file 2024-08-11 16:29:42 -03:00
Judson Cairo
7b1e4e9e3d Add chat name to fetch chats request 2024-08-11 15:49:43 -03:00
Judson Cairo
93cc25b513 Add migration for unique index in contacts 2024-08-11 15:33:46 -03:00
Judson Cairo
77cf4125dd Added migration for name column in chats 2024-08-11 15:29:39 -03:00
Judson Cairo
54e47c09c4 Fixed contacts update in the database 2024-08-10 23:43:53 -03:00
Judson Cairo
dacd408f8d Make contacts unique for the same instance
Avoid duplicated contacts in the database
2024-08-10 23:42:45 -03:00
Judson Cairo
d31b2c7f97 Remove unnecessary logs 2024-08-10 23:16:14 -03:00
Judson Cairo
926197b1ba Save chat names for groups identification 2024-08-10 23:15:20 -03:00
Judson Cairo
668f477218 Validate if session exists before deleting it 2024-08-10 23:15:02 -03:00
Davidson Gomes
feb7b795e9 refactor: .env.example 2024-08-09 14:38:33 -03:00
Davidson Gomes
0f299993d9 chore: adjusts in docker files 2024-08-09 12:41:16 -03:00
Davidson Gomes
e7ff09752e fix: StopBotFromMe working with chatwoot 2024-08-09 09:55:50 -03:00
Davidson Gomes
0dfbed4eb9 changelog 2024-08-09 08:01:47 -03:00
Davidson Gomes
9bf17f27f0 prisma: adjusts for mysql and postgres 2024-08-09 07:59:50 -03:00
Davidson Gomes
678f2c2b5d prisma: adjusts for mysql and postgres 2024-08-09 07:58:33 -03:00
Davidson Gomes
840f9c6f57 chore: adjusts in docker files 2024-08-09 07:17:09 -03:00
Davidson Gomes
9367be0fb1 chore: adjusting details 2024-08-09 06:53:43 -03:00
Davidson Gomes
fa05cf85ab changelog 2024-08-09 06:49:49 -03:00
Davidson Gomes
56a165db54 feat: added general session button in typebot, dify and openai in manager 2024-08-08 23:14:51 -03:00
Davidson Gomes
9329330297 Merge pull request #744 from rcesar/v2.0.0
Fix conversationId when is dify agent
2024-08-08 22:16:34 -03:00
Davidson Gomes
4d9f6ef416 fix: import contacts with image in chatwoot 2024-08-08 22:09:23 -03:00
Davidson Gomes
55d37250aa changelog 2024-08-08 20:31:45 -03:00
Davidson Gomes
bf3cb7c804 changelog 2024-08-08 20:23:52 -03:00
Davidson Gomes
801515a8f4 fix: adjusts in telemetry 2024-08-08 20:19:35 -03:00
Davidson Gomes
83d88ad70a fix: adjusts in telemetry 2024-08-08 20:18:20 -03:00
Davidson Gomes
6f2971cf24 feat: function for openai assistant added 2024-08-08 19:35:32 -03:00
Davidson Gomes
df3092b876 changelog 2024-08-08 19:24:51 -03:00
Davidson Gomes
a49b1e5ac4 changelog 2024-08-08 19:22:36 -03:00
Davidson Gomes
e3ba803247 changelog 2024-08-08 19:12:53 -03:00
Davidson Gomes
543a82d0f9 feat: function for openai assistant added 2024-08-08 19:03:07 -03:00
Davidson Gomes
26a974a239 feat: function for openai assistant added 2024-08-08 18:47:52 -03:00
Davidson Gomes
e7ca3cf254 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-08-08 17:51:27 -03:00
Davidson Gomes
59edf4ffb7 feat: Variables passed to the input in dify 2024-08-08 17:51:12 -03:00
Renan Cesar
0e4034ffac Fix conversationId when is dify agent 2024-08-08 16:28:40 -03:00
Davidson Gomes
d0a723b8ef Merge pull request #739 from fmedeiros95/v2.0.0
Improve reconnection logic for ban and block cases and add disconnection information to BaileysStartupService and Instance model
2024-08-06 15:03:11 -03:00
Felipe Medeiros
1c3bea4225 feat: add disconnection information to BaileysStartupService and Instance model
- Updated BaileysStartupService to include disconnection handling logic.
- Enhanced Instance model to store disconnection status and details.
2024-08-06 10:38:53 -03:00
Felipe Medeiros
258f56759c refactor: update reconnection logic to prevent reconnection in cases of banishment or blocking
Handled specific errors to improve reconnection logic:
- 401: Triggered logout to handle unauthorized access.
- 402: Recognized as temporary ban, reconnection attempts paused.
- 403: Recognized as forbidden, reconnection attempts stopped.
- 406: Recognized as permanent ban, reconnection attempts halted.
2024-08-06 01:48:42 -03:00
Davidson Gomes
d82945a735 changelog 2024-08-03 14:05:08 -03:00
Davidson Gomes
de8e4a0ca3 fix(dify agent integration): Updated dify agent integration to use streaming response mode and handle message data in chunks. Modified CHANGELOG.md and src/api/integrations/dify/services/dify.service.ts.
This commit addresses an issue with the dify agent integration by updating it to use a streaming response mode. This allows for handling message data in smaller chunks, improving performance and reducing memory usage. The commit also includes updates to the CHANGELOG.md file and the dify.service.ts file, where the actual changes were implemented.
2024-08-03 14:04:39 -03:00
Davidson Gomes
2aa0e08ae4 fix: Added description column on typebot, dify and openai 2024-08-03 13:51:24 -03:00
Davidson Gomes
8438c442b4 fix: Credentials verify on manager login 2024-08-03 13:37:54 -03:00
Davidson Gomes
1d530ac2e9 changelog 2024-08-03 13:36:51 -03:00
Davidson Gomes
9c5eb4bfd1 fix: Session is now individual per instance and remoteJid
Changes made:
- Added `instanceId` to sessions in DifyService, OpenaiService, and TypebotService to ensure that sessions are individual per instance and remoteJid.
- Decreased delay time in BaileysStartupService from 2000ms to 1000ms.

The bug fix ensures that sessions are unique per instance and remoteJid, which improves the overall functionality of the application. The delay time reduction in BaileysStartupService speeds up the pairing code request process.

The modified files are DifyService, OpenaiService, TypebotService, and BaileysStartupService.
2024-08-03 13:36:31 -03:00
Davidson Gomes
c74333719f changelog 2024-08-03 13:20:47 -03:00
Davidson Gomes
819ef70b7b fix: Resolve issue with connecting to instance
Corrected an issue with connecting to the instance by updating the connection status in the Whatsapp Baileys service.

Modified files:
- Whatsapp Baileys service (src/api/services/channels/whatsapp.baileys.service.ts)
2024-08-03 13:20:22 -03:00
Davidson Gomes
9f2801d289 Fix: Resolved issue with connecting to instance
Modified: index.router.ts, whatsapp.baileys.service.ts

Fixed an issue with connecting to the instance by modifying the code in index.router.ts and whatsapp.baileys.service.ts. This change resolves a critical problem that was preventing the application from connecting to the necessary instance.
2024-08-03 13:17:02 -03:00
Davidson Gomes
b92a985cf8 chore(readme): update on readme 2024-08-03 12:56:16 -03:00
Davidson Gomes
c6db03ffa2 fix: Adjusts in restart instance 2024-08-03 12:54:23 -03:00
Davidson Gomes
7ed1965f57 fix: BusinessId added on create instances in manager 2024-08-03 11:27:19 -03:00
Davidson Gomes
8df38e871a fix: BusinessId added on create instances in manager 2024-08-03 11:27:07 -03:00
Davidson Gomes
385307edc6 chore(readme): update on readme 2024-08-03 10:00:26 -03:00
Davidson Gomes
7ad96f54ca fix: update typebot, openai and dify 2024-08-02 19:42:54 -03:00
Davidson Gomes
671b677569 fix: fetchInstances with clientName parameter 2024-08-02 19:22:44 -03:00
Davidson Gomes
3fa6b1fcc5 fix: get models openai 2024-08-02 10:49:06 -03:00
Davidson Gomes
fd64ea07d0 v2.0.5-rc 2024-08-01 18:01:36 -03:00
Davidson Gomes
359908041b fix: instance screen scroll bar in manager 2024-08-01 18:00:49 -03:00
Davidson Gomes
fc5b8668e6 Merge branch 'v2.0.0' of github.com:EvolutionAPI/evolution-api into v2.0.0 2024-08-01 17:15:40 -03:00
Davidson Gomes
67409e1bf5 Add speech-to-text functionality using OpenAI
This commit introduces a new feature that transcribes audio messages to text using OpenAI's Whisper model. The following files were modified to implement this feature:

- `CHANGELOG.md`: Added a new entry under the 'Features' section to document the speech-to-text functionality.
- `prisma/postgresql-schema.prisma`: Added a new boolean field `speechToText` to the `OpenaiSetting` model.
- `src/api/integrations/openai/dto/openai.dto.ts`: Added a new optional boolean property `speechToText` to the `OpenaiSettingDto` class.
- `src/api/integrations/openai/services/openai.service.ts`: Implemented the `speechToText` method to handle the transcription process.
- `src/api/integrations/openai/validate/openai.schema.ts`: Added a new required boolean schema for the `speechToText` property in the `openaiSettingSchema`.
- `src/api/integrations/typebot/services/typebot.service.ts`: Updated the `audioMessage` property to consider the new `speechToText` field.
- `src/api/services/channels/whatsapp.baileys.service.ts` and `src/api/services/channels/whatsapp.business.service.ts`: Added logic to handle the transcription of audio messages when the `speechToText` setting is enabled.

The purpose of this change is to provide a more accessible way for users to interact with audio messages by converting them to text. This improvement will be particularly useful for users with hearing impairments or those in noisy environments.
2024-08-01 17:15:20 -03:00
Davidson Gomes
b6e90bb037 Merge pull request #725 from oriondesign2015/patch-1
Atualização Stack Evolution API v2
2024-07-31 18:51:04 -03:00
OrionDesign
af5ef4d53c Update evolution_api_v2.yaml 2024-07-31 18:47:27 -03:00
OrionDesign
b4d01da68d Update evolution_api_v2.yaml 2024-07-31 18:37:16 -03:00
OrionDesign
9b4f80dfc5 Update evolution_api_v2.yaml 2024-07-30 19:40:42 -03:00
OrionDesign
f09fedb7c0 Atualização Stack Evolution API v2
Adição de algumas environments que imagino que estejam faltando.
2024-07-30 19:39:17 -03:00
Davidson Gomes
a73b74ceaa updates on manager 2024-07-30 18:39:00 -03:00
Davidson Gomes
a49c63bc2b chore: Update CHANGELOG and API routes
Updated CHANGELOG.md with details of the current release.
Modified src/api/routes/index.router.ts to improve the API routing.

These changes are part of the ongoing maintenance and improvement of the project.
2024-07-30 18:38:13 -03:00
Davidson Gomes
8118c68dce v2.0.4-rc 2024-07-30 17:07:45 -03:00
Davidson Gomes
ef2291b9a9 v2.0.4-rc 2024-07-30 15:39:00 -03:00
Davidson Gomes
bb65b566e5 chore: Update dify and openai services
Modified the implementation of Dify and OpenAI services to improve overall functionality. These changes aim to enhance the stability and performance of the integration layer, although no new features have been added.

Changes affected the following files:
- dify.service.ts
- openai.service.ts
2024-07-30 15:38:27 -03:00
Davidson Gomes
881c1c2aa6 v2.0.4-rc 2024-07-30 14:52:19 -03:00
Davidson Gomes
fcb9dd29f3 v2.0.4-rc 2024-07-30 14:14:17 -03:00
Davidson Gomes
7cd0d2430d feat: update new manager for dify 2024-07-30 14:12:46 -03:00
Davidson Gomes
35016087d6 changelog 2024-07-30 13:35:31 -03:00
Davidson Gomes
a5d72a0dfd feat: Integration with Dify
Adds support for Dify integration, including new routes, services, and controllers. The configuration for Dify has been added to the environment file, and the necessary changes have been made to the `.env.example` file. Additionally, the WhatsApp Baileys service has been updated to handle Dify notifications.

Modified files:
- `.env.example`
- `package.json`
- `src/api/integrations/openai/services/openai.service.ts`
- `src/api/routes/index.router.ts`
- `src/api/server.module.ts`
- `src/api/services/channel.service.ts`
- `src/api/services/channels/whatsapp.baileys.service.ts`
- `src/config/env.config.ts`
- `src/validate/validate.schema.ts`

Introduced files:
- `src/api/integrations/dify/`
- `src/api/integrations/dify/controllers/dify.controller.ts`
- `src/api/integrations/dify/dto/dify.dto.ts`
- `src/api/integrations/dify/routes/dify.router.ts`
- `src/api/integrations/dify/services/dify.service.ts`
- `src/api/integrations/dify/validate/dify.schema.ts`
2024-07-30 13:34:35 -03:00
Davidson Gomes
b604e4ecc7 feat: Introduce dify tables with related migrations
This commit introduces a new feature, dify tables, along with related migration scripts. The `prisma/migrations/20240730152156_create_dify_tables/migration.sql` file contains the migration for creating the dify tables, while the `prisma/postgresql-schema.prisma` file has been modified to include the necessary schema changes for these tables. This change improves data organization and simplifies data management for the project.
2024-07-30 12:22:39 -03:00
Davidson Gomes
66814b403e chore: Update monitor service and instance controller
Refactored the instance controller and monitor service to improve the connection handling and management of WhatsApp instances.

- Modified the instance controller to close the WebSocket connection and restart the instance instead of reloading it.
- Updated the monitor service to remove the instance from the `waInstances` object and emit an event to clean up and remove the instance data.
- Fixed an issue where the instance was not being removed from the `waInstances` object.

Files affected:
- CHANGELOG.md
- src/api/controllers/instance.controller.ts
- src/api/services/monitor.service.ts
2024-07-30 11:15:21 -03:00
Davidson Gomes
95bc5e6b21 chore: Updated dependencies and added new manager
In this commit, the following changes were made:

- Updated the version of the project to 2.0.4-beta.
- Added the new manager with version 2.0.0.
- Updated the Baileys version.
- Modified several files such as CHANGELOG.md, Dockerfile, package.json, src/api/routes/index.router.ts, and src/api/routes/view.router.ts.
- Deleted the views/manager.hbs file and added the manager/ folder.

These changes update the dependencies and include a new manager, which may impact the application's functionality.
2024-07-30 09:17:49 -03:00
Davidson Gomes
5047e6281a fix: Correct openai session deletion and pause functionality
This commit fixes an issue where openai sessions were not being properly deleted or paused. It updates the `openai.service.ts` and `openai.schema.ts` files to correctly handle session deletion and pausing.

The `openai.service.ts` file now includes additional checks for session status before deleting or updating. The `openai.schema.ts` file has been updated to include a new 'delete' status option.

These changes ensure that openai sessions are properly managed and that the bot can be paused and resumed as intended. This improves the overall functionality and user experience of the application.
2024-07-29 19:07:26 -03:00
Davidson Gomes
7ba1f2fdf4 fix: Correct pause and listen to my messages from Typebot integration
This commit fixes an issue where the bot was not pausing and listening to my messages from the Typebot integration. The changes include modifying the Typebot service, Typebot schema, and WhatsApp Baileys and Business services to properly handle the pause and message listening functionality. The affected files are typebot.service.ts, typebot.schema.ts, and both WhatsApp services.

The specific modifications include adding a new 'delete' status option in the Typebot schema, updating the Typebot service to handle the 'delete' status, and adjusting the WhatsApp services to properly send Typebot messages based on the new schema. This ensures that the bot can pause and listen to messages from Typebot integration, providing a better user experience.
2024-07-29 17:53:18 -03:00
Davidson Gomes
21375bcb4d changelog 2024-07-29 17:30:26 -03:00
Davidson Gomes
7bfb4f93bb Fix: Corrected openai trigger validation
Corrected an issue in the validation of openai triggers by changing the 'findFirst' method to 'findMany' and implementing a loop to find the correct trigger match. This change improves the accuracy of trigger validation and ensures that all possible matches are considered.

Impact: This fix ensures that the correct trigger is identified, improving the overall functionality of the openai integration.

Affected files:
- openai.service.ts
2024-07-29 17:29:55 -03:00
Davidson Gomes
c03e0cc954 fix: corrected typebot trigger validation
Explanation:
This commit fixes an issue in the validation of typebot triggers. The 'findFirst' method was used to search for triggers, but it only returns the first match found. To solve this problem, the 'findMany' method was used instead, and a loop was added to search for all matches. This change ensures that all triggers that match the validation criteria are returned.

The modified file is:
- typebot.service.ts: this is the main file where the changes were made. It was necessary to modify the function that validates the triggers, replacing the 'findFirst' method with the 'findMany' method and adding a loop to search for all matches.

This change improves the validation of typebot triggers, ensuring that all matches are returned, and prevents errors in the trigger validation process.
2024-07-29 17:29:18 -03:00
Davidson Gomes
b3b1fb30c7 fix: adjusts for new manager 2024-07-29 15:10:04 -03:00
Davidson Gomes
2a7f9698d2 fix: adjusts for new manager 2024-07-29 15:09:40 -03:00
Davidson Gomes
089810fb55 fix: Update Baileys version in package.json and CHANGELOG.md
This commit updates the Baileys version from 'github:EvolutionAPI/Baileys' to '6.7.5' in the package.json file. Additionally, it includes an update to the CHANGELOG.md file, adding a new section for version 2.0.4-beta with a fixed issue related to Baileys. This change improves the stability and compatibility of the project with the latest Baileys version.
2024-07-29 09:34:29 -03:00
Davidson Gomes
24866834e9 version 2024-07-29 09:03:37 -03:00
Davidson Gomes
c3bb632a1a fix: Fixed Typebot start call with active session by updating instanceId references in TypebotService
In this commit, I fixed an issue with the start call of Typebot when there is an active session. I noticed that there were inconsistencies in the way the instanceId was being referenced in the TypebotService.

To resolve this, I modified the TypebotService to update the instanceId references to the correct format. Specifically, I changed the following files:
- CHANGELOG.md: added a note about the fix for the Typebot start call with active session
- src/api/integrations/typebot/services/typebot.service.ts: updated the instanceId references in the startTypebot, createNewSession, and other related methods.

This change ensures that the Typebot start call with active session works as intended, improving the overall functionality of the Typebot integration.
2024-07-29 09:02:51 -03:00
Davidson Gomes
bda0f6a198 changelog 2024-07-29 08:53:42 -03:00
Davidson Gomes
d00e3677f5 chore: adjust TriggerType for OpenAI and Typebot integrations
Modifies the TriggerType enum to include a 'none' option and updates the OpenAI and Typebot services to handle this new option. Additionally, the services now require a trigger operator and value when the trigger type is set to 'keyword'.

Modified files:
- prisma/postgresql-schema.prisma
- src/api/integrations/openai/services/openai.service.ts
- src/api/integrations/typebot/services/typebot.service.ts

Untracked file:
- prisma/migrations/20240729115127_modify_trigger_type_openai_typebot_table/
2024-07-29 08:53:15 -03:00
Davidson Gomes
f95d34a1da chore: Update WhatsApp Business service to stop processing read messages from non-broadcast and non-me jids
Modifies the WhatsApp Business service to skip processing read messages from non-broadcast and non-me jids, improving performance and reducing unnecessary computations. Affects src/api/services/channels/whatsapp.business.service.ts.
2024-07-28 19:54:45 -03:00
Davidson Gomes
0bb2b92853 feat: Sending template approval status webhook 2024-07-25 19:38:34 -03:00
Davidson Gomes
31cb83a40c chore: Update changelog with new webhook feature and bug fix
- Add new section "Features" with webhook url by submitted template
- Equations and adjustments for the new manager under "Fixed" section
- CHANGELOG.md modified
2024-07-23 17:14:26 -03:00
Davidson Gomes
4746d3991e chore: Add webhookUrl to Message model, DTOs, and services
Adds webhookUrl field to Message model, SendMessageDto, SendTemplateDto, SendContactDto, and related services to enable sending messages to a specified webhook URL. This change allows for more flexible message handling and delivery options.

Modified files:
- prisma/postgresql-schema.prisma
- src/api/dto/sendMessage.dto.ts
- src/api/services/channels/whatsapp.business.service.ts
- src/validate/message.schema.ts

Untracked files:
- prisma/migrations/20240723200254_add_webhookurl_on_message/
2024-07-23 17:13:37 -03:00
Davidson Gomes
50591e9ed6 chore: Update package version and changelog
Bumped package version from 2.0.2-beta to 2.0.3-beta to reflect recent changes.
Updated the changelog accordingly. The modification was made in the package.json file.
This change is a preparation for the next release and does not introduce new features or bug fixes.
2024-07-23 12:35:56 -03:00
Davidson Gomes
388a4f7630 chore: Update changelog
Update the CHANGELOG.md file to reflect the recent changes in the project. This commit includes the addition and modification of the changelog to keep track of the updates made in the v2.0.0 branch.
2024-07-23 12:35:36 -03:00
Davidson Gomes
c1d3209f2f chore: equations and adjustments for the new manager 2024-07-23 12:34:58 -03:00
Davidson Gomes
837f7f310a fix(CHANGELOG.md): Update version 2.0.2-beta release date and remove assistant details
This commit updates the release date of version 2.0.2-beta in the CHANGELOG.md file and removes the detailed description of Open AI assistants implementation, as it is not necessary for this section. The main purpose of this commit is to keep the CHANGELOG.md file clean and concise, only mentioning the high-level changes and updates.

Note that the focus of this commit is on the CHANGELOG.md file, which is a crucial file for tracking the project's versioning and changes over time. By providing a clear and concise commit message, other developers can easily understand the purpose of this change and its impact on the project's versioning and documentation.
2024-07-18 21:34:02 -03:00
Davidson Gomes
f8e303f3a3 fix: Implement open chat completion and refactor code
Remove unnecessary initialization of empty arrays for systemMessages, assistantMessages, and userMessages in OpenaiService.
Also, implement a function to handle open chat completion and refactor the code for better readability and maintainability.
Affected files: openai.service.ts
2024-07-18 21:33:21 -03:00
Davidson Gomes
51749e8712 feat: Open AI assistants implemented 2024-07-18 21:11:46 -03:00
Davidson Gomes
29b9e688a8 chore: Crud openai complete 2024-07-18 10:14:53 -03:00
Davidson Gomes
5b13de377b feat: started openai integration, added models to the database
This commit introduces a new openai integration in the project, along with necessary changes in the database schema. The package.json file has been updated to include the openai package, and the prisma/postgresql-schema.prisma file has been modified to include OpenaiCreds, OpenaiAssistant, OpenaiAssistantThread, and OpenaiChatCompletion models. These models will handle the integration with OpenAI's API for various tasks.

Some of the key changes include:

- Addition of OpenaiCreds model to manage API credentials.
- Addition of OpenaiAssistant model to handle OpenAI assistant instances.
- Addition of OpenaiAssistantThread model to manage OpenAI assistant threads.
- Addition of OpenaiChatCompletion model to handle OpenAI chat completions.

These changes will enable seamless integration with OpenAI's API and allow for better management of assistant instances, threads, and chat completions.
2024-07-18 08:48:56 -03:00
Davidson Gomes
aa2da01401 fix: Correction in start typebot, create it if not exists
- Corrected an issue where the start typebot function would throw an error if the typebot was not found.
- Added a condition to create a new typebot if it doesn't exist.
- Updated CHANGELOG.md with the details of the changes.

Files affected:
- CHANGELOG.md
- src/api/integrations/typebot/services/typebot.service.ts
2024-07-18 08:25:59 -03:00
Davidson Gomes
9aa2b1b3bf chore: Add apiKey and ServerUrl to prefilledVariables in typebot service
Update typebot.service.ts to add apiKey and ServerUrl to prefilledVariables.
This change is necessary for the typebot service to correctly prefill variables with the required credentials.
The deleted file .github/workflows/publish_docker_image_v2.yml was not related to this change.

Note: This change does not affect the current functionality but provides a better way to handle credentials.

Confidence: 90%
2024-07-18 08:15:53 -03:00
Davidson Gomes
b907d85a7e Fix: Fixed global exchange name and updated database connection client name
This commit resolves an issue with the global exchange name and updates the database connection client name. The `.env.example`, `CHANGELOG.md`, and `src/api/integrations/rabbitmq/libs/amqp.server.ts` files were modified. The exchange name in the AMQP server and global queues initialization has been changed to use the value from the configuration service. Additionally, the database connection client name has been updated in the `.env.example` file. The change in the `CHANGELOG.md` file has been updated accordingly.
2024-07-17 18:55:35 -03:00
Davidson Gomes
7e9132fcfe chore: Remove DEL\_TEMP\_INSTANCES variable and related functionality
The DEL\_TEMP\_INSTANCES variable and its related functionality have been removed from the .env.example, CHANGELOG.md, and src/api/services/monitor.service.ts files. The `delInstanceFiles` and `deleteTempInstances` methods have been removed from the MonitoringService class. This change simplifies the codebase and removes unnecessary functionality that was not being used.

Please note that this change does not impact the current functionalities of the application. However, it's important to update the documentation and any other related files accordingly. Make sure to test the application thoroughly to ensure there are no unintended consequences from this change.
2024-07-17 18:52:40 -03:00
Davidson Gomes
d76816eb9c Fix: Resolve 'not find name' issue in WhatsApp service
Resolves an issue where a name was not being found in the WhatsApp service. This fix updates the 'name' property in the WhatsApp service to use 'remoteJid' instead of 'id' when searching for contacts. This change affects the 'src/api/services/channels/whatsapp.baileys.service.ts' file and is reflected in the latest CHANGELOG.md update.

Note: The 'not find name' issue was initially addressed in the previous CHANGELOG.md version but was reintroduced due to a change in the contacts search logic. This commit aims to definitively resolve the issue.
2024-07-17 18:49:39 -03:00
Davidson Gomes
d1098cfcae fix: Update version and fix data saving function
This commit updates the package version from 2.0.1-beta to 2.0.2-beta and fixes an issue with the function of saving or not saving data in the database. It modifies the package.json and CHANGELOG.md files.

Note: The CHANGELOG.md file includes a detailed list of changes and can be reviewed for more information.
2024-07-17 18:43:44 -03:00
Davidson Gomes
1e96878e5f fix: Improve database saving functionality
This commit fixes an issue with data being inconsistently saved in the database. It introduces a new configuration option to enable/disable saving of chat and contact data, as well as message updates and historic data.

The following files were modified:
- .env.example
- CHANGELOG.md
- src/api/services/channels/whatsapp.baileys.service.ts
- src/config/env.config.ts

The 'DATABASE_SAVE_DATA_NEW_MESSAGE', 'DATABASE_SAVE_DATA_MESSAGE_UPDATE', 'DATABASE_SAVE_DATA_CONTACTS', 'DATABASE_SAVE_DATA_CHATS', and 'DATABASE_SAVE_DATA_HISTORIC' options have been added to the 'SaveData' interface in 'env.config.ts'. These options control whether new messages, message updates, contacts, chats, and historic data are saved in the database, respectively. The 'DATABASE_SAVE_DATA_HISTORIC' option is new and allows for more granular control over what data is saved.

The 'WhatsappBaileysService' in 'whatsapp.baileys.service.ts' has been updated to check these configuration options before saving data in the database. This ensures that data is only saved when explicitly allowed.

The 'CHANGELOG.md' has been updated to reflect these changes.
2024-07-17 18:41:11 -03:00
Davidson Gomes
19e9ff9cc8 Fix: Resolved issue with Chatwoot not receiving messages sent by Typebot
Modified: CHANGELOG.md, src/api/integrations/typebot/services/typebot.service.ts

This commit resolves an issue where Chatwoot was not receiving messages sent by Typebot. The necessary changes were made to the typebot service file and the changelog was updated accordingly.
2024-07-17 15:49:03 -03:00
Davidson Gomes
6188944100 chore: Update README.md with new contributors
- Added new contributors to the README.md file
- Updated the Comunidade Hub Connect link with a new one
- Added four new content creators to the README.md file
- The changes will improve the visibility of the project and its contributors
- The updated file is README.md
2024-07-15 17:43:19 -03:00
Davidson Gomes
a03ce984f6 chore: Update telemetry and add new integrations
Refactored the telemetry guard to use a new sendTelemetry utility function,
which allows for easier tracking of API routes. Also, added telemetry events
for message sending in the Chatwoot and Typebot services.

Additionally, updated the README.md to include new content creators and
added new integrations with Typebot and Chatwoot services.

Modified:
- README.md
- package.json
- src/api/guards/telemetry.guard.ts
- src/api/integrations/chatwoot/services/chatwoot.service.ts
- src/api/integrations/typebot/services/typebot.service.ts

Added:
- src/utils/sendTelemetry.ts
2024-07-15 12:43:20 -03:00
Davidson Gomes
22a24b1b88 chore: Implement telemetry and update README
Updated README.md to include a notice about the implementation of telemetry. The telemetry collects data on the routes used, the most accessed routes, and the version of the API in use, without collecting any sensitive or personal data. This change will help identify improvements and provide a better experience for users.
2024-07-15 09:36:08 -03:00
Davidson Gomes
e33893d943 chore: Add telemetry system
Added new file 'telemetry.guard.ts' in 'src/api/guards' directory.
Modified 'index.router.ts' in 'src/api/routes' directory to integrate the new telemetry system.

This change improves the monitoring and data gathering capabilities of the application, allowing for better performance analysis and potential issue detection.
2024-07-15 09:25:40 -03:00
Davidson Gomes
7a675e7b37 fix(CHANGELOG): update version from alpha to beta
- Updated the version from 2.0.0 (alpha) to 2.0.0 (beta) in the CHANGELOG.md file.
- This change reflects the progression of the project towards a beta version.
2024-07-14 12:29:16 -03:00
Davidson Gomes
cb1921d28c chore: Updated Docker image tag for v2.0.0 in publish workflow
This commit updates the Docker image tag from 'v2.0.0-alpha' to 'v2.0.0-beta' in the 'publish\_docker\_image\_v2.yml' workflow file. The change aims to reflect the progress of the version towards a more stable release.

The main file affected by this change is '.github/workflows/publish\_docker\_image\_v2.yml'.
2024-07-14 12:27:56 -03:00
Davidson Gomes
585421c514 chore: Update changelog with new features and bug fixes
- Update CHANGELOG.md with new typebot integration improvements
  - Media sent to typebot now goes as a template string, example: imageMessage|MESSAGE\_ID
  - Added debounce time for typebot messages
  - Tagging in chatwoot contact by instance
  - Ignore jids configuration added to typebot (will be used for both groups and contacts)
  - When S3 integration enabled, the media sent to typebot now goes as a template string, example: imageMessage|MEDIA\_URL
- Fix typo in CHANGELOG.md: * Media sent to typebot now goes as a template string, example: imageMessage:MESSAGE\_ID (corrected to |)

Please review the updated changelog for accuracy and completeness.
2024-07-14 10:50:38 -03:00
Davidson Gomes
484736facd fix: Updated media handling in WhatsApp Baileys and Typebot services
This commit fixes issues with media handling in the WhatsApp Baileys and Typebot services. Specifically, it updates the way media messages are processed and stored. The changes include:

- Importing the `S3` class from the configuration in the Typebot service (`src/api/integrations/typebot/services/typebot.service.ts`).
- Modifying the `getTypeMessage` method in the Typebot service to handle media messages more efficiently.
- Refactoring the `BaileysStartupService` in the WhatsApp Baileys service (`src/api/services/channels/whatsapp.baileys.service.ts`) to handle media messages more consistently.

These changes improve the handling and storage of media messages, ensuring that they are processed correctly and efficiently.
2024-07-14 10:39:32 -03:00
Davidson Gomes
e6916acf45 chore: Improve 'getBase64FromMediaMessage' function in Whatsapp Baileys service
The 'getBase64FromMediaMessage' function in the Whatsapp Baileys service has been improved. Now, the 'getBuffer' parameter has a default value of 'false', making it optional. This change simplifies the function call and enhances readability.

Modified file:
- src/api/services/channels/whatsapp.baileys.service.ts
2024-07-13 16:15:55 -03:00
Davidson Gomes
d80b0d14ac chore: Whatsapp Baileys service - disable webhook media download when S3 is not enabled
This change disables the download of media messages through the Whatsapp Baileys service's local webhook when the S3 storage is not enabled. This is to prevent unnecessary media downloads and potential storage issues. The modified file is 'whatsapp.baileys.service.ts'.
2024-07-13 16:12:16 -03:00
Davidson Gomes
db1ab7404b chore: Update environment variables and add Minio/S3 integration
Updated .env.example with new environment variables for Minio/S3 integration.
Added configuration for Minio/S3 endpoint, bucket, access key, secret key, and other related settings.
Updated CHANGELOG.md to include the Minio/S3 integration.

This change allows for the addition of Minio/S3 as a storage option for the project, improving flexibility and scalability.
2024-07-13 16:09:20 -03:00
Davidson Gomes
e73d9c1982 chore: Integration with MinIO and S3
Adds support for MinIO and S3 for storing media files. Modified several files to implement this feature, including package.json, prisma/postgresql-schema.prisma, src/api/integrations/typebot/services/typebot.service.ts, src/api/routes/index.router.ts, src/api/services/channels/whatsapp.baileys.service.ts, and src/config/env.config.ts. Added untracked files for the new S3 integration. Also added a new S3Controller and S3Service for handling S3 related operations.

This change allows for more flexible media storage options and enables the use of MinIO or S3 for storing media files.
2024-07-13 16:07:16 -03:00
Davidson Gomes
f7a731a193 chore: Add ignoreJid feature to typebot and improve comparison
Adds a new feature to the typebot integration that allows ignoring specific remote JIDs. Also improves the comparison functionality. The main changes are in the typebot controller, DTO, route, and service. Additionally, the WhatsApp Business Service and event configuration files have been updated.

The main files modified are:
- typebot.controller.ts
- typebot.dto.ts
- typebot.router.ts
- typebot.service.ts
- typebot.schema.ts
- whatsapp.business.service.ts
- event.config.ts
2024-07-13 13:55:42 -03:00
Davidson Gomes
e3a97d0071 refactor: using stream instead of temp files in chatwoot and repository services
This commit refactors the code in the `chatwoot.service.ts` and `repository.service.ts` files to use streams instead of temporary files. This change reduces the number of disk operations, making the application faster and more efficient.

In the `chatwoot.service.ts` file, the `createReadStream`, `unlinkSync`, and `writeFileSync` functions have been replaced with the `Readable` stream. The `sendData` method has been updated to accept a `fileStream` and `fileName` instead of a file path. The `processImage` method has been refactored to use a stream instead of writing the image to a file.

In the `repository.service.ts` file, the `initStoreFolders` method has been removed, as it is no longer needed.

These changes improve the maintainability of the codebase by reducing the number of disk operations and simplifying the code. This refactoring also makes the application more efficient and faster, as it reduces the number of disk operations.

Motivation:
The motivation behind this refactoring is to improve the performance and efficiency of the application by reducing the number of disk operations.

Impact:
This refactoring reduces the number of disk operations, making the application faster and more efficient. It also simplifies the codebase and improves its maintainability.
2024-07-13 08:10:36 -03:00
Davidson Gomes
d3ab402d94 chore: Update changelog with new changes
- Add support for ignoring jids configuration in typebot
- Update regex and fallback implementation in typebot
- Enable tagging in chatwoot contact by instance
- Add support for managing WhatsApp templates via official API

The changelog has been updated to reflect the recent changes in the project. This includes the addition of a new feature to ignore jids configuration in typebot, updates to the regex and fallback implementation in typebot, the ability to enable tagging in chatwoot contact by instance, and support for managing WhatsApp templates via the official API. These changes improve the functionality and maintainability of the project.
2024-07-12 20:18:39 -03:00
Davidson Gomes
b2bf5d2318 chore: Ignore specific JIDs in Typebot integration
Implements the ability to ignore specific JIDs in the Typebot integration, improving the flexibility of the feature. This change includes modifications in the Prisma schema, DTOs, services, and validation schema.

- Adds 'ignoreJids' field to the PostgreSQL schema (prisma/postgresql-schema.prisma).
- Updates TypebotDto and TypebotSettingDto to include 'ignoreJids' (src/api/integrations/typebot/dto/typebot.dto.ts).
- Modifies TypebotService to handle 'ignoreJids' when creating and updating Typebot instances (src/api/integrations/typebot/services/typebot.service.ts).
- Adds 'ignoreJids' to the Typebot validation schema (src/api/integrations/typebot/validate/typebot.schema.ts).

This update allows for more precise control over which JIDs are processed by the Typebot integration, reducing unnecessary processing and improving performance.
2024-07-12 20:14:57 -03:00
Davidson Gomes
480cc67927 feat: Fixes and implementation of regex and fallback in typebot 2024-07-12 20:03:53 -03:00
Davidson Gomes
a52a687493 chore: Remove unused fileExists function in use-multi-file-auth-state-prisma.ts
Explanation:
This commit removes an unused `fileExists` function from the `use-multi-file-auth-state-prisma.ts` file. This change simplifies the code and reduces the potential for confusion or maintenance issues in the future. The previously implemented `fileExists` function was commented out and not used in any other part of the file, so it was safe to remove. This change does not affect the functionality of the module and is a pure code improvement.

Affected files:
- `src/utils/use-multi-file-auth-state-prisma.ts`
2024-07-12 14:15:16 -03:00
Davidson Gomes
634ee9b4b3 fix: Resolve 'no such file or directory' error (#123)
This commit fixes an issue where a 'no such file or directory' error was being thrown. The error was caused by the absence of a temporary directory used for storing data. To resolve this issue, the `initStoreFolders` method was added to the `PrismaRepository` class, which creates the necessary store path and temporary directory during initialization.

The modifications include changes to the `repository.service.ts` file, where the `initStoreFolders` method was implemented. The `fs` and `path` modules were imported to facilitate file system operations.

With these changes, the error should no longer occur, ensuring the proper functioning of the application.
2024-07-12 14:01:18 -03:00
Davidson Gomes
49ad9812a4 fix: Correction in response returns from buttons, lists and templates
Fixes the display of unnecessary logs in the webhook controller and updates the way context data is handled in the Whatsapp Business service. Adds private methods to handle different types of messages, such as buttons, reactions and contacts.

Modified files:
- webhook.controller.ts
- whatsapp.business.service.ts
2024-07-12 13:45:31 -03:00
Davidson Gomes
c782305456 Remove template model and related functionality (prisma/postgresql-schema.prisma, src/api/services/template.service.ts)
This commit removes the Template model, including its related functionality, from the project. The template table has been removed from the database schema, and all related functions and methods in the template service have been deleted. This change was made because the project now uses the persistence of the meta, eliminating the need for a separate template model.

Please note that this change may affect other parts of the application that rely on the Template model. Ensure that all necessary adjustments have been made before merging this commit.
2024-07-12 13:25:59 -03:00
Davidson Gomes
ca3dadfb35 Fix: Resolve issue with template association in Instance model
The Issue:
The Instance model in the postgresql-schema.prisma file previously had a Template field that was a single Template object, but this caused issues with the association of multiple templates to a single instance.

The Change:
This commit resolves the issue by changing the Template field to an array of Template objects. This allows for multiple templates to be associated with a single instance.

The Impact:
This change allows for more flexible use of templates in the system and resolves a previous limitation in the association of templates to instances.

Affected Files:
- prisma/postgresql-schema.prisma
- src/api/services/template.service.ts

Note: The migration folder added in the untracked files section is a result of the Prisma schema change and can be safely ignored in this commit message.
2024-07-12 13:01:17 -03:00
Davidson Gomes
99a091ec61 fix: Correção no retorno dos envios na API oficial do WhatsApp
Correção no serviço WhatsApp Business para retornar a mensagem após o envio.
Além disso, foi adicionada a capacidade de deletar templates por ID.

Arquivos modificados:
- whatsapp.business.service.ts
- template.service.ts
2024-07-12 12:55:16 -03:00
Davidson Gomes
26bddf3c53 Add support for managing WhatsApp templates via official API
This commit introduces changes to support managing WhatsApp templates using the official WhatsApp Business API. The following modifications have been made:

- Implemented a new Template model in the Prisma schema, including fields for template ID, name, language, and associated Instance (business ID, instance ID, and created/updated timestamps).
- Modified the Instance model in the Prisma schema to include a Template relationship.
- Updated InstanceController to include a new `businessId` property in the InstanceDto.
- Added a new TemplateRouter, TemplateController, and TemplateService to handle template-related requests and services.
- Updated the WebhookService to utilize the new TemplateService.
- Added new TypebotController, WebhookController, and WAMonitoringService methods to handle template-related events.
- Updated the validate schema to include a new template schema.

The main goal of this commit is to enable managing WhatsApp templates, including creating, updating, and deleting templates, as well as associating them with specific instances.
2024-07-12 12:32:44 -03:00
Davidson Gomes
a145935366 chore: Add businessId to Instance model
Updated the Instance model to include a new optional string property called businessId. This change affects the following files:

- prisma/postgresql-schema.prisma
- src/api/controllers/instance.controller.ts
- src/api/dto/instance.dto.ts
- src/api/services/monitor.service.ts
- src/validate/instance.schema.ts

A new untracked migration folder has been created to manage database schema updates:

- prisma/migrations/20240712144948_add_business_id_column_to_instances/

This change allows for storing a business identifier alongside the instance, enhancing the ability to categorize and manage instances more effectively.
2024-07-12 11:52:29 -03:00
Davidson Gomes
f6d4f940a3 chore: Update cloud API message sending for lists and buttons
This commit updates the way messages are sent to the cloud API for lists and buttons,
adjusting the structure of the request payload. The affected files include:
- sendMessage.dto.ts: updates the format of the Button class
- sendMessage.router.ts: adds a new route for sending button messages
- whatsapp.business.service.ts: updates the handling of list and button messages
- message.schema.ts: adds a new schema for button messages

These changes improve the integration with the cloud API and allow for better handling of lists and buttons in messages.
2024-07-12 09:40:15 -03:00
Davidson Gomes
4737c71ae1 refactor: change webhook reception for all instances
This commit refactors the webhook reception to handle all instances at once. Previously, each instance had its own webhook endpoint, but now there is a single endpoint for all instances. This change simplifies the codebase and reduces the potential for errors.

The main changes include:
- Modifying the `InstanceController` to update the webhook URL for all instances.
- Modifying the `WebhookController` to handle the reception of webhooks for all instances.
- Modifying the `IndexRouter` and `WebhookRouter` to add a new route for the webhook reception endpoint.
- Modifying the `ServerModule` to inject the `PrismaRepository` into the `WebhookService`.
- Modifying the `WebhookService` to handle the reception of webhooks for all instances.

These changes improve the maintainability and scalability of the application, as there is no longer a need to manage individual webhook endpoints for each instance.
2024-07-12 08:52:18 -03:00
Davidson Gomes
90e03e6d1e ajuste 2024-07-03 18:58:57 -03:00
Davidson Gomes
3637b95f8f chore: Update Dockerfile and whatsapp.baileys.service.ts
Update and modifications in Dockerfile and src/api/services/channels/whatsapp.baileys.service.ts files. These changes improve the performance and maintainability of the Node.js project.
2024-07-03 18:35:12 -03:00
Davidson Gomes
b3a0899f4f chore: Update GitHub actions workflow
Update the GitHub actions workflow file to improve the CI/CD pipeline. The changes include modifying the existing `publish_docker_image_v2.yml` file. These changes ensure the project's version 2.0.0 remains up-to-date and compatible with the latest GitHub actions and Docker image publishing process.
2024-07-03 18:04:52 -03:00
Davidson Gomes
ebc78d63ac chore: Update GitHub Actions workflow in v2.0.0
Update to the GitHub Actions workflow in the v2.0.0 branch. This change modifies the
`.github/workflows/publish_docker_image_v2.yml` file, which is part of the CI/CD
pipeline for publishing Docker images. The specific modifications and their impact
are not detailed in the provided information.
2024-07-03 18:01:34 -03:00
Davidson Gomes
7e48f1bba1 chore: Update WhatsApp Baileys service
Updated the WhatsApp Baileys service at 'src/api/services/channels/whatsapp.baileys.service.ts' to improve test coverage and reliability. This change does not alter the functionality of the service but enhances its maintainability.
2024-07-03 17:59:43 -03:00
Davidson Gomes
aab62e4b03 chore: Update CHANGELOG, Dockerfile and add CI workflow for publishing latest Docker image
- Update CHANGELOG.md to include the new Docker workflow
- Update Dockerfile to improve the build process
- Add a new GitHub Actions workflow (.github/workflows/publish\_docker\_image\_latest.yml) to publish the latest Docker image on push to the 'v2.0.0' branch

This change allows for easier deployment of the latest version of the application, with an updated Dockerfile and a new GitHub Actions workflow to handle publishing the Docker image.
2024-07-03 17:25:38 -03:00
Davidson Gomes
6cea02252e chore: Clear logs in Whatsapp Baileys Service
This commit removes console logs from the Whatsapp Baileys Service in the `whatsapp.baileys.service.ts` file. The logs that were removed were not necessary for the functionality of the service and were only used for debugging purposes. By removing them, we improve the performance and readability of the code.

Modified files:
- src/api/services/channels/whatsapp.baileys.service.ts
2024-07-03 13:22:09 -03:00
Davidson Gomes
8e72983304 fix: Correction in the generation of the queue name 'rabbit'
Fixes a bug in the generation of the 'rabbit' queue name in the 'channel.service.ts' file. The variable 'transformedWe' was replaced by 'event' to generate the queue name. This ensures that the queue name is generated correctly, avoiding possible errors or malfunctions in the system.
2024-06-30 11:25:12 -03:00
Davidson Gomes
b5683aed2a chore: Update 'baileys' dependency to use 'EvolutionAPI' repository
The 'baileys' dependency in the 'package.json' file has been updated to use the 'EvolutionAPI' repository instead of 'WhiskeySockets'. This change ensures that the latest version of 'baileys' is used, which includes improvements in group message sending and cache utilization.

Modified files:
- package.json
2024-06-27 17:49:48 -03:00
Davidson Gomes
228dcf8aa5 chore: Improve code consistency and readability
Refactored the initialization of `LocalSettings` in `channel.service.ts` to only set the properties that have been explicitly provided. This refactoring improves code consistency and readability. Also, removed the unused `initStoreFolders` method from `repository.service.ts` and its related imports. In addition, updated the import style for `PrismaClient` in `repository.service.ts`.

The modified files are:
- src/api/controllers/instance.controller.ts
- src/api/repository/repository.service.ts
- src/api/services/channel.service.ts
- src/api/services/channels/whatsapp.baileys.service.ts
2024-06-27 09:01:02 -03:00
Davidson Gomes
457628b996 fix: Adjusted group message sending with cache improvement
This commit addresses an adjustment in the process of sending messages to groups, with a focus on improving cache utilization. The main modifications include:

- Updated 'package.json' to use the latest 'baileys' version from 'WhiskeySockets' repository.
- Modified 'src/api/services/channels/whatsapp.baileys.service.ts' for better handling of group metadata cache.

The force update group metadata cache function has been removed to streamline the codebase and improve cache handling. This change will ensure that group metadata is updated more efficiently and reduce the overall processing time.
2024-06-27 02:02:34 -03:00
Davidson Gomes
5ea276398f chore: Improve performance of status update and message sending in groups
The performance of sending status updates and messages in groups has been significantly improved. The batch size for sending messages has been reduced from 200 to 1, which allows for more efficient processing.

The `whatsapp.baileys.service.ts` file has been modified to implement this change. The previous batch size was set to 200, which has been updated to 1. This change reduces the number of participants processed in each batch, resulting in improved performance.

This modification also includes a conditional statement to ensure that no further processing is performed when there are no more batches left. This enhancement aims to optimize the overall process of sending status updates and messages in groups.
2024-06-26 23:22:51 -03:00
Davidson Gomes
d342a7b621 chore: Refactor WAMonitoringService instance retrieval and improve code readability
Refactored WAMonitoringService to retrieve instances using Prisma's `findMany` method with a dynamic `where` clause.
This change simplifies the code and makes it more maintainable.
It also removes the deprecated `for...of` loop and the unnecessary instantiation of objects.
The new implementation provides better performance and is more aligned with the current best practices.

Modified files:
- src/api/services/monitor.service.ts
2024-06-26 19:27:06 -03:00
Davidson Gomes
b70ab5a4c3 fix: Update message function to support different message types
The updateMessage function was updated to support different message types such as text, image, and video.
A new private function formatUpdateMessage was added to handle the logic of formatting the message based on its type.
The function checks the message type and returns the corresponding format for the message.
If the message type is not supported, it will return null and throw a BadRequestException.
The createJid function is now called in the updateMessage function to get the jid of the recipient.
This change improves the flexibility of the updateMessage function and ensures that it can handle different types of messages.
2024-06-26 18:23:18 -03:00
Davidson Gomes
6cb3357f08 fix: Correction in WhatsApp sticker sending
Corrected an issue where stickers were not being sent properly in WhatsApp channels. The bug was caused by a mistake in the 'src/api/services/channels/whatsapp.baileys.service.ts' file. This fix resolves the problem and ensures that stickers are sent correctly in WhatsApp channels.
2024-06-26 17:52:51 -03:00
Davidson Gomes
99f4fe2e43 fix: Ghost emoji correction in message sending
Corrects an issue where a ghost emoji was being displayed in message sending. The 'Mentions' class was removed and its properties were moved to the 'Options' class. The 'everyOne' and 'mentioned' properties were replaced by 'mentionsEveryOne' and 'mentioned', respectively. This change improves the code readability and maintainability.

The affected files are:
- src/api/dto/sendMessage.dto.ts
- src/api/services/channels/whatsapp.baileys.service.ts
- src/api/services/channels/whatsapp.business.service.ts
2024-06-26 17:27:38 -03:00
Davidson Gomes
0ded76d366 chore: Recover lost messages from cache in WhatsApp Baileys service 2024-06-26 16:57:55 -03:00
Davidson Gomes
a737fed5cb chore: Updated WhatsApp baileys service
Modified the WhatsApp baileys service to improve the overall functionality. This change aims to enhance the user experience and maintain code quality.

Please note that only the 'src/api/services/channels/whatsapp.baileys.service.ts' file has been modified.
2024-06-26 16:13:21 -03:00
Davidson Gomes
79cadadcc7 chore: Update group metadata cache (#GI234)
- Updated the group metadata cache to improve performance.
- Added verbose logging for cache updates and requests.
- Affected file: `whatsapp.baileys.service.ts`.

Please note that this change does not alter the functionality or behavior of the application. It is a maintenance task to optimize cache management.
2024-06-26 15:38:04 -03:00
Davidson Gomes
75922e603b chore: Update group metadata cache on participants update
Refactored WhatsappBaileysService to update group metadata cache when a participants update event is triggered. This will improve the accuracy of the group metadata and ensure that it stays up-to-date with the latest changes in the group.

Modified:
- src/api/services/channels/whatsapp.baileys.service.ts
2024-06-26 15:23:06 -03:00
Davidson Gomes
d0eee796ba fix: Resolve generation of pairing code
In this commit, we have fixed an issue related to the generation of the pairing code. The changes include modifying the `whatsapp.baileys.service.ts` file, where we have updated the `connectToWhatsapp` method to accept a phone number parameter. Additionally, we have made changes to the `browser` variable to handle phone number and browser options. These changes improve the reliability of the pairing code generation.
2024-06-26 13:55:11 -03:00
Davidson Gomes
47d6fd5d31 chore: Update privacy settings, refactor code and improve performance
In this commit, several changes were made to improve the codebase and update privacy settings. Specifically, the following changes were made:

- The `PrivacySetting` class was refactored to `PrivacySettingDto` in `chat.dto.ts`.
- The `put` method was changed to `post` in `chat.router.ts` for updating the profile picture.
- Several methods in `channel.service.ts` were refactored to improve performance and readability. Specifically, the `setWebhook`, `setRabbitmq`, `setSqs`, `fetchContacts`, and `fetchMessages` methods were improved.
- The `updatePrivacySettings` method in `whatsapp.baileys.service.ts` was refactored to reduce complexity and improve readability.

These changes were made to improve the overall performance and maintainability of the codebase. Additionally, the privacy settings for the WhatsApp client were updated to provide better control over user data.
2024-06-26 08:08:12 -03:00
Davidson Gomes
4120318ec4 feat: update dependencies and improve channel services
Updated dependencies in package.json to ensure compatibility and performance. Enhanced functionality in channel.service.ts and whatsapp.baileys.service.ts for better service handling and reliability. This update aims to improve overall system stability and performance.
2024-06-18 11:28:10 -03:00
Davidson Gomes
4349959daa Merge pull request #647 from francisbreit/evolution-api-v2.0.0-alpha-fr1
Update criador_de_inbox.json for Evolution v2.0
2024-06-17 14:28:38 -03:00
Davidson Gomes
549224ac16 fix: update WhatsApp Baileys service
Modified the WhatsApp Baileys service in channels to fix an issue. This change addresses a bug that was causing incorrect message handling. The update ensures more reliable communication through the WhatsApp API.
2024-06-17 13:48:46 -03:00
Davidson Gomes
d45e303d55 fix: add TypeScript types to use-multi-file-auth-state-prisma.ts functions
Added TypeScript types to functions in use-multi-file-auth-state-prisma.ts to improve type safety and code readability. This change helps catch type-related errors during development and enhances the maintainability of the codebase.
2024-06-17 13:42:18 -03:00
Davidson Gomes
85106667a2 feat: update message sending logic
Refactored sendMessage.controller.ts, chat.dto.ts, and sendMessage.dto.ts to improve message handling. Updated chatwoot.service.ts and sendMessage.router.ts for better integration with Chatwoot. Enhanced whatsapp.baileys.service.ts for more reliable WhatsApp communication. Adjusted chat.schema.ts and message.schema.ts for validation improvements. These changes enhance the overall messaging functionality and reliability.
2024-06-15 12:46:52 -03:00
Francis Breit
371ab944b3 Update criador_de_inbox.json for Evolution v2.0
Update criador_de_inbox.json for Evolution v2.0
2024-06-14 13:16:42 -03:00
Davidson Gomes
2d49c73023 fix: add validation to prevent group calls in whatsapp.baileys.service.ts
Added a check to prevent group calls by throwing a BadRequestException when a group JID is detected. This change ensures that only individual calls are processed, preventing unsupported group call attempts and improving error handling.
2024-06-14 09:45:02 -03:00
Davidson Gomes
92a0d8ccc9 feat: update API routes and services for better cache handling
Modified instance.router.ts to change HTTP method from PUT to POST for 'restart' route. Updated whatsapp.baileys.service.ts to correct cache configuration logic, ensuring proper usage of cached group metadata. Removed obsolete Typebot-related schema definitions from instance.schema.ts for cleaner validation. These changes improve API functionality and maintainability.
2024-06-14 09:25:18 -03:00
Davidson Gomes
7dfc09ff16 feat: update Baileys library and add fake call feature
Updated the Baileys library reference in package.json and refactored imports across multiple files to use the new library. Added a new feature to handle fake calls in sendMessage.controller.ts and related DTOs. This change improves the integration with the Baileys library and introduces the ability to simulate calls, enhancing the testing capabilities. Main files modified: package.json, instance.controller.ts, sendMessage.controller.ts, chat.dto.ts, instance.dto.ts, sendMessage.dto.ts, chatwoot.service.ts, chatwoot-import-helper.ts, sendMessage.router.ts, cache.service.ts, channel.service.ts, whatsapp.baileys.service.ts, whatsapp.business.service.ts, wa.types.ts, rediscache.ts, use-multi-file-auth-state-prisma.ts, use-multi-file-auth-state-provider-files.ts, use-multi-file-auth-state-redis-db.ts, message.schema.ts.
2024-06-14 08:44:19 -03:00
Davidson Gomes
61d6ddfa81 fix: update default values for WA_BUSINESS configuration
Updated the default values for TOKEN_WEBHOOK, URL, and VERSION in the WA_BUSINESS configuration. This change ensures that the application has more meaningful default settings, improving the initial setup experience. The impact is limited to default behavior when environment variables are not set.
2024-06-13 18:53:20 -03:00
Davidson Gomes
06ba1fd17b chore: update baileys version in package.json
Updated the baileys version in package.json to ensure compatibility with the latest features and bug fixes. This change is necessary to maintain the stability and performance of the application.
2024-06-12 18:56:17 -03:00
Davidson Gomes
f1c31a70bc fix: adjust settings in whatsapp.baileys.service.ts
Increased retryRequestDelayMs, added maxMsgRetryCount, and updated connectTimeoutMs and qrTimeout values for better performance. Adjusted transactionOpts for more efficient retries. These changes aim to enhance connection stability and message handling efficiency.
2024-06-12 18:39:57 -03:00
Davidson Gomes
7799e6626f fix: baileys ignore newsletter 2024-06-12 15:42:37 -03:00
Davidson Gomes
aa79c1bfd7 feat: tagging in chatwoot contact by instance 2024-06-12 15:18:37 -03:00
Davidson Gomes
7451b0d1e3 feat: tagging in chatwoot contact by instance 2024-06-12 15:18:26 -03:00
Davidson Gomes
18d4c68025 fix: messageId baileys 2024-06-12 11:23:51 -03:00
Davidson Gomes
a7887f0b1c fix: messageId baileys 2024-06-12 09:55:40 -03:00
Davidson Gomes
fa14b7b1a9 feat: Added debounce time for typebot messages 2024-06-11 17:56:45 -03:00
Davidson Gomes
2776f113cb feat: Added debounce time for typebot messages 2024-06-11 17:56:20 -03:00
Davidson Gomes
0bf8e55144 fix: provider variables are no longer mandatory in the env 2024-06-11 13:06:35 -03:00
Davidson Gomes
87c68df0f6 fix: provider variables are no longer mandatory in the env 2024-06-11 12:40:00 -03:00
Davidson Gomes
f551242e86 fix: reply message 2024-06-11 11:07:49 -03:00
Davidson Gomes
31258a9b85 feat: Organization configuration and logo in chatwoot bot contact 2024-06-11 10:09:04 -03:00
Davidson Gomes
a8937bd8b1 fix: get message id for typebot 2024-06-10 18:32:05 -03:00
Davidson Gomes
fa3306b0f4 adjusts in typebot 2024-06-10 16:38:11 -03:00
Davidson Gomes
4824ccafd6 fix: get base64 for media message 2024-06-10 15:55:40 -03:00
Davidson Gomes
f40cdb62ba fix: get message id for typebot 2024-06-10 15:48:48 -03:00
Davidson Gomes
8c6e1a579f fix: reply with media message 2024-06-10 15:15:13 -03:00
Davidson Gomes
95022578ba fix: reply with media message 2024-06-10 15:03:41 -03:00
Davidson Gomes
99999eae5d fix: reply with media message 2024-06-10 14:50:03 -03:00
Davidson Gomes
2eb09c1853 fix: reply with media message 2024-06-10 14:49:46 -03:00
Davidson Gomes
99ebb81838 chore: Dockerfile 2024-06-10 14:16:40 -03:00
Davidson Gomes
6d6f7293f9 fix: audio convertion with stream to mp4 2024-06-10 14:01:07 -03:00
Davidson Gomes
9cd50833cf fix: audio convertion with stream 2024-06-10 13:15:24 -03:00
Davidson Gomes
c1cbc0d30c test: audio convertion 2024-06-10 13:01:38 -03:00
Davidson Gomes
ed6e28744e test: audio convertion 2024-06-10 12:34:06 -03:00
Davidson Gomes
28e5b2f65e fix: instances 2024-06-10 11:52:19 -03:00
Davidson Gomes
4879bdb527 fix: instances 2024-06-10 11:33:36 -03:00
Davidson Gomes
7ebf237c1c fix: init store folders 2024-06-10 11:28:28 -03:00
Davidson Gomes
21d984969a fix: Correction of audio sending, now we can speed it up and have the audio wireframe 2024-06-10 07:45:43 -03:00
Davidson Gomes
b3adedca0b docker 2024-06-09 21:56:43 -03:00
Davidson Gomes
f6cca7df92 docker 2024-06-09 21:54:10 -03:00
Davidson Gomes
1737e61d60 docker 2024-06-09 21:51:12 -03:00
Davidson Gomes
dae04c5a2f docker 2024-06-09 21:43:53 -03:00
Davidson Gomes
7b2f8fa5e1 docker 2024-06-09 21:23:09 -03:00
Davidson Gomes
11a52c3f43 docker 2024-06-09 17:38:45 -03:00
Davidson Gomes
d61d5e9631 docker 2024-06-09 17:35:05 -03:00
Davidson Gomes
2e61de5297 docker 2024-06-09 17:31:47 -03:00
Davidson Gomes
b7936d77f5 docker 2024-06-09 17:11:45 -03:00
Davidson Gomes
184009bc4b docker 2024-06-09 16:54:44 -03:00
Davidson Gomes
8369b857da docker 2024-06-09 16:51:47 -03:00
Davidson Gomes
585692cae3 git actions v2 2024-06-09 16:15:44 -03:00
Davidson Gomes
56950bc274 git actions v2 2024-06-09 15:07:56 -03:00
Davidson Gomes
e132434846 git actions v2 2024-06-09 15:03:15 -03:00
Davidson Gomes
5abb94f187 git actions v2 2024-06-09 14:57:49 -03:00
Davidson Gomes
a2dbfed19c git actions v2 2024-06-09 14:55:20 -03:00
Davidson Gomes
7dd4d8ae86 git actions v2 2024-06-09 14:53:48 -03:00
Davidson Gomes
6c8e84eed4 git actions v2 2024-06-09 14:50:22 -03:00
Davidson Gomes
14e7a68c32 git actions v2 2024-06-09 14:49:09 -03:00
Davidson Gomes
71a97e047a git actions v2 2024-06-09 14:41:02 -03:00
Davidson Gomes
35aa19853c git actions v2 2024-06-09 14:31:22 -03:00
Davidson Gomes
caf8d0c826 git actions v2 2024-06-09 14:26:23 -03:00
Davidson Gomes
43c8842dc6 git actions v2 2024-06-09 14:24:57 -03:00
Davidson Gomes
9e25904dc9 Review integration with official WhatsApp API 2024-06-09 14:18:19 -03:00
Davidson Gomes
585bf84af4 Adjust search for chats, messages and contacts 2024-06-09 09:28:15 -03:00
Davidson Gomes
620cd8b06b readme 2024-06-09 08:58:22 -03:00
Davidson Gomes
828ac2f383 Merge branch 'develop' into v2.0.0 2024-06-09 08:55:22 -03:00
Davidson Gomes
9f1c2e4e5f MySQL implementation via prism orm 2024-06-09 08:51:51 -03:00
Davidson Gomes
72de0a6e4d Chatwoot review and improvements 2024-06-09 08:44:06 -03:00
Davidson Gomes
3342a22cc7 sync history set 2024-06-08 22:27:26 -03:00
Davidson Gomes
81a62373f8 changelog 2024-06-08 21:32:01 -03:00
Davidson Gomes
e7b0bb53b9 changelog 2024-06-08 21:30:38 -03:00
Davidson Gomes
49daf5719b changelog 2024-06-08 21:24:33 -03:00
Davidson Gomes
ee9cdc51c0 adjusts in typebot 2024-06-08 19:22:12 -03:00
Davidson Gomes
b7a34ec81a adjusts in keepOpen typebot 2024-06-08 19:10:01 -03:00
Davidson Gomes
9178fd74a9 changelog 2024-06-08 19:05:16 -03:00
Davidson Gomes
fe9803b828 feat: Now you can register several typebots with triggers 2024-06-08 19:04:57 -03:00
Davidson Gomes
56df0caab0 fix: now in typebot we wait until the terminal block to accept the user's message, if it arrives before the block is sent, it is ignored 2024-06-08 15:09:55 -03:00
Davidson Gomes
ff31ef912e readme 2024-06-08 14:05:57 -03:00
Davidson Gomes
360d378c33 readme 2024-06-08 14:04:45 -03:00
Davidson Gomes
be65b93d59 fix: Correction of variables breaking lines in typebot 2024-06-08 13:41:44 -03:00
Davidson Gomes
de89f03f13 integrations 2024-06-08 10:31:52 -03:00
Davidson Gomes
cbb5d1d048 integrations: adjusts in payloads 2024-06-07 19:16:51 -03:00
Davidson Gomes
2cb6bdb38b readme 2024-06-07 13:31:23 -03:00
Davidson Gomes
da687041af prisma orm: mysql 2024-06-07 13:30:29 -03:00
Davidson Gomes
52c1394ce2 readme 2024-06-07 13:12:46 -03:00
Davidson Gomes
cf2ebdad63 todo 2024-06-07 13:03:03 -03:00
Davidson Gomes
dbb309eaa0 changelog 2024-06-07 13:00:54 -03:00
Davidson Gomes
8fd082ad80 chore: Simplified payloads and endpoints 2024-06-07 13:00:35 -03:00
Davidson Gomes
a578384e85 chore: Simplified payloads and instance endpoint 2024-06-07 11:09:08 -03:00
Davidson Gomes
eed32a3bd9 chore: optimization in instance registration 2024-06-07 08:28:22 -03:00
Davidson Gomes
0bb9940d05 changelog 2024-06-06 18:45:42 -03:00
Davidson Gomes
ea0ef20979 changelog 2024-06-06 18:43:15 -03:00
Davidson Gomes
85b0627737 adjustis in instance controller 2024-06-06 18:30:45 -03:00
Davidson Gomes
bdd1b8fa21 log: removed excessive verbose logs 2024-06-06 18:04:45 -03:00
Davidson Gomes
51c873c19e prisma orm: all endpoints ok 2024-06-06 17:01:48 -03:00
Davidson Gomes
161814a9e5 added typebot integration activation 2024-06-06 16:44:18 -03:00
Davidson Gomes
1be9c7f95d added chatwoot integration activation 2024-06-06 16:38:43 -03:00
Davidson Gomes
99c8cc0242 prima orm: instance controller ok 2024-06-06 16:14:22 -03:00
Davidson Gomes
b309d686ec version: 2.0.0 2024-06-06 14:56:18 -03:00
Davidson Gomes
36ec67cef9 feat: prisma and remove mongodb 2024-06-06 14:47:58 -03:00
Davidson Gomes
35f97e08dd feat: prisma 2024-06-06 01:13:23 -03:00
Davidson Gomes
272bed1351 feat: prisma 2024-06-06 01:08:24 -03:00
425 changed files with 59489 additions and 20676 deletions

BIN
.DS_Store vendored

Binary file not shown.

107
.cursor/rules/README.md Normal file
View File

@@ -0,0 +1,107 @@
# Evolution API Cursor Rules
Este diretório contém as regras e configurações do Cursor IDE para o projeto Evolution API.
## Estrutura dos Arquivos
### Arquivos Principais (alwaysApply: true)
- **`core-development.mdc`** - Princípios fundamentais de desenvolvimento
- **`project-context.mdc`** - Contexto específico do projeto Evolution API
- **`cursor.json`** - Configurações do Cursor IDE
### Regras Especializadas (alwaysApply: false)
Estas regras são ativadas automaticamente quando você trabalha nos arquivos correspondentes:
#### Camadas da Aplicação
- **`specialized-rules/service-rules.mdc`** - Padrões para services (`src/api/services/`)
- **`specialized-rules/controller-rules.mdc`** - Padrões para controllers (`src/api/controllers/`)
- **`specialized-rules/dto-rules.mdc`** - Padrões para DTOs (`src/api/dto/`)
- **`specialized-rules/guard-rules.mdc`** - Padrões para guards (`src/api/guards/`)
- **`specialized-rules/route-rules.mdc`** - Padrões para routers (`src/api/routes/`)
#### Tipos e Validação
- **`specialized-rules/type-rules.mdc`** - Definições TypeScript (`src/api/types/`)
- **`specialized-rules/validate-rules.mdc`** - Schemas de validação (`src/validate/`)
#### Utilitários
- **`specialized-rules/util-rules.mdc`** - Funções utilitárias (`src/utils/`)
#### Integrações
- **`specialized-rules/integration-channel-rules.mdc`** - Integrações de canal (`src/api/integrations/channel/`)
- **`specialized-rules/integration-chatbot-rules.mdc`** - Integrações de chatbot (`src/api/integrations/chatbot/`)
- **`specialized-rules/integration-storage-rules.mdc`** - Integrações de storage (`src/api/integrations/storage/`)
- **`specialized-rules/integration-event-rules.mdc`** - Integrações de eventos (`src/api/integrations/event/`)
## Como Usar
### Referências Cruzadas
Os arquivos principais fazem referência aos especializados usando a sintaxe `@specialized-rules/nome-do-arquivo.mdc`. Quando você trabalha em um arquivo específico, o Cursor automaticamente carrega as regras relevantes.
### Exemplo de Uso
Quando você edita um arquivo em `src/api/services/`, o Cursor automaticamente:
1. Carrega `core-development.mdc` (sempre ativo)
2. Carrega `project-context.mdc` (sempre ativo)
3. Carrega `specialized-rules/service-rules.mdc` (ativado pelo glob pattern)
### Padrões de Código
Cada arquivo de regras contém:
- **Estruturas padrão** - Como organizar o código
- **Padrões de nomenclatura** - Convenções de nomes
- **Exemplos práticos** - Código de exemplo
- **Anti-padrões** - O que evitar
- **Testes** - Como testar o código
- **Padrões de Commit** - Conventional Commits com commitlint
## Configuração do Cursor
O arquivo `cursor.json` contém:
- Configurações de formatação
- Padrões de código específicos do Evolution API
- Diretórios principais do projeto
- Integrações e tecnologias utilizadas
## Manutenção
Para manter as regras atualizadas:
1. Analise novos padrões no código
2. Atualize as regras especializadas correspondentes
3. Mantenha os exemplos sincronizados com o código real
4. Documente mudanças significativas
## Tecnologias Cobertas
- **Backend**: Node.js 20+ + TypeScript 5+ + Express.js
- **Database**: Prisma ORM (PostgreSQL/MySQL)
- **Cache**: Redis + Node-cache
- **Queue**: RabbitMQ + Amazon SQS
- **Real-time**: Socket.io
- **Storage**: AWS S3 + Minio
- **Validation**: JSONSchema7
- **Logging**: Pino
- **WhatsApp**: Baileys + Meta Business API
- **Integrations**: Chatwoot, Typebot, OpenAI, Dify
## Estrutura do Projeto
```
src/
├── api/
│ ├── controllers/ # Controllers (HTTP handlers)
│ ├── services/ # Business logic
│ ├── dto/ # Data Transfer Objects
│ ├── guards/ # Authentication/Authorization
│ ├── routes/ # Express routers
│ ├── types/ # TypeScript definitions
│ └── integrations/ # External integrations
│ ├── channel/ # WhatsApp channels (Baileys, Business API)
│ ├── chatbot/ # Chatbot integrations
│ ├── event/ # Event integrations
│ └── storage/ # Storage integrations
├── cache/ # Cache implementations
├── config/ # Configuration files
├── utils/ # Utility functions
├── validate/ # Validation schemas
└── exceptions/ # Custom exceptions
```
Este sistema de regras garante consistência no código e facilita o desenvolvimento seguindo os padrões estabelecidos do Evolution API.

View File

@@ -0,0 +1,167 @@
---
description: Core development principles and standards for Evolution API development
globs:
alwaysApply: true
---
# Evolution API Development Standards
## Cross-References
- **Project Context**: @project-context.mdc for Evolution API-specific patterns
- **Specialized Rules**:
- @specialized-rules/service-rules.mdc for service layer patterns
- @specialized-rules/controller-rules.mdc for controller patterns
- @specialized-rules/dto-rules.mdc for DTO validation patterns
- @specialized-rules/guard-rules.mdc for authentication/authorization
- @specialized-rules/route-rules.mdc for router patterns
- @specialized-rules/type-rules.mdc for TypeScript definitions
- @specialized-rules/util-rules.mdc for utility functions
- @specialized-rules/validate-rules.mdc for validation schemas
- @specialized-rules/integration-channel-rules.mdc for channel integrations
- @specialized-rules/integration-chatbot-rules.mdc for chatbot integrations
- @specialized-rules/integration-storage-rules.mdc for storage integrations
- @specialized-rules/integration-event-rules.mdc for event integrations
- **TypeScript/Node.js**: Node.js 20+ + TypeScript 5+ best practices
- **Express/Prisma**: Express.js + Prisma ORM patterns
- **WhatsApp Integrations**: Baileys + Meta Business API patterns
## Senior Engineer Context - Evolution API Platform
- You are a senior software engineer working on a WhatsApp API platform
- Focus on Node.js + TypeScript + Express.js full-stack development
- Specialized in real-time messaging, WhatsApp integrations, and event-driven architecture
- Apply scalable patterns for multi-tenant API platform
- Consider WhatsApp integration workflow implications and performance at scale
## Fundamental Principles
### Code Quality Standards
- **Simplicity First**: Always prefer simple solutions over complex ones
- **DRY Principle**: Avoid code duplication - check for existing similar functionality before implementing
- **Single Responsibility**: Each function/class should have one clear purpose
- **Readable Code**: Write code that tells a story - clear naming and structure
### Problem Resolution Approach
- **Follow Existing Patterns**: Use established Service patterns, DTOs, and Integration patterns
- **Event-Driven First**: Leverage EventEmitter2 for event publishing when adding new features
- **Integration Pattern**: Follow existing WhatsApp integration patterns for new channels
- **Conservative Changes**: Prefer extending existing services over creating new architecture
- **Clean Migration**: Remove deprecated patterns when introducing new ones
- **Incremental Changes**: Break large changes into smaller, testable increments with proper migrations
### File and Function Organization - Node.js/TypeScript Structure
- **Services**: Keep services focused and under 200 lines
- **Controllers**: Keep controllers thin - only routing and validation
- **DTOs**: Use JSONSchema7 for all input validation
- **Integrations**: Follow `src/api/integrations/` structure for new integrations
- **Utils**: Extract common functionality into well-named utilities
- **Types**: Define clear TypeScript interfaces and types
### Code Analysis and Reflection
- After writing code, deeply reflect on scalability and maintainability
- Provide 1-2 paragraph analysis of code changes
- Suggest improvements or next steps based on reflection
- Consider performance, security, and maintenance implications
## Development Standards
### TypeScript Standards
- **Strict Mode**: Always use TypeScript strict mode
- **No Any**: Avoid `any` type - use proper typing
- **Interfaces**: Define clear contracts with interfaces
- **Enums**: Use enums for constants and status values
- **Generics**: Use generics for reusable components
### Error Handling Standards
- **HTTP Exceptions**: Use appropriate HTTP status codes
- **Logging**: Structured logging with context
- **Retry Logic**: Implement retry for external services
- **Graceful Degradation**: Handle service failures gracefully
### Security Standards
- **Input Validation**: Validate all inputs with JSONSchema7
- **Authentication**: Use API keys and JWT tokens
- **Rate Limiting**: Implement rate limiting for APIs
- **Data Sanitization**: Sanitize sensitive data in logs
### Performance Standards
- **Caching**: Use Redis for frequently accessed data
- **Database**: Optimize Prisma queries with proper indexing
- **Memory**: Monitor memory usage and implement cleanup
- **Async**: Use async/await properly with error handling
## Communication Standards
### Language Requirements
- **User Communication**: Always respond in Portuguese (PT-BR)
- **Code Comments**: English for technical documentation
- **API Documentation**: English for consistency
- **Error Messages**: Portuguese for user-facing errors
### Documentation Standards
- **Code Comments**: Document complex business logic
- **API Documentation**: Document all public endpoints
- **README**: Keep project documentation updated
- **Changelog**: Document breaking changes
## Quality Assurance
### Testing Standards
- **Unit Tests**: Test business logic in services
- **Integration Tests**: Test API endpoints
- **Mocks**: Mock external dependencies
- **Coverage**: Aim for 70%+ test coverage
### Code Review Standards
- **Peer Review**: All code must be reviewed
- **Automated Checks**: ESLint, Prettier, TypeScript
- **Security Review**: Check for security vulnerabilities
- **Performance Review**: Check for performance issues
### Commit Standards (Conventional Commits)
- **Format**: `type(scope): subject` (max 100 characters)
- **Types**:
- `feat` - New feature
- `fix` - Bug fix
- `docs` - Documentation changes
- `style` - Code style changes (formatting, etc)
- `refactor` - Code refactoring
- `perf` - Performance improvements
- `test` - Adding or updating tests
- `chore` - Maintenance tasks
- `ci` - CI/CD changes
- `build` - Build system changes
- `revert` - Reverting changes
- `security` - Security fixes
- **Examples**:
- `feat(api): add WhatsApp message status endpoint`
- `fix(baileys): resolve connection timeout issue`
- `docs(readme): update installation instructions`
- `refactor(service): extract common message validation logic`
- **Tools**: Use `npm run commit` (Commitizen) for guided commits
- **Validation**: Enforced by commitlint on commit-msg hook
## Evolution API Specific Patterns
### WhatsApp Integration Patterns
- **Connection Management**: One connection per instance
- **Event Handling**: Proper event listeners for Baileys
- **Message Processing**: Queue-based message processing
- **Error Recovery**: Automatic reconnection logic
### Multi-Database Support
- **Schema Compatibility**: Support PostgreSQL and MySQL
- **Migration Sync**: Keep migrations synchronized
- **Type Safety**: Use Prisma generated types
- **Connection Pooling**: Proper database connection management
### Cache Strategy
- **Redis Primary**: Use Redis for distributed caching
- **Local Fallback**: Node-cache for local fallback
- **TTL Strategy**: Appropriate TTL for different data types
- **Cache Invalidation**: Proper cache invalidation patterns
### Event System
- **EventEmitter2**: Use for internal events
- **WebSocket**: Socket.io for real-time updates
- **Queue Systems**: RabbitMQ/SQS for async processing
- **Webhook Processing**: Proper webhook validation and processing

179
.cursor/rules/cursor.json Normal file
View File

@@ -0,0 +1,179 @@
{
"version": "1.0",
"description": "Cursor IDE configuration for Evolution API project",
"rules": {
"general": {
"max_line_length": 120,
"indent_size": 2,
"end_of_line": "lf",
"charset": "utf-8",
"trim_trailing_whitespace": true,
"insert_final_newline": true
},
"typescript": {
"quotes": "single",
"semi": true,
"trailing_comma": "es5",
"bracket_spacing": true,
"arrow_parens": "avoid",
"print_width": 120,
"tab_width": 2,
"use_tabs": false,
"single_quote": true,
"end_of_line": "lf",
"strict": true,
"no_implicit_any": true,
"strict_null_checks": true
},
"javascript": {
"quotes": "single",
"semi": true,
"trailing_comma": "es5",
"bracket_spacing": true,
"arrow_parens": "avoid",
"print_width": 120,
"tab_width": 2,
"use_tabs": false,
"single_quote": true,
"end_of_line": "lf",
"style_guide": "eslint-airbnb"
},
"json": {
"tab_width": 2,
"use_tabs": false,
"parser": "json"
},
"ignore": {
"files": [
"node_modules/**",
"dist/**",
"build/**",
".git/**",
"*.min.js",
"*.min.css",
".env",
".env.*",
".env.example",
"coverage/**",
"*.log",
"*.lock",
"pnpm-lock.yaml",
"package-lock.json",
"yarn.lock",
"log/**",
"tmp/**",
"instances/**",
"public/uploads/**",
"*.dump",
"*.rdb",
"*.mmdb",
".DS_Store",
"*.swp",
"*.swo",
"*.un~",
".jest-cache",
".idea/**",
".vscode/**",
".yalc/**",
"yalc.lock",
"*.local",
"prisma/migrations/**",
"prisma/mysql-migrations/**",
"prisma/postgresql-migrations/**"
]
},
"search": {
"exclude_patterns": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/.git/**",
"**/coverage/**",
"**/log/**",
"**/tmp/**",
"**/instances/**",
"**/public/uploads/**",
"**/*.min.js",
"**/*.min.css",
"**/*.log",
"**/*.lock",
"**/pnpm-lock.yaml",
"**/package-lock.json",
"**/yarn.lock",
"**/*.dump",
"**/*.rdb",
"**/*.mmdb",
"**/.DS_Store",
"**/*.swp",
"**/*.swo",
"**/*.un~",
"**/.jest-cache",
"**/.idea/**",
"**/.vscode/**",
"**/.yalc/**",
"**/yalc.lock",
"**/*.local",
"**/prisma/migrations/**",
"**/prisma/mysql-migrations/**",
"**/prisma/postgresql-migrations/**"
]
},
"evolution_api": {
"project_type": "nodejs_typescript_api",
"backend_framework": "express_prisma",
"database": ["postgresql", "mysql"],
"cache": ["redis", "node_cache"],
"queue": ["rabbitmq", "sqs"],
"real_time": "socket_io",
"file_storage": ["aws_s3", "minio"],
"validation": "class_validator",
"logging": "pino",
"main_directories": {
"source": "src/",
"api": "src/api/",
"controllers": "src/api/controllers/",
"services": "src/api/services/",
"integrations": "src/api/integrations/",
"dto": "src/api/dto/",
"types": "src/api/types/",
"guards": "src/api/guards/",
"routes": "src/api/routes/",
"cache": "src/cache/",
"config": "src/config/",
"utils": "src/utils/",
"exceptions": "src/exceptions/",
"validate": "src/validate/",
"prisma": "prisma/",
"tests": "test/",
"docs": "docs/"
},
"key_patterns": [
"whatsapp_integration",
"multi_database_support",
"instance_management",
"event_driven_architecture",
"service_layer_pattern",
"dto_validation",
"webhook_processing",
"message_queuing",
"real_time_communication",
"file_storage_integration"
],
"whatsapp_integrations": [
"baileys",
"meta_business_api",
"whatsapp_cloud_api"
],
"external_integrations": [
"chatwoot",
"typebot",
"openai",
"dify",
"rabbitmq",
"sqs",
"s3",
"minio"
]
}
}
}

View File

@@ -0,0 +1,174 @@
---
description: Evolution API project-specific context and constraints
globs:
alwaysApply: true
---
# Evolution API Project Context
## Cross-References
- **Core Development**: @core-development.mdc for fundamental development principles
- **Specialized Rules**: Reference specific specialized rules when working on:
- Services: @specialized-rules/service-rules.mdc
- Controllers: @specialized-rules/controller-rules.mdc
- DTOs: @specialized-rules/dto-rules.mdc
- Guards: @specialized-rules/guard-rules.mdc
- Routes: @specialized-rules/route-rules.mdc
- Types: @specialized-rules/type-rules.mdc
- Utils: @specialized-rules/util-rules.mdc
- Validation: @specialized-rules/validate-rules.mdc
- Channel Integrations: @specialized-rules/integration-channel-rules.mdc
- Chatbot Integrations: @specialized-rules/integration-chatbot-rules.mdc
- Storage Integrations: @specialized-rules/integration-storage-rules.mdc
- Event Integrations: @specialized-rules/integration-event-rules.mdc
- **TypeScript/Node.js**: Node.js 20+ + TypeScript 5+ backend standards
- **Express/Prisma**: Express.js + Prisma ORM patterns
- **WhatsApp Integrations**: Baileys, Meta Business API, and other messaging platforms
## Technology Stack
- **Backend**: Node.js 20+ + TypeScript 5+ + Express.js
- **Database**: Prisma ORM (PostgreSQL/MySQL support)
- **Cache**: Redis + Node-cache for local fallback
- **Queue**: RabbitMQ + Amazon SQS for message processing
- **Real-time**: Socket.io for WebSocket connections
- **Storage**: AWS S3 + Minio for file storage
- **Validation**: JSONSchema7 for input validation
- **Logging**: Pino for structured logging
- **Architecture**: Multi-tenant API with WhatsApp integrations
## Project-Specific Patterns
### WhatsApp Integration Architecture
- **MANDATORY**: All WhatsApp integrations must follow established patterns
- **BAILEYS**: Use `whatsapp.baileys.service.ts` patterns for WhatsApp Web
- **META BUSINESS**: Use `whatsapp.business.service.ts` for official API
- **CONNECTION MANAGEMENT**: One connection per instance with proper lifecycle
- **EVENT HANDLING**: Proper event listeners and error handling
### Multi-Database Architecture
- **CRITICAL**: Support both PostgreSQL and MySQL
- **SCHEMAS**: Use appropriate schema files (postgresql-schema.prisma / mysql-schema.prisma)
- **MIGRATIONS**: Keep migrations synchronized between databases
- **TYPES**: Use database-specific types (@db.JsonB vs @db.Json)
- **COMPATIBILITY**: Ensure feature parity between databases
### API Integration Workflow
- **CORE FEATURE**: REST API for WhatsApp communication
- **COMPLEXITY**: High - involves webhook processing, message routing, and instance management
- **COMPONENTS**: Instance management, message handling, media processing
- **INTEGRATIONS**: Baileys, Meta Business API, Chatwoot, Typebot, OpenAI, Dify
### Multi-Tenant Instance Architecture
- **CRITICAL**: All operations must be scoped by instance
- **ISOLATION**: Complete data isolation between instances
- **SECURITY**: Validate instance ownership before operations
- **SCALING**: Support thousands of concurrent instances
- **AUTHENTICATION**: API key-based authentication per instance
## Documentation Requirements
### Implementation Documentation
- **MANDATORY**: Document complex integration patterns
- **LOCATION**: Use inline comments for business logic
- **API DOCS**: Document all public endpoints
- **WEBHOOK DOCS**: Document webhook payloads and signatures
### Change Documentation
- **CHANGELOG**: Document breaking changes
- **MIGRATION GUIDES**: Document database migrations
- **INTEGRATION GUIDES**: Document new integration patterns
## Environment and Security
### Environment Variables
- **CRITICAL**: Never hardcode sensitive values
- **VALIDATION**: Validate required environment variables on startup
- **SECURITY**: Use secure defaults and proper encryption
- **DOCUMENTATION**: Document all environment variables
### File Organization - Node.js/TypeScript Structure
- **CONTROLLERS**: Organized by feature (`api/controllers/`)
- **SERVICES**: Business logic in service classes (`api/services/`)
- **INTEGRATIONS**: External integrations (`api/integrations/`)
- **DTOS**: Data transfer objects (`api/dto/`)
- **TYPES**: TypeScript types (`api/types/`)
- **UTILS**: Utility functions (`utils/`)
## Integration Points
### WhatsApp Providers
- **BAILEYS**: WhatsApp Web integration with QR code
- **META BUSINESS**: Official WhatsApp Business API
- **CLOUD API**: WhatsApp Cloud API integration
- **WEBHOOK PROCESSING**: Proper webhook validation and processing
### External Integrations
- **CHATWOOT**: Customer support platform integration
- **TYPEBOT**: Chatbot flow integration
- **OPENAI**: AI-powered chat integration
- **DIFY**: AI workflow integration
- **STORAGE**: S3/Minio for media file storage
### Event-Driven Communication
- **EVENTEMITTER2**: Internal event system
- **SOCKET.IO**: Real-time WebSocket communication
- **RABBITMQ**: Message queue for async processing
- **SQS**: Amazon SQS for cloud-based queuing
- **WEBHOOKS**: Outbound webhook system
## Development Constraints
### Language Requirements
- **USER COMMUNICATION**: Always respond in Portuguese (PT-BR)
- **CODE/COMMENTS**: English for code and technical documentation
- **API RESPONSES**: English for consistency
- **ERROR MESSAGES**: Portuguese for user-facing errors
### Performance Constraints
- **MEMORY**: Efficient memory usage for multiple instances
- **DATABASE**: Optimized queries with proper indexing
- **CACHE**: Strategic caching for frequently accessed data
- **CONNECTIONS**: Proper connection pooling and management
### Security Constraints
- **AUTHENTICATION**: API key validation for all endpoints
- **AUTHORIZATION**: Instance-based access control
- **INPUT VALIDATION**: Validate all inputs with JSONSchema7
- **RATE LIMITING**: Prevent abuse with rate limiting
- **WEBHOOK SECURITY**: Validate webhook signatures
## Quality Standards
- **TYPE SAFETY**: Full TypeScript coverage with strict mode
- **ERROR HANDLING**: Comprehensive error scenarios with proper logging
- **TESTING**: Unit and integration tests for critical paths
- **MONITORING**: Proper logging and error tracking
- **DOCUMENTATION**: Clear API documentation and code comments
- **PERFORMANCE**: Optimized for high-throughput message processing
- **SECURITY**: Secure by default with proper validation
- **SCALABILITY**: Design for horizontal scaling
## Evolution API Specific Development Patterns
### Instance Management
- **LIFECYCLE**: Proper instance creation, connection, and cleanup
- **STATE MANAGEMENT**: Track connection status and health
- **RECOVERY**: Automatic reconnection and error recovery
- **MONITORING**: Health checks and status reporting
### Message Processing
- **QUEUE-BASED**: Use queues for message processing
- **RETRY LOGIC**: Implement exponential backoff for failures
- **MEDIA HANDLING**: Proper media upload and processing
- **WEBHOOK DELIVERY**: Reliable webhook delivery with retries
### Integration Patterns
- **SERVICE LAYER**: Business logic in service classes
- **DTO VALIDATION**: Input validation with JSONSchema7
- **ERROR HANDLING**: Consistent error responses
- **LOGGING**: Structured logging with correlation IDs
### Database Patterns
- **PRISMA**: Use Prisma ORM for all database operations
- **TRANSACTIONS**: Use transactions for multi-step operations
- **MIGRATIONS**: Proper migration management
- **INDEXING**: Optimize queries with appropriate indexes

View File

@@ -0,0 +1,342 @@
---
description: Controller patterns for Evolution API
globs:
- "src/api/controllers/**/*.ts"
- "src/api/integrations/**/controllers/*.ts"
alwaysApply: false
---
# Evolution API Controller Rules
## Controller Structure Pattern
### Standard Controller Class
```typescript
export class ExampleController {
constructor(private readonly exampleService: ExampleService) {}
public async createExample(instance: InstanceDto, data: ExampleDto) {
return this.exampleService.create(instance, data);
}
public async findExample(instance: InstanceDto) {
return this.exampleService.find(instance);
}
}
```
## Dependency Injection Pattern
### Service Injection
```typescript
// CORRECT - Evolution API pattern
export class ChatController {
constructor(private readonly waMonitor: WAMonitoringService) {}
public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) {
return await this.waMonitor.waInstances[instanceName].getWhatsAppNumbers(data);
}
}
// INCORRECT - Don't inject multiple services when waMonitor is sufficient
export class ChatController {
constructor(
private readonly waMonitor: WAMonitoringService,
private readonly prismaRepository: PrismaRepository, // ❌ Unnecessary if waMonitor has access
private readonly configService: ConfigService, // ❌ Unnecessary if waMonitor has access
) {}
}
```
## Method Signature Pattern
### Instance Parameter Pattern
```typescript
// CORRECT - Evolution API pattern (destructuring instanceName)
public async fetchCatalog({ instanceName }: InstanceDto, data: getCatalogDto) {
return await this.waMonitor.waInstances[instanceName].fetchCatalog(instanceName, data);
}
// CORRECT - Alternative pattern for full instance (when using services)
public async createTemplate(instance: InstanceDto, data: TemplateDto) {
return this.templateService.create(instance, data);
}
// INCORRECT - Don't use generic method names
public async methodName(instance: InstanceDto, data: DataDto) { // ❌ Use specific names
return this.service.performAction(instance, data);
}
```
## WAMonitor Access Pattern
### Direct WAMonitor Usage
```typescript
// CORRECT - Standard pattern in controllers
export class CallController {
constructor(private readonly waMonitor: WAMonitoringService) {}
public async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) {
return await this.waMonitor.waInstances[instanceName].offerCall(data);
}
}
```
## Controller Registration Pattern
### Server Module Registration
```typescript
// In server.module.ts
export const templateController = new TemplateController(templateService);
export const businessController = new BusinessController(waMonitor);
export const chatController = new ChatController(waMonitor);
export const callController = new CallController(waMonitor);
```
## Error Handling in Controllers
### Let Services Handle Errors
```typescript
// CORRECT - Let service handle errors
public async fetchCatalog(instance: InstanceDto, data: getCatalogDto) {
return await this.waMonitor.waInstances[instance.instanceName].fetchCatalog(instance.instanceName, data);
}
// INCORRECT - Don't add try-catch in controllers unless specific handling needed
public async fetchCatalog(instance: InstanceDto, data: getCatalogDto) {
try {
return await this.waMonitor.waInstances[instance.instanceName].fetchCatalog(instance.instanceName, data);
} catch (error) {
throw error; // ❌ Unnecessary try-catch
}
}
```
## Complex Controller Pattern
### Instance Controller Pattern
```typescript
export class InstanceController {
constructor(
private readonly waMonitor: WAMonitoringService,
private readonly configService: ConfigService,
private readonly prismaRepository: PrismaRepository,
private readonly eventEmitter: EventEmitter2,
private readonly chatwootService: ChatwootService,
private readonly settingsService: SettingsService,
private readonly proxyService: ProxyController,
private readonly cache: CacheService,
private readonly chatwootCache: CacheService,
private readonly baileysCache: CacheService,
private readonly providerFiles: ProviderFiles,
) {}
private readonly logger = new Logger('InstanceController');
// Multiple methods handling different aspects
public async createInstance(data: InstanceDto) {
// Complex instance creation logic
}
public async deleteInstance({ instanceName }: InstanceDto) {
// Complex instance deletion logic
}
}
```
## Channel Controller Pattern
### Base Channel Controller
```typescript
export class ChannelController {
public prismaRepository: PrismaRepository;
public waMonitor: WAMonitoringService;
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
this.prisma = prismaRepository;
this.monitor = waMonitor;
}
// Getters and setters for dependency access
public set prisma(prisma: PrismaRepository) {
this.prismaRepository = prisma;
}
public get prisma() {
return this.prismaRepository;
}
public set monitor(waMonitor: WAMonitoringService) {
this.waMonitor = waMonitor;
}
public get monitor() {
return this.waMonitor;
}
}
```
### Extended Channel Controller
```typescript
export class EvolutionController extends ChannelController implements ChannelControllerInterface {
private readonly logger = new Logger('EvolutionController');
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
super(prismaRepository, waMonitor);
}
integrationEnabled: boolean;
public async receiveWebhook(data: any) {
const numberId = data.numberId;
if (!numberId) {
this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');
return;
}
const instance = await this.prismaRepository.instance.findFirst({
where: { number: numberId },
});
if (!instance) {
this.logger.error('WebhookService -> receiveWebhook -> instance not found');
return;
}
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
return {
status: 'success',
};
}
}
```
## Chatbot Controller Pattern
### Base Chatbot Controller
```typescript
export abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>
extends ChatbotController
implements ChatbotControllerInterface
{
public readonly logger: Logger;
integrationEnabled: boolean;
// Abstract methods to be implemented
protected abstract readonly integrationName: string;
protected abstract processBot(/* parameters */): Promise<void>;
protected abstract getFallbackBotId(settings: any): string | undefined;
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
super(prismaRepository, waMonitor);
}
// Base implementation methods
public async createBot(instance: InstanceDto, data: BotData) {
// Common bot creation logic
}
}
```
## Method Naming Conventions
### Standard Method Names
- `create*()` - Create operations
- `find*()` - Find operations
- `fetch*()` - Fetch from external APIs
- `send*()` - Send operations
- `receive*()` - Receive webhook/data
- `handle*()` - Handle specific actions
- `offer*()` - Offer services (like calls)
## Return Patterns
### Direct Return Pattern
```typescript
// CORRECT - Direct return from service
public async createTemplate(instance: InstanceDto, data: TemplateDto) {
return this.templateService.create(instance, data);
}
// CORRECT - Direct return from waMonitor
public async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) {
return await this.waMonitor.waInstances[instanceName].offerCall(data);
}
```
## Controller Testing Pattern
### Unit Test Structure
```typescript
describe('ExampleController', () => {
let controller: ExampleController;
let service: jest.Mocked<ExampleService>;
beforeEach(() => {
const mockService = {
create: jest.fn(),
find: jest.fn(),
};
controller = new ExampleController(mockService as any);
service = mockService as any;
});
describe('createExample', () => {
it('should call service create method', async () => {
const instance = { instanceName: 'test' };
const data = { test: 'data' };
const expectedResult = { success: true };
service.create.mockResolvedValue(expectedResult);
const result = await controller.createExample(instance, data);
expect(service.create).toHaveBeenCalledWith(instance, data);
expect(result).toEqual(expectedResult);
});
});
});
```
## Interface Implementation
### Controller Interface Pattern
```typescript
export interface ChannelControllerInterface {
integrationEnabled: boolean;
}
export interface ChatbotControllerInterface {
integrationEnabled: boolean;
createBot(instance: InstanceDto, data: any): Promise<any>;
findBot(instance: InstanceDto): Promise<any>;
// ... other methods
}
```
## Controller Organization
### File Naming Convention
- `*.controller.ts` - Main controllers
- `*/*.controller.ts` - Integration-specific controllers
### Method Organization
1. Constructor
2. Public methods (alphabetical order)
3. Private methods (if any)
### Import Organization
```typescript
// DTOs first
import { InstanceDto } from '@api/dto/instance.dto';
import { ExampleDto } from '@api/dto/example.dto';
// Services
import { ExampleService } from '@api/services/example.service';
// Types
import { WAMonitoringService } from '@api/services/monitor.service';
```

View File

@@ -0,0 +1,433 @@
---
description: DTO patterns and validation for Evolution API
globs:
- "src/api/dto/**/*.ts"
- "src/api/integrations/**/dto/*.ts"
alwaysApply: false
---
# Evolution API DTO Rules
## DTO Structure Pattern
### Basic DTO Class
```typescript
export class ExampleDto {
name: string;
category: string;
allowCategoryChange: boolean;
language: string;
components: any;
webhookUrl?: string;
}
```
## Inheritance Pattern
### DTO Inheritance
```typescript
// CORRECT - Evolution API pattern
export class InstanceDto extends IntegrationDto {
instanceName: string;
instanceId?: string;
qrcode?: boolean;
businessId?: string;
number?: string;
integration?: string;
token?: string;
status?: string;
ownerJid?: string;
profileName?: string;
profilePicUrl?: string;
// Settings
rejectCall?: boolean;
msgCall?: string;
groupsIgnore?: boolean;
alwaysOnline?: boolean;
readMessages?: boolean;
readStatus?: boolean;
syncFullHistory?: boolean;
wavoipToken?: string;
// Proxy settings
proxyHost?: string;
proxyPort?: string;
proxyProtocol?: string;
proxyUsername?: string;
proxyPassword?: string;
// Webhook configuration
webhook?: {
enabled?: boolean;
events?: string[];
headers?: JsonValue;
url?: string;
byEvents?: boolean;
base64?: boolean;
};
// Chatwoot integration
chatwootAccountId?: string;
chatwootConversationPending?: boolean;
chatwootAutoCreate?: boolean;
chatwootDaysLimitImportMessages?: number;
chatwootImportContacts?: boolean;
chatwootImportMessages?: boolean;
chatwootLogo?: string;
chatwootMergeBrazilContacts?: boolean;
chatwootNameInbox?: string;
chatwootOrganization?: string;
chatwootReopenConversation?: boolean;
chatwootSignMsg?: boolean;
chatwootToken?: string;
chatwootUrl?: string;
}
```
## Base DTO Pattern
### Base Chatbot DTO
```typescript
/**
* Base DTO for all chatbot integrations
* Contains common properties shared by all chatbot types
*/
export class BaseChatbotDto {
enabled?: boolean;
description: string;
expire?: number;
keywordFinish?: string;
delayMessage?: number;
unknownMessage?: string;
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
triggerType: TriggerType;
triggerOperator?: TriggerOperator;
triggerValue?: string;
ignoreJids?: string[];
splitMessages?: boolean;
timePerChar?: number;
}
/**
* Base settings DTO for all chatbot integrations
*/
export class BaseChatbotSettingDto {
expire?: number;
keywordFinish?: string;
delayMessage?: number;
unknownMessage?: string;
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
ignoreJids?: string[];
splitMessages?: boolean;
timePerChar?: number;
}
```
## Message DTO Patterns
### Send Message DTOs
```typescript
export class Metadata {
number: string;
delay?: number;
}
export class SendTextDto extends Metadata {
text: string;
linkPreview?: boolean;
mentionsEveryOne?: boolean;
mentioned?: string[];
}
export class SendListDto extends Metadata {
title: string;
description: string;
buttonText: string;
footerText?: string;
sections: Section[];
}
export class ContactMessage {
fullName: string;
wuid: string;
phoneNumber: string;
organization?: string;
email?: string;
url?: string;
}
export class SendTemplateDto extends Metadata {
name: string;
language: string;
components: any;
}
```
## Simple DTO Patterns
### Basic DTOs
```typescript
export class NumberDto {
number: string;
}
export class LabelDto {
id?: string;
name: string;
color: string;
predefinedId?: string;
}
export class HandleLabelDto {
number: string;
labelId: string;
}
export class ProfileNameDto {
name: string;
}
export class WhatsAppNumberDto {
numbers: string[];
}
```
## Complex DTO Patterns
### Business DTOs
```typescript
export class getCatalogDto {
number?: string;
limit?: number;
cursor?: string;
}
export class getCollectionsDto {
number?: string;
limit?: number;
cursor?: string;
}
export class NumberBusiness {
number: string;
name?: string;
description?: string;
email?: string;
websites?: string[];
latitude?: number;
longitude?: number;
address?: string;
profilehandle?: string;
}
```
## Settings DTO Pattern
### Settings Configuration
```typescript
export class SettingsDto {
rejectCall?: boolean;
msgCall?: string;
groupsIgnore?: boolean;
alwaysOnline?: boolean;
readMessages?: boolean;
readStatus?: boolean;
syncFullHistory?: boolean;
wavoipToken?: string;
}
export class ProxyDto {
host?: string;
port?: string;
protocol?: string;
username?: string;
password?: string;
}
```
## Presence DTO Pattern
### WhatsApp Presence
```typescript
export class SetPresenceDto {
presence: WAPresence;
}
export class SendPresenceDto {
number: string;
presence: WAPresence;
}
```
## DTO Structure (No Decorators)
### Simple DTO Classes (Evolution API Pattern)
```typescript
// CORRECT - Evolution API pattern (no decorators)
export class ExampleDto {
name: string;
description?: string;
enabled: boolean;
items?: string[];
timeout?: number;
}
// INCORRECT - Don't use class-validator decorators
export class ValidatedDto {
@IsString() // ❌ Evolution API doesn't use decorators
name: string;
}
```
## Type Safety Patterns
### Prisma Type Integration
```typescript
import { JsonValue } from '@prisma/client/runtime/library';
import { WAPresence } from 'baileys';
import { TriggerOperator, TriggerType } from '@prisma/client';
export class TypeSafeDto {
presence: WAPresence;
triggerType: TriggerType;
triggerOperator?: TriggerOperator;
metadata?: JsonValue;
}
```
## DTO Documentation
### JSDoc Comments
```typescript
/**
* DTO for creating WhatsApp templates
* Used by Meta Business API integration
*/
export class TemplateDto {
/** Template name - must be unique */
name: string;
/** Template category (MARKETING, UTILITY, AUTHENTICATION) */
category: string;
/** Whether category can be changed after creation */
allowCategoryChange: boolean;
/** Language code (e.g., 'pt_BR', 'en_US') */
language: string;
/** Template components (header, body, footer, buttons) */
components: any;
/** Optional webhook URL for template status updates */
webhookUrl?: string;
}
```
## DTO Naming Conventions
### Standard Naming Patterns
- `*Dto` - Data transfer objects
- `Create*Dto` - Creation DTOs
- `Update*Dto` - Update DTOs
- `Send*Dto` - Message sending DTOs
- `Get*Dto` - Query DTOs
- `Handle*Dto` - Action DTOs
## File Organization
### DTO File Structure
```
src/api/dto/
├── instance.dto.ts # Main instance DTO
├── template.dto.ts # Template management
├── sendMessage.dto.ts # Message sending DTOs
├── chat.dto.ts # Chat operations
├── business.dto.ts # Business API DTOs
├── group.dto.ts # Group management
├── label.dto.ts # Label management
├── proxy.dto.ts # Proxy configuration
├── settings.dto.ts # Instance settings
└── call.dto.ts # Call operations
```
## Integration DTO Patterns
### Chatbot Integration DTOs
```typescript
// Base for all chatbot DTOs
export class BaseChatbotDto {
enabled?: boolean;
description: string;
// ... common properties
}
// Specific chatbot DTOs extend base
export class TypebotDto extends BaseChatbotDto {
url: string;
typebot: string;
// ... typebot-specific properties
}
export class OpenaiDto extends BaseChatbotDto {
apiKey: string;
model: string;
// ... openai-specific properties
}
```
## DTO Testing Pattern
### DTO Validation Tests
```typescript
describe('ExampleDto', () => {
it('should validate required fields', () => {
const dto = new ExampleDto();
dto.name = 'test';
dto.category = 'MARKETING';
dto.allowCategoryChange = true;
dto.language = 'pt_BR';
dto.components = {};
expect(dto.name).toBe('test');
expect(dto.category).toBe('MARKETING');
});
it('should handle optional fields', () => {
const dto = new ExampleDto();
dto.name = 'test';
dto.category = 'MARKETING';
dto.allowCategoryChange = true;
dto.language = 'pt_BR';
dto.components = {};
dto.webhookUrl = 'https://example.com/webhook';
expect(dto.webhookUrl).toBe('https://example.com/webhook');
});
});
```
## DTO Transformation
### Request to DTO Mapping (Evolution API Pattern)
```typescript
// CORRECT - Evolution API uses RouterBroker dataValidate
const response = await this.dataValidate<ExampleDto>({
request: req,
schema: exampleSchema, // JSONSchema7
ClassRef: ExampleDto,
execute: (instance, data) => controller.method(instance, data),
});
// INCORRECT - Don't use class-validator
const dto = plainToClass(ExampleDto, req.body); // ❌ Not used in Evolution API
const errors = await validate(dto); // ❌ Not used in Evolution API
```

View File

@@ -0,0 +1,416 @@
---
description: Guard patterns for authentication and authorization in Evolution API
globs:
- "src/api/guards/**/*.ts"
alwaysApply: false
---
# Evolution API Guard Rules
## Guard Structure Pattern
### Standard Guard Function
```typescript
import { NextFunction, Request, Response } from 'express';
import { Logger } from '@config/logger.config';
import { UnauthorizedException, ForbiddenException } from '@exceptions';
const logger = new Logger('GUARD');
async function guardFunction(req: Request, _: Response, next: NextFunction) {
// Guard logic here
if (validationFails) {
throw new UnauthorizedException();
}
return next();
}
export const guardName = { guardFunction };
```
## Authentication Guard Pattern
### API Key Authentication
```typescript
async function apikey(req: Request, _: Response, next: NextFunction) {
const env = configService.get<Auth>('AUTHENTICATION').API_KEY;
const key = req.get('apikey');
const db = configService.get<Database>('DATABASE');
if (!key) {
throw new UnauthorizedException();
}
// Global API key check
if (env.KEY === key) {
return next();
}
// Special routes handling
if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) {
throw new ForbiddenException('Missing global api key', 'The global api key must be set');
}
const param = req.params as unknown as InstanceDto;
try {
if (param?.instanceName) {
const instance = await prismaRepository.instance.findUnique({
where: { name: param.instanceName },
});
if (instance.token === key) {
return next();
}
} else {
if (req.originalUrl.includes('/instance/fetchInstances') && db.SAVE_DATA.INSTANCE) {
const instanceByKey = await prismaRepository.instance.findFirst({
where: { token: key },
});
if (instanceByKey) {
return next();
}
}
}
} catch (error) {
logger.error(error);
}
throw new UnauthorizedException();
}
export const authGuard = { apikey };
```
## Instance Validation Guards
### Instance Exists Guard
```typescript
async function getInstance(instanceName: string) {
try {
const cacheConf = configService.get<CacheConf>('CACHE');
const exists = !!waMonitor.waInstances[instanceName];
if (cacheConf.REDIS.ENABLED && cacheConf.REDIS.SAVE_INSTANCES) {
const keyExists = await cache.has(instanceName);
return exists || keyExists;
}
return exists || (await prismaRepository.instance.findMany({ where: { name: instanceName } })).length > 0;
} catch (error) {
throw new InternalServerErrorException(error?.toString());
}
}
export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) {
if (req.originalUrl.includes('/instance/create')) {
return next();
}
const param = req.params as unknown as InstanceDto;
if (!param?.instanceName) {
throw new BadRequestException('"instanceName" not provided.');
}
if (!(await getInstance(param.instanceName))) {
throw new NotFoundException(`The "${param.instanceName}" instance does not exist`);
}
next();
}
```
### Instance Logged Guard
```typescript
export async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) {
if (req.originalUrl.includes('/instance/create')) {
const instance = req.body as InstanceDto;
if (await getInstance(instance.instanceName)) {
throw new ForbiddenException(`This name "${instance.instanceName}" is already in use.`);
}
if (waMonitor.waInstances[instance.instanceName]) {
delete waMonitor.waInstances[instance.instanceName];
}
}
next();
}
```
## Telemetry Guard Pattern
### Telemetry Collection
```typescript
class Telemetry {
public collectTelemetry(req: Request, res: Response, next: NextFunction): void {
// Collect telemetry data
const telemetryData = {
route: req.originalUrl,
method: req.method,
timestamp: new Date(),
userAgent: req.get('User-Agent'),
};
// Send telemetry asynchronously (don't block request)
setImmediate(() => {
this.sendTelemetry(telemetryData);
});
next();
}
private async sendTelemetry(data: any): Promise<void> {
try {
// Send telemetry data
} catch (error) {
// Silently fail - don't affect main request
}
}
}
export default Telemetry;
```
## Guard Composition Pattern
### Multiple Guards Usage
```typescript
// In router setup
const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];
router
.use('/instance', new InstanceRouter(configService, ...guards).router)
.use('/message', new MessageRouter(...guards).router)
.use('/chat', new ChatRouter(...guards).router);
```
## Error Handling in Guards
### Proper Exception Throwing
```typescript
// CORRECT - Use proper HTTP exceptions
if (!apiKey) {
throw new UnauthorizedException('API key required');
}
if (instanceExists) {
throw new ForbiddenException('Instance already exists');
}
if (!instanceFound) {
throw new NotFoundException('Instance not found');
}
if (validationFails) {
throw new BadRequestException('Invalid request parameters');
}
// INCORRECT - Don't use generic Error
if (!apiKey) {
throw new Error('API key required'); // ❌ Use specific exceptions
}
```
## Configuration Access in Guards
### Config Service Usage
```typescript
async function configAwareGuard(req: Request, _: Response, next: NextFunction) {
const authConfig = configService.get<Auth>('AUTHENTICATION');
const cacheConfig = configService.get<CacheConf>('CACHE');
const dbConfig = configService.get<Database>('DATABASE');
// Use configuration for guard logic
if (authConfig.API_KEY.KEY === providedKey) {
return next();
}
throw new UnauthorizedException();
}
```
## Database Access in Guards
### Prisma Repository Usage
```typescript
async function databaseGuard(req: Request, _: Response, next: NextFunction) {
try {
const param = req.params as unknown as InstanceDto;
const instance = await prismaRepository.instance.findUnique({
where: { name: param.instanceName },
});
if (!instance) {
throw new NotFoundException('Instance not found');
}
// Additional validation logic
if (instance.status !== 'active') {
throw new ForbiddenException('Instance not active');
}
return next();
} catch (error) {
logger.error('Database guard error:', error);
throw new InternalServerErrorException('Database access failed');
}
}
```
## Cache Integration in Guards
### Cache Service Usage
```typescript
async function cacheAwareGuard(req: Request, _: Response, next: NextFunction) {
const cacheConf = configService.get<CacheConf>('CACHE');
if (cacheConf.REDIS.ENABLED) {
const cached = await cache.get(`guard:${req.params.instanceName}`);
if (cached) {
// Use cached validation result
return next();
}
}
// Perform validation and cache result
const isValid = await performValidation(req.params.instanceName);
if (cacheConf.REDIS.ENABLED) {
await cache.set(`guard:${req.params.instanceName}`, isValid, 300); // 5 min TTL
}
if (isValid) {
return next();
}
throw new UnauthorizedException();
}
```
## Logging in Guards
### Structured Logging
```typescript
const logger = new Logger('GUARD');
async function loggedGuard(req: Request, _: Response, next: NextFunction) {
logger.log(`Guard validation started for ${req.originalUrl}`);
try {
// Guard logic
const isValid = await validateRequest(req);
if (isValid) {
logger.log(`Guard validation successful for ${req.params.instanceName}`);
return next();
}
logger.warn(`Guard validation failed for ${req.params.instanceName}`);
throw new UnauthorizedException();
} catch (error) {
logger.error(`Guard validation error: ${error.message}`, error.stack);
throw error;
}
}
```
## Guard Testing Pattern
### Unit Test Structure
```typescript
describe('authGuard', () => {
let req: Partial<Request>;
let res: Partial<Response>;
let next: NextFunction;
beforeEach(() => {
req = {
get: jest.fn(),
params: {},
originalUrl: '/test',
};
res = {};
next = jest.fn();
});
describe('apikey', () => {
it('should pass with valid global API key', async () => {
(req.get as jest.Mock).mockReturnValue('valid-global-key');
await authGuard.apikey(req as Request, res as Response, next);
expect(next).toHaveBeenCalled();
});
it('should throw UnauthorizedException with no API key', async () => {
(req.get as jest.Mock).mockReturnValue(undefined);
await expect(
authGuard.apikey(req as Request, res as Response, next)
).rejects.toThrow(UnauthorizedException);
});
it('should pass with valid instance token', async () => {
(req.get as jest.Mock).mockReturnValue('instance-token');
req.params = { instanceName: 'test-instance' };
// Mock prisma repository
jest.spyOn(prismaRepository.instance, 'findUnique').mockResolvedValue({
token: 'instance-token',
} as any);
await authGuard.apikey(req as Request, res as Response, next);
expect(next).toHaveBeenCalled();
});
});
});
```
## Guard Performance Considerations
### Efficient Validation
```typescript
// CORRECT - Efficient guard with early returns
async function efficientGuard(req: Request, _: Response, next: NextFunction) {
// Quick checks first
if (req.originalUrl.includes('/public')) {
return next(); // Skip validation for public routes
}
const apiKey = req.get('apikey');
if (!apiKey) {
throw new UnauthorizedException(); // Fail fast
}
// More expensive checks only if needed
if (apiKey === globalKey) {
return next(); // Skip database check
}
// Database check only as last resort
const isValid = await validateInDatabase(apiKey);
if (isValid) {
return next();
}
throw new UnauthorizedException();
}
// INCORRECT - Inefficient guard
async function inefficientGuard(req: Request, _: Response, next: NextFunction) {
// Always do expensive database check first
const dbResult = await expensiveDatabaseQuery(); // ❌ Expensive operation first
const apiKey = req.get('apikey');
if (!apiKey && dbResult) { // ❌ Complex logic
throw new UnauthorizedException();
}
next();
}
```

View File

@@ -0,0 +1,552 @@
---
description: Channel integration patterns for Evolution API
globs:
- "src/api/integrations/channel/**/*.ts"
alwaysApply: false
---
# Evolution API Channel Integration Rules
## Channel Controller Pattern
### Base Channel Controller
```typescript
export interface ChannelControllerInterface {
integrationEnabled: boolean;
}
export class ChannelController {
public prismaRepository: PrismaRepository;
public waMonitor: WAMonitoringService;
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
this.prisma = prismaRepository;
this.monitor = waMonitor;
}
public set prisma(prisma: PrismaRepository) {
this.prismaRepository = prisma;
}
public get prisma() {
return this.prismaRepository;
}
public set monitor(waMonitor: WAMonitoringService) {
this.waMonitor = waMonitor;
}
public get monitor() {
return this.waMonitor;
}
public init(instanceData: InstanceDto, data: ChannelDataType) {
if (!instanceData.token && instanceData.integration === Integration.WHATSAPP_BUSINESS) {
throw new BadRequestException('token is required');
}
if (instanceData.integration === Integration.WHATSAPP_BUSINESS) {
return new BusinessStartupService(/* dependencies */);
}
if (instanceData.integration === Integration.EVOLUTION) {
return new EvolutionStartupService(/* dependencies */);
}
if (instanceData.integration === Integration.WHATSAPP_BAILEYS) {
return new BaileysStartupService(/* dependencies */);
}
return null;
}
}
```
### Extended Channel Controller
```typescript
export class EvolutionController extends ChannelController implements ChannelControllerInterface {
private readonly logger = new Logger('EvolutionController');
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
super(prismaRepository, waMonitor);
}
integrationEnabled: boolean;
public async receiveWebhook(data: any) {
const numberId = data.numberId;
if (!numberId) {
this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');
return;
}
const instance = await this.prismaRepository.instance.findFirst({
where: { number: numberId },
});
if (!instance) {
this.logger.error('WebhookService -> receiveWebhook -> instance not found');
return;
}
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
return {
status: 'success',
};
}
}
```
## Channel Service Pattern
### Base Channel Service
```typescript
export class ChannelStartupService {
constructor(
private readonly configService: ConfigService,
private readonly eventEmitter: EventEmitter2,
private readonly prismaRepository: PrismaRepository,
public readonly cache: CacheService,
public readonly chatwootCache: CacheService,
) {}
public readonly logger = new Logger('ChannelStartupService');
public client: WASocket;
public readonly instance: wa.Instance = {};
public readonly localChatwoot: wa.LocalChatwoot = {};
public readonly localProxy: wa.LocalProxy = {};
public readonly localSettings: wa.LocalSettings = {};
public readonly localWebhook: wa.LocalWebHook = {};
public setInstance(instance: InstanceDto) {
this.logger.setInstance(instance.instanceName);
this.instance.name = instance.instanceName;
this.instance.id = instance.instanceId;
this.instance.integration = instance.integration;
this.instance.number = instance.number;
this.instance.token = instance.token;
this.instance.businessId = instance.businessId;
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {
this.chatwootService.eventWhatsapp(
Events.STATUS_INSTANCE,
{ instanceName: this.instance.name },
{
instance: this.instance.name,
status: 'created',
},
);
}
}
public set instanceName(name: string) {
this.logger.setInstance(name);
this.instance.name = name;
}
public get instanceName() {
return this.instance.name;
}
}
```
### Extended Channel Service
```typescript
export class EvolutionStartupService extends ChannelStartupService {
constructor(
configService: ConfigService,
eventEmitter: EventEmitter2,
prismaRepository: PrismaRepository,
cache: CacheService,
chatwootCache: CacheService,
) {
super(configService, eventEmitter, prismaRepository, cache, chatwootCache);
}
public async sendMessage(data: SendTextDto): Promise<any> {
// Evolution-specific message sending logic
const response = await this.evolutionApiCall('/send-message', data);
return response;
}
public async connectToWhatsapp(data: any): Promise<void> {
// Evolution-specific connection logic
this.logger.log('Connecting to Evolution API');
// Set up webhook listeners
this.setupWebhookHandlers();
// Initialize connection
await this.initializeConnection(data);
}
private async evolutionApiCall(endpoint: string, data: any): Promise<any> {
const config = this.configService.get<Evolution>('EVOLUTION');
try {
const response = await axios.post(`${config.API_URL}${endpoint}`, data, {
headers: {
'Authorization': `Bearer ${this.instance.token}`,
'Content-Type': 'application/json',
},
});
return response.data;
} catch (error) {
this.logger.error(`Evolution API call failed: ${error.message}`);
throw new InternalServerErrorException('Evolution API call failed');
}
}
private setupWebhookHandlers(): void {
// Set up webhook event handlers
}
private async initializeConnection(data: any): Promise<void> {
// Initialize connection with Evolution API
}
}
```
## Business API Service Pattern
### Meta Business Service
```typescript
export class BusinessStartupService extends ChannelStartupService {
constructor(
configService: ConfigService,
eventEmitter: EventEmitter2,
prismaRepository: PrismaRepository,
cache: CacheService,
chatwootCache: CacheService,
baileysCache: CacheService,
providerFiles: ProviderFiles,
) {
super(configService, eventEmitter, prismaRepository, cache, chatwootCache);
}
public async sendMessage(data: SendTextDto): Promise<any> {
const businessConfig = this.configService.get<WaBusiness>('WA_BUSINESS');
const payload = {
messaging_product: 'whatsapp',
to: data.number,
type: 'text',
text: {
body: data.text,
},
};
try {
const response = await axios.post(
`${businessConfig.URL}/${businessConfig.VERSION}/${this.instance.businessId}/messages`,
payload,
{
headers: {
'Authorization': `Bearer ${this.instance.token}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
this.logger.error(`Business API call failed: ${error.message}`);
throw new BadRequestException('Failed to send message via Business API');
}
}
public async receiveWebhook(data: any): Promise<void> {
// Process incoming webhook from Meta Business API
const { entry } = data;
for (const entryItem of entry) {
const { changes } = entryItem;
for (const change of changes) {
if (change.field === 'messages') {
await this.processMessage(change.value);
}
}
}
}
private async processMessage(messageData: any): Promise<void> {
// Process incoming message from Business API
const { messages, contacts } = messageData;
if (messages) {
for (const message of messages) {
await this.handleIncomingMessage(message, contacts);
}
}
}
private async handleIncomingMessage(message: any, contacts: any[]): Promise<void> {
// Handle individual message
const contact = contacts?.find(c => c.wa_id === message.from);
// Emit event for message processing
this.eventEmitter.emit(Events.MESSAGES_UPSERT, {
instanceName: this.instance.name,
message,
contact,
});
}
}
```
## Baileys Service Pattern
### Baileys Integration Service
```typescript
export class BaileysStartupService extends ChannelStartupService {
constructor(
configService: ConfigService,
eventEmitter: EventEmitter2,
prismaRepository: PrismaRepository,
cache: CacheService,
chatwootCache: CacheService,
baileysCache: CacheService,
providerFiles: ProviderFiles,
) {
super(configService, eventEmitter, prismaRepository, cache, chatwootCache);
}
public async connectToWhatsapp(): Promise<void> {
const authPath = path.join(INSTANCE_DIR, this.instance.name);
const { state, saveCreds } = await useMultiFileAuthState(authPath);
this.client = makeWASocket({
auth: state,
logger: P({ level: 'error' }),
printQRInTerminal: false,
browser: ['Evolution API', 'Chrome', '4.0.0'],
defaultQueryTimeoutMs: 60000,
});
this.setupEventHandlers();
this.client.ev.on('creds.update', saveCreds);
}
private setupEventHandlers(): void {
this.client.ev.on('connection.update', (update) => {
this.handleConnectionUpdate(update);
});
this.client.ev.on('messages.upsert', ({ messages, type }) => {
this.handleIncomingMessages(messages, type);
});
this.client.ev.on('messages.update', (updates) => {
this.handleMessageUpdates(updates);
});
this.client.ev.on('contacts.upsert', (contacts) => {
this.handleContactsUpdate(contacts);
});
this.client.ev.on('chats.upsert', (chats) => {
this.handleChatsUpdate(chats);
});
}
private async handleConnectionUpdate(update: ConnectionUpdate): Promise<void> {
const { connection, lastDisconnect, qr } = update;
if (qr) {
this.instance.qrcode = {
count: this.instance.qrcode?.count ? this.instance.qrcode.count + 1 : 1,
base64: qr,
};
this.eventEmitter.emit(Events.QRCODE_UPDATED, {
instanceName: this.instance.name,
qrcode: this.instance.qrcode,
});
}
if (connection === 'close') {
const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut;
if (shouldReconnect) {
this.logger.log('Connection closed, reconnecting...');
await this.connectToWhatsapp();
} else {
this.logger.log('Connection closed, logged out');
this.eventEmitter.emit(Events.LOGOUT_INSTANCE, {
instanceName: this.instance.name,
});
}
}
if (connection === 'open') {
this.logger.log('Connection opened successfully');
this.instance.wuid = this.client.user?.id;
this.eventEmitter.emit(Events.CONNECTION_UPDATE, {
instanceName: this.instance.name,
state: 'open',
});
}
}
public async sendMessage(data: SendTextDto): Promise<any> {
const jid = createJid(data.number);
const message = {
text: data.text,
};
if (data.linkPreview !== undefined) {
message.linkPreview = data.linkPreview;
}
if (data.mentionsEveryOne) {
// Handle mentions
}
try {
const response = await this.client.sendMessage(jid, message);
return response;
} catch (error) {
this.logger.error(`Failed to send message: ${error.message}`);
throw new BadRequestException('Failed to send message');
}
}
}
```
## Channel Router Pattern
### Channel Router Structure
```typescript
export class ChannelRouter {
public readonly router: Router;
constructor(configService: any, ...guards: any[]) {
this.router = Router();
this.router.use('/', new EvolutionRouter(configService).router);
this.router.use('/', new MetaRouter(configService).router);
this.router.use('/baileys', new BaileysRouter(...guards).router);
}
}
```
### Specific Channel Router
```typescript
export class EvolutionRouter extends RouterBroker {
constructor(private readonly configService: ConfigService) {
super();
this.router
.post(this.routerPath('webhook'), async (req, res) => {
const response = await evolutionController.receiveWebhook(req.body);
return res.status(HttpStatus.OK).json(response);
});
}
public readonly router: Router = Router();
}
```
## Integration Types
### Channel Data Types
```typescript
type ChannelDataType = {
configService: ConfigService;
eventEmitter: EventEmitter2;
prismaRepository: PrismaRepository;
cache: CacheService;
chatwootCache: CacheService;
baileysCache: CacheService;
providerFiles: ProviderFiles;
};
export enum Integration {
WHATSAPP_BUSINESS = 'WHATSAPP-BUSINESS',
WHATSAPP_BAILEYS = 'WHATSAPP-BAILEYS',
EVOLUTION = 'EVOLUTION',
}
```
## Error Handling in Channels
### Channel-Specific Error Handling
```typescript
// CORRECT - Channel-specific error handling
public async sendMessage(data: SendTextDto): Promise<any> {
try {
const response = await this.channelSpecificSend(data);
return response;
} catch (error) {
this.logger.error(`${this.constructor.name} send failed: ${error.message}`);
if (error.response?.status === 401) {
throw new UnauthorizedException('Invalid token for channel');
}
if (error.response?.status === 429) {
throw new BadRequestException('Rate limit exceeded');
}
throw new InternalServerErrorException('Channel communication failed');
}
}
```
## Channel Testing Pattern
### Channel Service Testing
```typescript
describe('EvolutionStartupService', () => {
let service: EvolutionStartupService;
let configService: jest.Mocked<ConfigService>;
let eventEmitter: jest.Mocked<EventEmitter2>;
beforeEach(() => {
const mockConfig = {
get: jest.fn().mockReturnValue({
API_URL: 'https://api.evolution.com',
}),
};
service = new EvolutionStartupService(
mockConfig as any,
eventEmitter,
prismaRepository,
cache,
chatwootCache,
);
});
describe('sendMessage', () => {
it('should send message successfully', async () => {
const data = { number: '5511999999999', text: 'Test message' };
// Mock axios response
jest.spyOn(axios, 'post').mockResolvedValue({
data: { success: true, messageId: '123' },
});
const result = await service.sendMessage(data);
expect(result.success).toBe(true);
expect(axios.post).toHaveBeenCalledWith(
expect.stringContaining('/send-message'),
data,
expect.objectContaining({
headers: expect.objectContaining({
'Authorization': expect.stringContaining('Bearer'),
}),
})
);
});
});
});
```

View File

@@ -0,0 +1,597 @@
---
description: Chatbot integration patterns for Evolution API
globs:
- "src/api/integrations/chatbot/**/*.ts"
alwaysApply: false
---
# Evolution API Chatbot Integration Rules
## Base Chatbot Pattern
### Base Chatbot DTO
```typescript
/**
* Base DTO for all chatbot integrations
* Contains common properties shared by all chatbot types
*/
export class BaseChatbotDto {
enabled?: boolean;
description: string;
expire?: number;
keywordFinish?: string;
delayMessage?: number;
unknownMessage?: string;
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
triggerType: TriggerType;
triggerOperator?: TriggerOperator;
triggerValue?: string;
ignoreJids?: string[];
splitMessages?: boolean;
timePerChar?: number;
}
```
### Base Chatbot Controller
```typescript
export abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>
extends ChatbotController
implements ChatbotControllerInterface
{
public readonly logger: Logger;
integrationEnabled: boolean;
botRepository: any;
settingsRepository: any;
sessionRepository: any;
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
// Abstract methods to be implemented by specific chatbots
protected abstract readonly integrationName: string;
protected abstract processBot(
waInstance: any,
remoteJid: string,
bot: BotType,
session: any,
settings: ChatbotSettings,
content: string,
pushName?: string,
msg?: any,
): Promise<void>;
protected abstract getFallbackBotId(settings: any): string | undefined;
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
super(prismaRepository, waMonitor);
this.sessionRepository = this.prismaRepository.integrationSession;
}
// Base implementation methods
public async createBot(instance: InstanceDto, data: BotData) {
if (!data.enabled) {
throw new BadRequestException(`${this.integrationName} is disabled`);
}
// Common bot creation logic
const bot = await this.botRepository.create({
data: {
...data,
instanceId: instance.instanceId,
},
});
return bot;
}
}
```
### Base Chatbot Service
```typescript
/**
* Base class for all chatbot service implementations
* Contains common methods shared across different chatbot integrations
*/
export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
protected readonly logger: Logger;
protected readonly waMonitor: WAMonitoringService;
protected readonly prismaRepository: PrismaRepository;
protected readonly configService?: ConfigService;
constructor(
waMonitor: WAMonitoringService,
prismaRepository: PrismaRepository,
loggerName: string,
configService?: ConfigService,
) {
this.waMonitor = waMonitor;
this.prismaRepository = prismaRepository;
this.logger = new Logger(loggerName);
this.configService = configService;
}
/**
* Check if a message contains an image
*/
protected isImageMessage(content: string): boolean {
return content.includes('imageMessage');
}
/**
* Extract text content from message
*/
protected getMessageContent(msg: any): string {
return getConversationMessage(msg);
}
/**
* Send typing indicator
*/
protected async sendTyping(instanceName: string, remoteJid: string): Promise<void> {
await this.waMonitor.waInstances[instanceName].sendPresence(remoteJid, 'composing');
}
}
```
## Typebot Integration Pattern
### Typebot Service
```typescript
export class TypebotService extends BaseChatbotService<TypebotModel, any> {
constructor(
waMonitor: WAMonitoringService,
configService: ConfigService,
prismaRepository: PrismaRepository,
private readonly openaiService: OpenaiService,
) {
super(waMonitor, prismaRepository, 'TypebotService', configService);
}
public async sendTypebotMessage(
instanceName: string,
remoteJid: string,
typebot: TypebotModel,
content: string,
): Promise<void> {
try {
const response = await axios.post(
`${typebot.url}/api/v1/typebots/${typebot.typebot}/startChat`,
{
message: content,
sessionId: `${instanceName}-${remoteJid}`,
},
{
headers: {
'Content-Type': 'application/json',
},
}
);
const { messages } = response.data;
for (const message of messages) {
await this.processTypebotMessage(instanceName, remoteJid, message);
}
} catch (error) {
this.logger.error(`Typebot API error: ${error.message}`);
throw new InternalServerErrorException('Typebot communication failed');
}
}
private async processTypebotMessage(
instanceName: string,
remoteJid: string,
message: any,
): Promise<void> {
const waInstance = this.waMonitor.waInstances[instanceName];
if (message.type === 'text') {
await waInstance.sendMessage({
number: remoteJid.split('@')[0],
text: message.content.richText[0].children[0].text,
});
}
if (message.type === 'image') {
await waInstance.sendMessage({
number: remoteJid.split('@')[0],
mediaMessage: {
mediatype: 'image',
media: message.content.url,
},
});
}
}
}
```
## OpenAI Integration Pattern
### OpenAI Service
```typescript
export class OpenaiService extends BaseChatbotService<OpenaiModel, any> {
constructor(
waMonitor: WAMonitoringService,
prismaRepository: PrismaRepository,
configService: ConfigService,
) {
super(waMonitor, prismaRepository, 'OpenaiService', configService);
}
public async sendOpenaiMessage(
instanceName: string,
remoteJid: string,
openai: OpenaiModel,
content: string,
pushName?: string,
): Promise<void> {
try {
const openaiConfig = this.configService.get<Openai>('OPENAI');
const response = await axios.post(
'https://api.openai.com/v1/chat/completions',
{
model: openai.model || 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: openai.systemMessage || 'You are a helpful assistant.',
},
{
role: 'user',
content: content,
},
],
max_tokens: openai.maxTokens || 1000,
temperature: openai.temperature || 0.7,
},
{
headers: {
'Authorization': `Bearer ${openai.apiKey || openaiConfig.API_KEY}`,
'Content-Type': 'application/json',
},
}
);
const aiResponse = response.data.choices[0].message.content;
await this.waMonitor.waInstances[instanceName].sendMessage({
number: remoteJid.split('@')[0],
text: aiResponse,
});
} catch (error) {
this.logger.error(`OpenAI API error: ${error.message}`);
// Send fallback message
await this.waMonitor.waInstances[instanceName].sendMessage({
number: remoteJid.split('@')[0],
text: openai.unknownMessage || 'Desculpe, não consegui processar sua mensagem.',
});
}
}
}
```
## Chatwoot Integration Pattern
### Chatwoot Service
```typescript
export class ChatwootService extends BaseChatbotService<any, any> {
constructor(
waMonitor: WAMonitoringService,
configService: ConfigService,
prismaRepository: PrismaRepository,
private readonly chatwootCache: CacheService,
) {
super(waMonitor, prismaRepository, 'ChatwootService', configService);
}
public async eventWhatsapp(
event: Events,
instanceName: { instanceName: string },
data: any,
): Promise<void> {
const chatwootConfig = this.configService.get<Chatwoot>('CHATWOOT');
if (!chatwootConfig.ENABLED) {
return;
}
try {
const instance = await this.prismaRepository.instance.findUnique({
where: { name: instanceName.instanceName },
});
if (!instance?.chatwootAccountId) {
return;
}
const webhook = {
event,
instance: instanceName.instanceName,
data,
timestamp: new Date().toISOString(),
};
await axios.post(
`${instance.chatwootUrl}/api/v1/accounts/${instance.chatwootAccountId}/webhooks`,
webhook,
{
headers: {
'Authorization': `Bearer ${instance.chatwootToken}`,
'Content-Type': 'application/json',
},
}
);
} catch (error) {
this.logger.error(`Chatwoot webhook error: ${error.message}`);
}
}
public async createConversation(
instanceName: string,
contact: any,
message: any,
): Promise<void> {
// Create conversation in Chatwoot
const instance = await this.prismaRepository.instance.findUnique({
where: { name: instanceName },
});
if (!instance?.chatwootAccountId) {
return;
}
try {
const conversation = await axios.post(
`${instance.chatwootUrl}/api/v1/accounts/${instance.chatwootAccountId}/conversations`,
{
source_id: contact.id,
inbox_id: instance.chatwootInboxId,
contact_id: contact.chatwootContactId,
},
{
headers: {
'Authorization': `Bearer ${instance.chatwootToken}`,
'Content-Type': 'application/json',
},
}
);
// Cache conversation
await this.chatwootCache.set(
`conversation:${instanceName}:${contact.id}`,
conversation.data,
3600
);
} catch (error) {
this.logger.error(`Chatwoot conversation creation error: ${error.message}`);
}
}
}
```
## Dify Integration Pattern
### Dify Service
```typescript
export class DifyService extends BaseChatbotService<DifyModel, any> {
constructor(
waMonitor: WAMonitoringService,
prismaRepository: PrismaRepository,
configService: ConfigService,
private readonly openaiService: OpenaiService,
) {
super(waMonitor, prismaRepository, 'DifyService', configService);
}
public async sendDifyMessage(
instanceName: string,
remoteJid: string,
dify: DifyModel,
content: string,
): Promise<void> {
try {
const response = await axios.post(
`${dify.apiUrl}/v1/chat-messages`,
{
inputs: {},
query: content,
user: remoteJid,
conversation_id: `${instanceName}-${remoteJid}`,
response_mode: 'blocking',
},
{
headers: {
'Authorization': `Bearer ${dify.apiKey}`,
'Content-Type': 'application/json',
},
}
);
const aiResponse = response.data.answer;
await this.waMonitor.waInstances[instanceName].sendMessage({
number: remoteJid.split('@')[0],
text: aiResponse,
});
} catch (error) {
this.logger.error(`Dify API error: ${error.message}`);
// Fallback to OpenAI if configured
if (dify.fallbackOpenai && this.openaiService) {
await this.openaiService.sendOpenaiMessage(instanceName, remoteJid, dify.openaiBot, content);
}
}
}
}
```
## Chatbot Router Pattern
### Chatbot Router Structure (Evolution API Real Pattern)
```typescript
export class ChatbotRouter {
public readonly router: Router;
constructor(...guards: any[]) {
this.router = Router();
// Real Evolution API chatbot integrations
this.router.use('/evolutionBot', new EvolutionBotRouter(...guards).router);
this.router.use('/chatwoot', new ChatwootRouter(...guards).router);
this.router.use('/typebot', new TypebotRouter(...guards).router);
this.router.use('/openai', new OpenaiRouter(...guards).router);
this.router.use('/dify', new DifyRouter(...guards).router);
this.router.use('/flowise', new FlowiseRouter(...guards).router);
this.router.use('/n8n', new N8nRouter(...guards).router);
this.router.use('/evoai', new EvoaiRouter(...guards).router);
}
}
```
## Chatbot Validation Patterns
### Chatbot Schema Validation (Evolution API Pattern)
```typescript
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...fields: string[]) => {
const properties = {};
fields.forEach((field) => {
properties[field] = {
if: { properties: { [field]: { type: 'string' } } },
then: { properties: { [field]: { minLength: 1 } } },
};
});
return {
allOf: Object.values(properties),
};
};
export const evolutionBotSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean' },
description: { type: 'string' },
apiUrl: { type: 'string' },
apiKey: { type: 'string' },
triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },
triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },
triggerValue: { type: 'string' },
expire: { type: 'integer' },
keywordFinish: { type: 'string' },
delayMessage: { type: 'integer' },
unknownMessage: { type: 'string' },
listeningFromMe: { type: 'boolean' },
stopBotFromMe: { type: 'boolean' },
keepOpen: { type: 'boolean' },
debounceTime: { type: 'integer' },
ignoreJids: { type: 'array', items: { type: 'string' } },
splitMessages: { type: 'boolean' },
timePerChar: { type: 'integer' },
},
required: ['enabled', 'apiUrl', 'triggerType'],
...isNotEmpty('enabled', 'apiUrl', 'triggerType'),
};
function validateKeywordTrigger(
content: string,
operator: TriggerOperator,
value: string,
): boolean {
const normalizedContent = content.toLowerCase().trim();
const normalizedValue = value.toLowerCase().trim();
switch (operator) {
case TriggerOperator.EQUALS:
return normalizedContent === normalizedValue;
case TriggerOperator.CONTAINS:
return normalizedContent.includes(normalizedValue);
case TriggerOperator.STARTS_WITH:
return normalizedContent.startsWith(normalizedValue);
case TriggerOperator.ENDS_WITH:
return normalizedContent.endsWith(normalizedValue);
default:
return false;
}
}
```
## Session Management Pattern
### Chatbot Session Handling
```typescript
export class ChatbotSessionManager {
constructor(
private readonly prismaRepository: PrismaRepository,
private readonly cache: CacheService,
) {}
public async getSession(
instanceName: string,
remoteJid: string,
botId: string,
): Promise<IntegrationSession | null> {
const cacheKey = `session:${instanceName}:${remoteJid}:${botId}`;
// Try cache first
let session = await this.cache.get(cacheKey);
if (session) {
return session;
}
// Query database
session = await this.prismaRepository.integrationSession.findFirst({
where: {
instanceId: instanceName,
remoteJid,
botId,
status: 'opened',
},
});
// Cache result
if (session) {
await this.cache.set(cacheKey, session, 300); // 5 min TTL
}
return session;
}
public async createSession(
instanceName: string,
remoteJid: string,
botId: string,
): Promise<IntegrationSession> {
const session = await this.prismaRepository.integrationSession.create({
data: {
instanceId: instanceName,
remoteJid,
botId,
status: 'opened',
createdAt: new Date(),
},
});
// Cache new session
const cacheKey = `session:${instanceName}:${remoteJid}:${botId}`;
await this.cache.set(cacheKey, session, 300);
return session;
}
public async closeSession(sessionId: string): Promise<void> {
await this.prismaRepository.integrationSession.update({
where: { id: sessionId },
data: { status: 'closed', updatedAt: new Date() },
});
// Invalidate cache
// Note: In a real implementation, you'd need to track cache keys by session ID
}
}
```

View File

@@ -0,0 +1,851 @@
---
description: Event integration patterns for Evolution API
globs:
- "src/api/integrations/event/**/*.ts"
alwaysApply: false
---
# Evolution API Event Integration Rules
## Event Manager Pattern
### Event Manager Structure
```typescript
import { PrismaRepository } from '@api/repository/repository.service';
import { ConfigService } from '@config/env.config';
import { Logger } from '@config/logger.config';
import { Server } from 'http';
export class EventManager {
private prismaRepository: PrismaRepository;
private configService: ConfigService;
private logger = new Logger('EventManager');
// Event integrations
private webhook: WebhookController;
private websocket: WebsocketController;
private rabbitmq: RabbitmqController;
private nats: NatsController;
private sqs: SqsController;
private pusher: PusherController;
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
server?: Server,
) {
this.prismaRepository = prismaRepository;
this.configService = configService;
// Initialize event controllers
this.webhook = new WebhookController(prismaRepository, configService);
this.websocket = new WebsocketController(prismaRepository, configService, server);
this.rabbitmq = new RabbitmqController(prismaRepository, configService);
this.nats = new NatsController(prismaRepository, configService);
this.sqs = new SqsController(prismaRepository, configService);
this.pusher = new PusherController(prismaRepository, configService);
}
public async emit(eventData: {
instanceName: string;
origin: string;
event: string;
data: Object;
serverUrl: string;
dateTime: string;
sender: string;
apiKey?: string;
local?: boolean;
integration?: string[];
}): Promise<void> {
this.logger.log(`Emitting event ${eventData.event} for instance ${eventData.instanceName}`);
// Emit to all configured integrations
await Promise.allSettled([
this.webhook.emit(eventData),
this.websocket.emit(eventData),
this.rabbitmq.emit(eventData),
this.nats.emit(eventData),
this.sqs.emit(eventData),
this.pusher.emit(eventData),
]);
}
public async setInstance(instanceName: string, data: any): Promise<any> {
const promises = [];
if (data.websocket) {
promises.push(
this.websocket.set(instanceName, {
websocket: {
enabled: true,
events: data.websocket?.events,
},
})
);
}
if (data.rabbitmq) {
promises.push(
this.rabbitmq.set(instanceName, {
rabbitmq: {
enabled: true,
events: data.rabbitmq?.events,
},
})
);
}
if (data.webhook) {
promises.push(
this.webhook.set(instanceName, {
webhook: {
enabled: true,
events: data.webhook?.events,
url: data.webhook?.url,
headers: data.webhook?.headers,
base64: data.webhook?.base64,
byEvents: data.webhook?.byEvents,
},
})
);
}
// Set other integrations...
await Promise.allSettled(promises);
}
}
```
## Base Event Controller Pattern
### Abstract Event Controller
```typescript
import { PrismaRepository } from '@api/repository/repository.service';
import { ConfigService } from '@config/env.config';
import { Logger } from '@config/logger.config';
export type EmitData = {
instanceName: string;
origin: string;
event: string;
data: Object;
serverUrl: string;
dateTime: string;
sender: string;
apiKey?: string;
local?: boolean;
integration?: string[];
};
export interface EventControllerInterface {
integrationEnabled: boolean;
emit(data: EmitData): Promise<void>;
set(instanceName: string, data: any): Promise<any>;
}
export abstract class EventController implements EventControllerInterface {
protected readonly logger: Logger;
protected readonly prismaRepository: PrismaRepository;
protected readonly configService: ConfigService;
public integrationEnabled: boolean = false;
// Available events for all integrations
public static readonly events = [
'APPLICATION_STARTUP',
'INSTANCE_CREATE',
'INSTANCE_DELETE',
'QRCODE_UPDATED',
'CONNECTION_UPDATE',
'STATUS_INSTANCE',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPDATE',
'CHATS_UPSERT',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUPS_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CREDS_UPDATE',
'MESSAGING_HISTORY_SET',
'REMOVE_INSTANCE',
'LOGOUT_INSTANCE',
];
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
loggerName: string,
) {
this.prismaRepository = prismaRepository;
this.configService = configService;
this.logger = new Logger(loggerName);
}
// Abstract methods to be implemented by specific integrations
public abstract emit(data: EmitData): Promise<void>;
public abstract set(instanceName: string, data: any): Promise<any>;
// Helper method to check if event should be processed
protected shouldProcessEvent(eventName: string, configuredEvents?: string[]): boolean {
if (!configuredEvents || configuredEvents.length === 0) {
return true; // Process all events if none specified
}
return configuredEvents.includes(eventName);
}
// Helper method to get instance configuration
protected async getInstanceConfig(instanceName: string): Promise<any> {
try {
const instance = await this.prismaRepository.instance.findUnique({
where: { name: instanceName },
});
return instance;
} catch (error) {
this.logger.error(`Failed to get instance config for ${instanceName}:`, error);
return null;
}
}
}
```
## Webhook Integration Pattern
### Webhook Controller Implementation
```typescript
export class WebhookController extends EventController {
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
) {
super(prismaRepository, configService, 'WebhookController');
}
public async emit(data: EmitData): Promise<void> {
try {
const instance = await this.getInstanceConfig(data.instanceName);
if (!instance?.webhook?.enabled) {
return;
}
const webhookConfig = instance.webhook;
if (!this.shouldProcessEvent(data.event, webhookConfig.events)) {
return;
}
const payload = {
event: data.event,
instance: data.instanceName,
data: data.data,
timestamp: data.dateTime,
sender: data.sender,
server: {
version: process.env.npm_package_version,
url: data.serverUrl,
},
};
// Encode data as base64 if configured
if (webhookConfig.base64) {
payload.data = Buffer.from(JSON.stringify(payload.data)).toString('base64');
}
const headers = {
'Content-Type': 'application/json',
'User-Agent': 'Evolution-API-Webhook',
...webhookConfig.headers,
};
if (webhookConfig.byEvents) {
// Send to event-specific endpoint
const eventUrl = `${webhookConfig.url}/${data.event.toLowerCase()}`;
await this.sendWebhook(eventUrl, payload, headers);
} else {
// Send to main webhook URL
await this.sendWebhook(webhookConfig.url, payload, headers);
}
this.logger.log(`Webhook sent for event ${data.event} to instance ${data.instanceName}`);
} catch (error) {
this.logger.error(`Webhook emission failed for ${data.instanceName}:`, error);
}
}
public async set(instanceName: string, data: any): Promise<any> {
try {
const webhookData = data.webhook;
await this.prismaRepository.instance.update({
where: { name: instanceName },
data: {
webhook: webhookData,
},
});
this.logger.log(`Webhook configuration set for instance ${instanceName}`);
return { webhook: webhookData };
} catch (error) {
this.logger.error(`Failed to set webhook config for ${instanceName}:`, error);
throw error;
}
}
private async sendWebhook(url: string, payload: any, headers: any): Promise<void> {
try {
const response = await axios.post(url, payload, {
headers,
timeout: 30000,
maxRedirects: 3,
});
if (response.status >= 200 && response.status < 300) {
this.logger.log(`Webhook delivered successfully to ${url}`);
} else {
this.logger.warn(`Webhook returned status ${response.status} for ${url}`);
}
} catch (error) {
this.logger.error(`Webhook delivery failed to ${url}:`, error.message);
// Implement retry logic here if needed
if (error.response?.status >= 500) {
// Server error - might be worth retrying
this.logger.log(`Server error detected, webhook might be retried later`);
}
}
}
}
```
## WebSocket Integration Pattern
### WebSocket Controller Implementation
```typescript
import { Server as SocketIOServer } from 'socket.io';
import { Server } from 'http';
export class WebsocketController extends EventController {
private io: SocketIOServer;
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
server?: Server,
) {
super(prismaRepository, configService, 'WebsocketController');
if (server) {
this.io = new SocketIOServer(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
this.setupSocketHandlers();
}
}
private setupSocketHandlers(): void {
this.io.on('connection', (socket) => {
this.logger.log(`WebSocket client connected: ${socket.id}`);
socket.on('join-instance', (instanceName: string) => {
socket.join(`instance:${instanceName}`);
this.logger.log(`Client ${socket.id} joined instance ${instanceName}`);
});
socket.on('leave-instance', (instanceName: string) => {
socket.leave(`instance:${instanceName}`);
this.logger.log(`Client ${socket.id} left instance ${instanceName}`);
});
socket.on('disconnect', () => {
this.logger.log(`WebSocket client disconnected: ${socket.id}`);
});
});
}
public async emit(data: EmitData): Promise<void> {
if (!this.io) {
return;
}
try {
const instance = await this.getInstanceConfig(data.instanceName);
if (!instance?.websocket?.enabled) {
return;
}
const websocketConfig = instance.websocket;
if (!this.shouldProcessEvent(data.event, websocketConfig.events)) {
return;
}
const payload = {
event: data.event,
instance: data.instanceName,
data: data.data,
timestamp: data.dateTime,
sender: data.sender,
};
// Emit to specific instance room
this.io.to(`instance:${data.instanceName}`).emit('evolution-event', payload);
// Also emit to global room for monitoring
this.io.emit('global-event', payload);
this.logger.log(`WebSocket event ${data.event} emitted for instance ${data.instanceName}`);
} catch (error) {
this.logger.error(`WebSocket emission failed for ${data.instanceName}:`, error);
}
}
public async set(instanceName: string, data: any): Promise<any> {
try {
const websocketData = data.websocket;
await this.prismaRepository.instance.update({
where: { name: instanceName },
data: {
websocket: websocketData,
},
});
this.logger.log(`WebSocket configuration set for instance ${instanceName}`);
return { websocket: websocketData };
} catch (error) {
this.logger.error(`Failed to set WebSocket config for ${instanceName}:`, error);
throw error;
}
}
}
```
## Queue Integration Patterns
### RabbitMQ Controller Implementation
```typescript
import amqp from 'amqplib';
export class RabbitmqController extends EventController {
private connection: amqp.Connection | null = null;
private channel: amqp.Channel | null = null;
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
) {
super(prismaRepository, configService, 'RabbitmqController');
this.initializeConnection();
}
private async initializeConnection(): Promise<void> {
try {
const rabbitmqConfig = this.configService.get('RABBITMQ');
if (!rabbitmqConfig?.ENABLED) {
return;
}
this.connection = await amqp.connect(rabbitmqConfig.URI);
this.channel = await this.connection.createChannel();
// Declare exchange for Evolution API events
await this.channel.assertExchange('evolution-events', 'topic', { durable: true });
this.logger.log('RabbitMQ connection established');
} catch (error) {
this.logger.error('Failed to initialize RabbitMQ connection:', error);
}
}
public async emit(data: EmitData): Promise<void> {
if (!this.channel) {
return;
}
try {
const instance = await this.getInstanceConfig(data.instanceName);
if (!instance?.rabbitmq?.enabled) {
return;
}
const rabbitmqConfig = instance.rabbitmq;
if (!this.shouldProcessEvent(data.event, rabbitmqConfig.events)) {
return;
}
const payload = {
event: data.event,
instance: data.instanceName,
data: data.data,
timestamp: data.dateTime,
sender: data.sender,
};
const routingKey = `evolution.${data.instanceName}.${data.event.toLowerCase()}`;
await this.channel.publish(
'evolution-events',
routingKey,
Buffer.from(JSON.stringify(payload)),
{
persistent: true,
timestamp: Date.now(),
messageId: `${data.instanceName}-${Date.now()}`,
}
);
this.logger.log(`RabbitMQ message published for event ${data.event} to instance ${data.instanceName}`);
} catch (error) {
this.logger.error(`RabbitMQ emission failed for ${data.instanceName}:`, error);
}
}
public async set(instanceName: string, data: any): Promise<any> {
try {
const rabbitmqData = data.rabbitmq;
await this.prismaRepository.instance.update({
where: { name: instanceName },
data: {
rabbitmq: rabbitmqData,
},
});
this.logger.log(`RabbitMQ configuration set for instance ${instanceName}`);
return { rabbitmq: rabbitmqData };
} catch (error) {
this.logger.error(`Failed to set RabbitMQ config for ${instanceName}:`, error);
throw error;
}
}
}
```
### SQS Controller Implementation
```typescript
import { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';
export class SqsController extends EventController {
private sqsClient: SQSClient | null = null;
constructor(
prismaRepository: PrismaRepository,
configService: ConfigService,
) {
super(prismaRepository, configService, 'SqsController');
this.initializeSQSClient();
}
private initializeSQSClient(): void {
try {
const sqsConfig = this.configService.get('SQS');
if (!sqsConfig?.ENABLED) {
return;
}
this.sqsClient = new SQSClient({
region: sqsConfig.REGION,
credentials: {
accessKeyId: sqsConfig.ACCESS_KEY_ID,
secretAccessKey: sqsConfig.SECRET_ACCESS_KEY,
},
});
this.logger.log('SQS client initialized');
} catch (error) {
this.logger.error('Failed to initialize SQS client:', error);
}
}
public async emit(data: EmitData): Promise<void> {
if (!this.sqsClient) {
return;
}
try {
const instance = await this.getInstanceConfig(data.instanceName);
if (!instance?.sqs?.enabled) {
return;
}
const sqsConfig = instance.sqs;
if (!this.shouldProcessEvent(data.event, sqsConfig.events)) {
return;
}
const payload = {
event: data.event,
instance: data.instanceName,
data: data.data,
timestamp: data.dateTime,
sender: data.sender,
};
const command = new SendMessageCommand({
QueueUrl: sqsConfig.queueUrl,
MessageBody: JSON.stringify(payload),
MessageAttributes: {
event: {
DataType: 'String',
StringValue: data.event,
},
instance: {
DataType: 'String',
StringValue: data.instanceName,
},
},
MessageGroupId: data.instanceName, // For FIFO queues
MessageDeduplicationId: `${data.instanceName}-${Date.now()}`, // For FIFO queues
});
await this.sqsClient.send(command);
this.logger.log(`SQS message sent for event ${data.event} to instance ${data.instanceName}`);
} catch (error) {
this.logger.error(`SQS emission failed for ${data.instanceName}:`, error);
}
}
public async set(instanceName: string, data: any): Promise<any> {
try {
const sqsData = data.sqs;
await this.prismaRepository.instance.update({
where: { name: instanceName },
data: {
sqs: sqsData,
},
});
this.logger.log(`SQS configuration set for instance ${instanceName}`);
return { sqs: sqsData };
} catch (error) {
this.logger.error(`Failed to set SQS config for ${instanceName}:`, error);
throw error;
}
}
}
```
## Event DTO Pattern
### Event Configuration DTO
```typescript
import { JsonValue } from '@prisma/client/runtime/library';
export class EventDto {
webhook?: {
enabled?: boolean;
events?: string[];
url?: string;
headers?: JsonValue;
byEvents?: boolean;
base64?: boolean;
};
websocket?: {
enabled?: boolean;
events?: string[];
};
sqs?: {
enabled?: boolean;
events?: string[];
queueUrl?: string;
};
rabbitmq?: {
enabled?: boolean;
events?: string[];
exchange?: string;
};
nats?: {
enabled?: boolean;
events?: string[];
subject?: string;
};
pusher?: {
enabled?: boolean;
appId?: string;
key?: string;
secret?: string;
cluster?: string;
useTLS?: boolean;
events?: string[];
};
}
```
## Event Router Pattern
### Event Router Structure
```typescript
import { NatsRouter } from '@api/integrations/event/nats/nats.router';
import { PusherRouter } from '@api/integrations/event/pusher/pusher.router';
import { RabbitmqRouter } from '@api/integrations/event/rabbitmq/rabbitmq.router';
import { SqsRouter } from '@api/integrations/event/sqs/sqs.router';
import { WebhookRouter } from '@api/integrations/event/webhook/webhook.router';
import { WebsocketRouter } from '@api/integrations/event/websocket/websocket.router';
import { Router } from 'express';
export class EventRouter {
public readonly router: Router;
constructor(configService: any, ...guards: any[]) {
this.router = Router();
this.router.use('/webhook', new WebhookRouter(configService, ...guards).router);
this.router.use('/websocket', new WebsocketRouter(...guards).router);
this.router.use('/rabbitmq', new RabbitmqRouter(...guards).router);
this.router.use('/nats', new NatsRouter(...guards).router);
this.router.use('/pusher', new PusherRouter(...guards).router);
this.router.use('/sqs', new SqsRouter(...guards).router);
}
}
```
## Event Validation Schema
### Event Configuration Validation
```typescript
import Joi from 'joi';
import { EventController } from '@api/integrations/event/event.controller';
const eventListSchema = Joi.array().items(
Joi.string().valid(...EventController.events)
).optional();
export const webhookSchema = Joi.object({
enabled: Joi.boolean().required(),
url: Joi.string().when('enabled', {
is: true,
then: Joi.required().uri({ scheme: ['http', 'https'] }),
otherwise: Joi.optional(),
}),
events: eventListSchema,
headers: Joi.object().pattern(Joi.string(), Joi.string()).optional(),
byEvents: Joi.boolean().optional().default(false),
base64: Joi.boolean().optional().default(false),
}).required();
export const websocketSchema = Joi.object({
enabled: Joi.boolean().required(),
events: eventListSchema,
}).required();
export const rabbitmqSchema = Joi.object({
enabled: Joi.boolean().required(),
events: eventListSchema,
exchange: Joi.string().optional().default('evolution-events'),
}).required();
export const sqsSchema = Joi.object({
enabled: Joi.boolean().required(),
events: eventListSchema,
queueUrl: Joi.string().when('enabled', {
is: true,
then: Joi.required().uri(),
otherwise: Joi.optional(),
}),
}).required();
export const eventSchema = Joi.object({
webhook: webhookSchema.optional(),
websocket: websocketSchema.optional(),
rabbitmq: rabbitmqSchema.optional(),
sqs: sqsSchema.optional(),
nats: Joi.object({
enabled: Joi.boolean().required(),
events: eventListSchema,
subject: Joi.string().optional().default('evolution.events'),
}).optional(),
pusher: Joi.object({
enabled: Joi.boolean().required(),
appId: Joi.string().when('enabled', { is: true, then: Joi.required() }),
key: Joi.string().when('enabled', { is: true, then: Joi.required() }),
secret: Joi.string().when('enabled', { is: true, then: Joi.required() }),
cluster: Joi.string().when('enabled', { is: true, then: Joi.required() }),
useTLS: Joi.boolean().optional().default(true),
events: eventListSchema,
}).optional(),
}).min(1).required();
```
## Event Testing Pattern
### Event Controller Testing
```typescript
describe('WebhookController', () => {
let controller: WebhookController;
let prismaRepository: jest.Mocked<PrismaRepository>;
let configService: jest.Mocked<ConfigService>;
beforeEach(() => {
controller = new WebhookController(prismaRepository, configService);
});
describe('emit', () => {
it('should send webhook when enabled', async () => {
const mockInstance = {
webhook: {
enabled: true,
url: 'https://example.com/webhook',
events: ['MESSAGES_UPSERT'],
},
};
prismaRepository.instance.findUnique.mockResolvedValue(mockInstance);
jest.spyOn(axios, 'post').mockResolvedValue({ status: 200 });
const eventData = {
instanceName: 'test-instance',
event: 'MESSAGES_UPSERT',
data: { message: 'test' },
origin: 'test',
serverUrl: 'http://localhost',
dateTime: new Date().toISOString(),
sender: 'test',
};
await controller.emit(eventData);
expect(axios.post).toHaveBeenCalledWith(
'https://example.com/webhook',
expect.objectContaining({
event: 'MESSAGES_UPSERT',
instance: 'test-instance',
}),
expect.objectContaining({
headers: expect.objectContaining({
'Content-Type': 'application/json',
}),
})
);
});
});
});
```

View File

@@ -0,0 +1,608 @@
---
description: Storage integration patterns for Evolution API
globs:
- "src/api/integrations/storage/**/*.ts"
alwaysApply: false
---
# Evolution API Storage Integration Rules
## Storage Service Pattern
### Base Storage Service Structure
```typescript
import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { Logger } from '@config/logger.config';
import { BadRequestException } from '@exceptions';
export class StorageService {
constructor(private readonly prismaRepository: PrismaRepository) {}
private readonly logger = new Logger('StorageService');
public async getMedia(instance: InstanceDto, query?: MediaDto) {
try {
const where: any = {
instanceId: instance.instanceId,
...query,
};
const media = await this.prismaRepository.media.findMany({
where,
select: {
id: true,
fileName: true,
type: true,
mimetype: true,
createdAt: true,
Message: true,
},
});
if (!media || media.length === 0) {
throw 'Media not found';
}
return media;
} catch (error) {
throw new BadRequestException(error);
}
}
public async getMediaUrl(instance: InstanceDto, data: MediaDto) {
const media = (await this.getMedia(instance, { id: data.id }))[0];
const mediaUrl = await this.generateUrl(media.fileName, data.expiry);
return {
mediaUrl,
...media,
};
}
protected abstract generateUrl(fileName: string, expiry?: number): Promise<string>;
}
```
## S3/MinIO Integration Pattern
### MinIO Client Setup
```typescript
import { ConfigService, S3 } from '@config/env.config';
import { Logger } from '@config/logger.config';
import { BadRequestException } from '@exceptions';
import * as MinIo from 'minio';
import { join } from 'path';
import { Readable, Transform } from 'stream';
const logger = new Logger('S3 Service');
const BUCKET = new ConfigService().get<S3>('S3');
interface Metadata extends MinIo.ItemBucketMetadata {
instanceId: string;
messageId?: string;
}
const minioClient = (() => {
if (BUCKET?.ENABLE) {
return new MinIo.Client({
endPoint: BUCKET.ENDPOINT,
port: BUCKET.PORT,
useSSL: BUCKET.USE_SSL,
accessKey: BUCKET.ACCESS_KEY,
secretKey: BUCKET.SECRET_KEY,
region: BUCKET.REGION,
});
}
})();
const bucketName = process.env.S3_BUCKET;
```
### Bucket Management Functions
```typescript
const bucketExists = async (): Promise<boolean> => {
if (minioClient) {
try {
const list = await minioClient.listBuckets();
return !!list.find((bucket) => bucket.name === bucketName);
} catch (error) {
logger.error('Error checking bucket existence:', error);
return false;
}
}
return false;
};
const setBucketPolicy = async (): Promise<void> => {
if (minioClient && bucketName) {
try {
const policy = {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: { AWS: ['*'] },
Action: ['s3:GetObject'],
Resource: [`arn:aws:s3:::${bucketName}/*`],
},
],
};
await minioClient.setBucketPolicy(bucketName, JSON.stringify(policy));
logger.log('Bucket policy set successfully');
} catch (error) {
logger.error('Error setting bucket policy:', error);
}
}
};
const createBucket = async (): Promise<void> => {
if (minioClient && bucketName) {
try {
const exists = await bucketExists();
if (!exists) {
await minioClient.makeBucket(bucketName, BUCKET.REGION || 'us-east-1');
await setBucketPolicy();
logger.log(`Bucket ${bucketName} created successfully`);
}
} catch (error) {
logger.error('Error creating bucket:', error);
}
}
};
```
### File Upload Functions
```typescript
export const uploadFile = async (
fileName: string,
buffer: Buffer,
mimetype: string,
metadata?: Metadata,
): Promise<string> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
await createBucket();
const uploadMetadata = {
'Content-Type': mimetype,
...metadata,
};
await minioClient.putObject(bucketName, fileName, buffer, buffer.length, uploadMetadata);
logger.log(`File ${fileName} uploaded successfully`);
return fileName;
} catch (error) {
logger.error(`Error uploading file ${fileName}:`, error);
throw new BadRequestException(`Failed to upload file: ${error.message}`);
}
};
export const uploadStream = async (
fileName: string,
stream: Readable,
size: number,
mimetype: string,
metadata?: Metadata,
): Promise<string> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
await createBucket();
const uploadMetadata = {
'Content-Type': mimetype,
...metadata,
};
await minioClient.putObject(bucketName, fileName, stream, size, uploadMetadata);
logger.log(`Stream ${fileName} uploaded successfully`);
return fileName;
} catch (error) {
logger.error(`Error uploading stream ${fileName}:`, error);
throw new BadRequestException(`Failed to upload stream: ${error.message}`);
}
};
```
### File Download Functions
```typescript
export const getObject = async (fileName: string): Promise<Buffer> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
const stream = await minioClient.getObject(bucketName, fileName);
const chunks: Buffer[] = [];
return new Promise((resolve, reject) => {
stream.on('data', (chunk) => chunks.push(chunk));
stream.on('end', () => resolve(Buffer.concat(chunks)));
stream.on('error', reject);
});
} catch (error) {
logger.error(`Error getting object ${fileName}:`, error);
throw new BadRequestException(`Failed to get object: ${error.message}`);
}
};
export const getObjectUrl = async (fileName: string, expiry: number = 3600): Promise<string> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
const url = await minioClient.presignedGetObject(bucketName, fileName, expiry);
logger.log(`Generated URL for ${fileName} with expiry ${expiry}s`);
return url;
} catch (error) {
logger.error(`Error generating URL for ${fileName}:`, error);
throw new BadRequestException(`Failed to generate URL: ${error.message}`);
}
};
export const getObjectStream = async (fileName: string): Promise<Readable> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
const stream = await minioClient.getObject(bucketName, fileName);
return stream;
} catch (error) {
logger.error(`Error getting object stream ${fileName}:`, error);
throw new BadRequestException(`Failed to get object stream: ${error.message}`);
}
};
```
### File Management Functions
```typescript
export const deleteObject = async (fileName: string): Promise<void> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
await minioClient.removeObject(bucketName, fileName);
logger.log(`File ${fileName} deleted successfully`);
} catch (error) {
logger.error(`Error deleting file ${fileName}:`, error);
throw new BadRequestException(`Failed to delete file: ${error.message}`);
}
};
export const listObjects = async (prefix?: string): Promise<MinIo.BucketItem[]> => {
if (!minioClient || !bucketName) {
throw new BadRequestException('S3 storage not configured');
}
try {
const objects: MinIo.BucketItem[] = [];
const stream = minioClient.listObjects(bucketName, prefix, true);
return new Promise((resolve, reject) => {
stream.on('data', (obj) => objects.push(obj));
stream.on('end', () => resolve(objects));
stream.on('error', reject);
});
} catch (error) {
logger.error('Error listing objects:', error);
throw new BadRequestException(`Failed to list objects: ${error.message}`);
}
};
export const objectExists = async (fileName: string): Promise<boolean> => {
if (!minioClient || !bucketName) {
return false;
}
try {
await minioClient.statObject(bucketName, fileName);
return true;
} catch (error) {
return false;
}
};
```
## Storage Controller Pattern
### S3 Controller Implementation
```typescript
import { InstanceDto } from '@api/dto/instance.dto';
import { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';
import { S3Service } from '@api/integrations/storage/s3/services/s3.service';
export class S3Controller {
constructor(private readonly s3Service: S3Service) {}
public async getMedia(instance: InstanceDto, data: MediaDto) {
return this.s3Service.getMedia(instance, data);
}
public async getMediaUrl(instance: InstanceDto, data: MediaDto) {
return this.s3Service.getMediaUrl(instance, data);
}
public async uploadMedia(instance: InstanceDto, data: UploadMediaDto) {
return this.s3Service.uploadMedia(instance, data);
}
public async deleteMedia(instance: InstanceDto, data: MediaDto) {
return this.s3Service.deleteMedia(instance, data);
}
}
```
## Storage Router Pattern
### Storage Router Structure
```typescript
import { S3Router } from '@api/integrations/storage/s3/routes/s3.router';
import { Router } from 'express';
export class StorageRouter {
public readonly router: Router;
constructor(...guards: any[]) {
this.router = Router();
this.router.use('/s3', new S3Router(...guards).router);
// Add other storage providers here
// this.router.use('/gcs', new GCSRouter(...guards).router);
// this.router.use('/azure', new AzureRouter(...guards).router);
}
}
```
### S3 Specific Router
```typescript
import { RouterBroker } from '@api/abstract/abstract.router';
import { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';
import { s3Schema, s3UrlSchema } from '@api/integrations/storage/s3/validate/s3.schema';
import { HttpStatus } from '@api/routes/index.router';
import { s3Controller } from '@api/server.module';
import { RequestHandler, Router } from 'express';
export class S3Router extends RouterBroker {
constructor(...guards: RequestHandler[]) {
super();
this.router
.post(this.routerPath('getMedia'), ...guards, async (req, res) => {
const response = await this.dataValidate<MediaDto>({
request: req,
schema: s3Schema,
ClassRef: MediaDto,
execute: (instance, data) => s3Controller.getMedia(instance, data),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('getMediaUrl'), ...guards, async (req, res) => {
const response = await this.dataValidate<MediaDto>({
request: req,
schema: s3UrlSchema,
ClassRef: MediaDto,
execute: (instance, data) => s3Controller.getMediaUrl(instance, data),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('uploadMedia'), ...guards, async (req, res) => {
const response = await this.dataValidate<UploadMediaDto>({
request: req,
schema: uploadSchema,
ClassRef: UploadMediaDto,
execute: (instance, data) => s3Controller.uploadMedia(instance, data),
});
res.status(HttpStatus.CREATED).json(response);
})
.delete(this.routerPath('deleteMedia'), ...guards, async (req, res) => {
const response = await this.dataValidate<MediaDto>({
request: req,
schema: s3Schema,
ClassRef: MediaDto,
execute: (instance, data) => s3Controller.deleteMedia(instance, data),
});
res.status(HttpStatus.OK).json(response);
});
}
public readonly router: Router = Router();
}
```
## Storage DTO Pattern
### Media DTO
```typescript
export class MediaDto {
id?: string;
fileName?: string;
type?: string;
mimetype?: string;
expiry?: number;
}
export class UploadMediaDto {
fileName: string;
mimetype: string;
buffer?: Buffer;
base64?: string;
url?: string;
metadata?: {
instanceId: string;
messageId?: string;
contactId?: string;
[key: string]: any;
};
}
```
## Storage Validation Schema
### S3 Validation Schemas
```typescript
import Joi from 'joi';
export const s3Schema = Joi.object({
id: Joi.string().optional(),
fileName: Joi.string().optional(),
type: Joi.string().optional().valid('image', 'video', 'audio', 'document'),
mimetype: Joi.string().optional(),
expiry: Joi.number().optional().min(60).max(604800).default(3600), // 1 min to 7 days
}).min(1).required();
export const s3UrlSchema = Joi.object({
id: Joi.string().required(),
expiry: Joi.number().optional().min(60).max(604800).default(3600),
}).required();
export const uploadSchema = Joi.object({
fileName: Joi.string().required().max(255),
mimetype: Joi.string().required(),
buffer: Joi.binary().optional(),
base64: Joi.string().base64().optional(),
url: Joi.string().uri().optional(),
metadata: Joi.object({
instanceId: Joi.string().required(),
messageId: Joi.string().optional(),
contactId: Joi.string().optional(),
}).optional(),
}).xor('buffer', 'base64', 'url').required(); // Exactly one of these must be present
```
## Error Handling in Storage
### Storage-Specific Error Handling
```typescript
// CORRECT - Storage-specific error handling
public async uploadFile(fileName: string, buffer: Buffer): Promise<string> {
try {
const result = await this.storageClient.upload(fileName, buffer);
return result;
} catch (error) {
this.logger.error(`Storage upload failed: ${error.message}`);
if (error.code === 'NoSuchBucket') {
throw new BadRequestException('Storage bucket not found');
}
if (error.code === 'AccessDenied') {
throw new UnauthorizedException('Storage access denied');
}
if (error.code === 'EntityTooLarge') {
throw new BadRequestException('File too large');
}
throw new InternalServerErrorException('Storage operation failed');
}
}
```
## Storage Configuration Pattern
### Environment Configuration
```typescript
export interface S3Config {
ENABLE: boolean;
ENDPOINT: string;
PORT: number;
USE_SSL: boolean;
ACCESS_KEY: string;
SECRET_KEY: string;
REGION: string;
BUCKET: string;
}
// Usage in service
const s3Config = this.configService.get<S3Config>('S3');
if (!s3Config.ENABLE) {
throw new BadRequestException('S3 storage is disabled');
}
```
## Storage Testing Pattern
### Storage Service Testing
```typescript
describe('S3Service', () => {
let service: S3Service;
let prismaRepository: jest.Mocked<PrismaRepository>;
beforeEach(() => {
service = new S3Service(prismaRepository);
});
describe('getMedia', () => {
it('should return media list', async () => {
const instance = { instanceId: 'test-instance' };
const mockMedia = [
{ id: '1', fileName: 'test.jpg', type: 'image', mimetype: 'image/jpeg' },
];
prismaRepository.media.findMany.mockResolvedValue(mockMedia);
const result = await service.getMedia(instance);
expect(result).toEqual(mockMedia);
expect(prismaRepository.media.findMany).toHaveBeenCalledWith({
where: { instanceId: 'test-instance' },
select: expect.objectContaining({
id: true,
fileName: true,
type: true,
mimetype: true,
}),
});
});
it('should throw error when no media found', async () => {
const instance = { instanceId: 'test-instance' };
prismaRepository.media.findMany.mockResolvedValue([]);
await expect(service.getMedia(instance)).rejects.toThrow(BadRequestException);
});
});
});
```
## Storage Performance Considerations
### Efficient File Handling
```typescript
// CORRECT - Stream-based upload for large files
public async uploadLargeFile(fileName: string, stream: Readable, size: number): Promise<string> {
const uploadStream = new Transform({
transform(chunk, encoding, callback) {
// Optional: Add compression, encryption, etc.
callback(null, chunk);
},
});
return new Promise((resolve, reject) => {
stream
.pipe(uploadStream)
.on('error', reject)
.on('finish', () => resolve(fileName));
});
}
// INCORRECT - Loading entire file into memory
public async uploadLargeFile(fileName: string, filePath: string): Promise<string> {
const buffer = fs.readFileSync(filePath); // ❌ Memory intensive for large files
return await this.uploadFile(fileName, buffer);
}
```

View File

@@ -0,0 +1,416 @@
---
description: Router patterns for Evolution API
globs:
- "src/api/routes/**/*.ts"
alwaysApply: false
---
# Evolution API Route Rules
## Router Base Pattern
### RouterBroker Extension
```typescript
import { RouterBroker } from '@api/abstract/abstract.router';
import { RequestHandler, Router } from 'express';
import { HttpStatus } from './index.router';
export class ExampleRouter extends RouterBroker {
constructor(...guards: RequestHandler[]) {
super();
this.router
.get(this.routerPath('findExample'), ...guards, async (req, res) => {
const response = await this.dataValidate<ExampleDto>({
request: req,
schema: null,
ClassRef: ExampleDto,
execute: (instance) => exampleController.find(instance),
});
return res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('createExample'), ...guards, async (req, res) => {
const response = await this.dataValidate<ExampleDto>({
request: req,
schema: exampleSchema,
ClassRef: ExampleDto,
execute: (instance, data) => exampleController.create(instance, data),
});
return res.status(HttpStatus.CREATED).json(response);
});
}
public readonly router: Router = Router();
}
```
## Main Router Pattern
### Index Router Structure
```typescript
import { Router } from 'express';
import { authGuard } from '@api/guards/auth.guard';
import { instanceExistsGuard, instanceLoggedGuard } from '@api/guards/instance.guard';
import Telemetry from '@api/guards/telemetry.guard';
enum HttpStatus {
OK = 200,
CREATED = 201,
NOT_FOUND = 404,
FORBIDDEN = 403,
BAD_REQUEST = 400,
UNAUTHORIZED = 401,
INTERNAL_SERVER_ERROR = 500,
}
const router: Router = Router();
const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];
const telemetry = new Telemetry();
router
.use((req, res, next) => telemetry.collectTelemetry(req, res, next))
.get('/', async (req, res) => {
res.status(HttpStatus.OK).json({
status: HttpStatus.OK,
message: 'Welcome to the Evolution API, it is working!',
version: packageJson.version,
clientName: process.env.DATABASE_CONNECTION_CLIENT_NAME,
manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined,
documentation: `https://doc.evolution-api.com`,
whatsappWebVersion: (await fetchLatestWaWebVersion({})).version.join('.'),
});
})
.use('/instance', new InstanceRouter(configService, ...guards).router)
.use('/message', new MessageRouter(...guards).router)
.use('/chat', new ChatRouter(...guards).router)
.use('/business', new BusinessRouter(...guards).router);
export { HttpStatus, router };
```
## Data Validation Pattern
### RouterBroker dataValidate Usage
```typescript
// CORRECT - Standard validation pattern
.post(this.routerPath('createTemplate'), ...guards, async (req, res) => {
const response = await this.dataValidate<TemplateDto>({
request: req,
schema: templateSchema,
ClassRef: TemplateDto,
execute: (instance, data) => templateController.create(instance, data),
});
return res.status(HttpStatus.CREATED).json(response);
})
// CORRECT - No schema validation (for simple DTOs)
.get(this.routerPath('findTemplate'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: null,
ClassRef: InstanceDto,
execute: (instance) => templateController.find(instance),
});
return res.status(HttpStatus.OK).json(response);
})
```
## Error Handling in Routes
### Try-Catch Pattern
```typescript
// CORRECT - Error handling with utility function
.post(this.routerPath('getCatalog'), ...guards, async (req, res) => {
try {
const response = await this.dataValidate<NumberDto>({
request: req,
schema: catalogSchema,
ClassRef: NumberDto,
execute: (instance, data) => businessController.fetchCatalog(instance, data),
});
return res.status(HttpStatus.OK).json(response);
} catch (error) {
// Log error for debugging
console.error('Business catalog error:', error);
// Use utility function to create standardized error response
const errorResponse = createMetaErrorResponse(error, 'business_catalog');
return res.status(errorResponse.status).json(errorResponse);
}
})
// INCORRECT - Let RouterBroker handle errors (when possible)
.post(this.routerPath('simpleOperation'), ...guards, async (req, res) => {
try {
const response = await this.dataValidate<SimpleDto>({
request: req,
schema: simpleSchema,
ClassRef: SimpleDto,
execute: (instance, data) => controller.simpleOperation(instance, data),
});
return res.status(HttpStatus.OK).json(response);
} catch (error) {
throw error; // ❌ Unnecessary - RouterBroker handles this
}
})
```
## Route Path Pattern
### routerPath Usage
```typescript
// CORRECT - Use routerPath for consistent naming
.get(this.routerPath('findLabels'), ...guards, async (req, res) => {
// Implementation
})
.post(this.routerPath('handleLabel'), ...guards, async (req, res) => {
// Implementation
})
// INCORRECT - Hardcoded paths
.get('/labels', ...guards, async (req, res) => { // ❌ Use routerPath
// Implementation
})
```
## Guard Application Pattern
### Guards Usage
```typescript
// CORRECT - Apply guards to protected routes
export class ProtectedRouter extends RouterBroker {
constructor(...guards: RequestHandler[]) {
super();
this.router
.get(this.routerPath('protectedAction'), ...guards, async (req, res) => {
// Protected action
})
.post(this.routerPath('anotherAction'), ...guards, async (req, res) => {
// Another protected action
});
}
}
// CORRECT - No guards for public routes
export class PublicRouter extends RouterBroker {
constructor() {
super();
this.router
.get('/health', async (req, res) => {
res.status(HttpStatus.OK).json({ status: 'healthy' });
})
.get('/version', async (req, res) => {
res.status(HttpStatus.OK).json({ version: packageJson.version });
});
}
}
```
## Static File Serving Pattern
### Static Assets Route
```typescript
// CORRECT - Secure static file serving
router.get('/assets/*', (req, res) => {
const fileName = req.params[0];
// Security: Reject paths containing traversal patterns
if (!fileName || fileName.includes('..') || fileName.includes('\\') || path.isAbsolute(fileName)) {
return res.status(403).send('Forbidden');
}
const basePath = path.join(process.cwd(), 'manager', 'dist');
const assetsPath = path.join(basePath, 'assets');
const filePath = path.join(assetsPath, fileName);
// Security: Ensure the resolved path is within the assets directory
const resolvedPath = path.resolve(filePath);
const resolvedAssetsPath = path.resolve(assetsPath);
if (!resolvedPath.startsWith(resolvedAssetsPath + path.sep) && resolvedPath !== resolvedAssetsPath) {
return res.status(403).send('Forbidden');
}
if (fs.existsSync(resolvedPath)) {
res.set('Content-Type', mimeTypes.lookup(resolvedPath) || 'text/css');
res.send(fs.readFileSync(resolvedPath));
} else {
res.status(404).send('File not found');
}
});
```
## Special Route Patterns
### Manager Route Pattern
```typescript
export class ViewsRouter extends RouterBroker {
public readonly router: Router;
constructor() {
super();
this.router = Router();
const basePath = path.join(process.cwd(), 'manager', 'dist');
const indexPath = path.join(basePath, 'index.html');
this.router.use(express.static(basePath));
this.router.get('*', (req, res) => {
res.sendFile(indexPath);
});
}
}
```
### Webhook Route Pattern
```typescript
// CORRECT - Webhook without guards
.post('/webhook/evolution', async (req, res) => {
const response = await evolutionController.receiveWebhook(req.body);
return res.status(HttpStatus.OK).json(response);
})
// CORRECT - Webhook with signature validation
.post('/webhook/meta', validateWebhookSignature, async (req, res) => {
const response = await metaController.receiveWebhook(req.body);
return res.status(HttpStatus.OK).json(response);
})
```
## Response Pattern
### Standard Response Format
```typescript
// CORRECT - Standard success response
return res.status(HttpStatus.OK).json(response);
// CORRECT - Created response
return res.status(HttpStatus.CREATED).json(response);
// CORRECT - Custom response with additional data
return res.status(HttpStatus.OK).json({
...response,
timestamp: new Date().toISOString(),
instanceName: req.params.instanceName,
});
```
## Route Organization
### File Structure
```
src/api/routes/
├── index.router.ts # Main router with all route registrations
├── instance.router.ts # Instance management routes
├── sendMessage.router.ts # Message sending routes
├── chat.router.ts # Chat operations routes
├── business.router.ts # Business API routes
├── group.router.ts # Group management routes
├── label.router.ts # Label management routes
├── proxy.router.ts # Proxy configuration routes
├── settings.router.ts # Instance settings routes
├── template.router.ts # Template management routes
├── call.router.ts # Call operations routes
└── view.router.ts # Frontend views routes
```
## Route Testing Pattern
### Router Testing
```typescript
describe('ExampleRouter', () => {
let app: express.Application;
let router: ExampleRouter;
beforeEach(() => {
app = express();
router = new ExampleRouter();
app.use('/api', router.router);
app.use(express.json());
});
describe('GET /findExample', () => {
it('should return example data', async () => {
const response = await request(app)
.get('/api/findExample/test-instance')
.set('apikey', 'test-key')
.expect(200);
expect(response.body).toBeDefined();
expect(response.body.instanceName).toBe('test-instance');
});
it('should return 401 without API key', async () => {
await request(app)
.get('/api/findExample/test-instance')
.expect(401);
});
});
describe('POST /createExample', () => {
it('should create example successfully', async () => {
const data = {
name: 'Test Example',
description: 'Test Description',
};
const response = await request(app)
.post('/api/createExample/test-instance')
.set('apikey', 'test-key')
.send(data)
.expect(201);
expect(response.body.name).toBe(data.name);
});
it('should validate required fields', async () => {
const data = {
description: 'Test Description',
// Missing required 'name' field
};
await request(app)
.post('/api/createExample/test-instance')
.set('apikey', 'test-key')
.send(data)
.expect(400);
});
});
});
```
## Route Documentation
### JSDoc for Routes
```typescript
/**
* @route GET /api/template/findTemplate/:instanceName
* @description Find template for instance
* @param {string} instanceName - Instance name
* @returns {TemplateDto} Template data
* @throws {404} Template not found
* @throws {401} Unauthorized
*/
.get(this.routerPath('findTemplate'), ...guards, async (req, res) => {
// Implementation
})
/**
* @route POST /api/template/createTemplate/:instanceName
* @description Create new template
* @param {string} instanceName - Instance name
* @body {TemplateDto} Template data
* @returns {TemplateDto} Created template
* @throws {400} Validation error
* @throws {401} Unauthorized
*/
.post(this.routerPath('createTemplate'), ...guards, async (req, res) => {
// Implementation
})
```

View File

@@ -0,0 +1,294 @@
---
description: Service layer patterns for Evolution API
globs:
- "src/api/services/**/*.ts"
- "src/api/integrations/**/services/*.ts"
alwaysApply: false
---
# Evolution API Service Rules
## Service Structure Pattern
### Standard Service Class
```typescript
export class ExampleService {
constructor(private readonly waMonitor: WAMonitoringService) {}
private readonly logger = new Logger('ExampleService');
public async create(instance: InstanceDto, data: ExampleDto) {
await this.waMonitor.waInstances[instance.instanceName].setData(data);
return { example: { ...instance, data } };
}
public async find(instance: InstanceDto): Promise<ExampleDto> {
try {
const result = await this.waMonitor.waInstances[instance.instanceName].findData();
if (Object.keys(result).length === 0) {
throw new Error('Data not found');
}
return result;
} catch (error) {
return null; // Evolution pattern - return null on error
}
}
}
```
## Dependency Injection Pattern
### Constructor Pattern
```typescript
// CORRECT - Evolution API pattern
constructor(
private readonly waMonitor: WAMonitoringService,
private readonly prismaRepository: PrismaRepository,
private readonly configService: ConfigService,
) {}
// INCORRECT - Don't use
constructor(waMonitor, prismaRepository, configService) {} // ❌ No types
```
## Logger Pattern
### Standard Logger Usage
```typescript
// CORRECT - Evolution API pattern
private readonly logger = new Logger('ServiceName');
// Usage
this.logger.log('Operation started');
this.logger.error('Operation failed', error);
// INCORRECT
console.log('Operation started'); // ❌ Use Logger
```
## WAMonitor Integration Pattern
### Instance Access Pattern
```typescript
// CORRECT - Standard pattern
public async operation(instance: InstanceDto, data: DataDto) {
await this.waMonitor.waInstances[instance.instanceName].performAction(data);
return { result: { ...instance, data } };
}
// Instance validation
const waInstance = this.waMonitor.waInstances[instance.instanceName];
if (!waInstance) {
throw new NotFoundException('Instance not found');
}
```
## Error Handling Pattern
### Try-Catch Pattern
```typescript
// CORRECT - Evolution API pattern
public async find(instance: InstanceDto): Promise<DataDto> {
try {
const result = await this.waMonitor.waInstances[instance.instanceName].findData();
if (Object.keys(result).length === 0) {
throw new Error('Data not found');
}
return result;
} catch (error) {
this.logger.error('Find operation failed', error);
return null; // Return null on error (Evolution pattern)
}
}
```
## Cache Integration Pattern
### Cache Service Usage
```typescript
export class CacheAwareService {
constructor(
private readonly cache: CacheService,
private readonly chatwootCache: CacheService,
private readonly baileysCache: CacheService,
) {}
public async getCachedData(key: string): Promise<any> {
const cached = await this.cache.get(key);
if (cached) return cached;
const data = await this.fetchFromSource(key);
await this.cache.set(key, data, 300); // 5 min TTL
return data;
}
}
```
## Integration Service Patterns
### Chatbot Service Base Pattern
```typescript
export class ChatbotService extends BaseChatbotService<BotType, SettingsType> {
constructor(
waMonitor: WAMonitoringService,
prismaRepository: PrismaRepository,
configService: ConfigService,
) {
super(waMonitor, prismaRepository, 'ChatbotService', configService);
}
protected async processBot(
waInstance: any,
remoteJid: string,
bot: BotType,
session: any,
settings: any,
content: string,
): Promise<void> {
// Implementation
}
}
```
### Channel Service Pattern
```typescript
export class ChannelService extends ChannelStartupService {
constructor(
configService: ConfigService,
eventEmitter: EventEmitter2,
prismaRepository: PrismaRepository,
cache: CacheService,
chatwootCache: CacheService,
baileysCache: CacheService,
) {
super(configService, eventEmitter, prismaRepository, cache, chatwootCache, baileysCache);
}
public readonly logger = new Logger('ChannelService');
public client: WASocket;
public readonly instance: wa.Instance = {};
}
```
## Service Initialization Pattern
### Service Registration
```typescript
// In server.module.ts pattern
export const templateService = new TemplateService(
waMonitor,
prismaRepository,
configService,
);
export const settingsService = new SettingsService(waMonitor);
```
## Async Operation Patterns
### Promise Handling
```typescript
// CORRECT - Evolution API pattern
public async sendMessage(instance: InstanceDto, data: MessageDto) {
const waInstance = this.waMonitor.waInstances[instance.instanceName];
return await waInstance.sendMessage(data);
}
// INCORRECT - Don't use .then()
public sendMessage(instance: InstanceDto, data: MessageDto) {
return this.waMonitor.waInstances[instance.instanceName]
.sendMessage(data)
.then(result => result); // ❌ Use async/await
}
```
## Configuration Access Pattern
### Config Service Usage
```typescript
// CORRECT - Evolution API pattern
const serverConfig = this.configService.get<HttpServer>('SERVER');
const authConfig = this.configService.get<Auth>('AUTHENTICATION');
const dbConfig = this.configService.get<Database>('DATABASE');
// Type-safe configuration access
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {
// Chatwoot logic
}
```
## Event Emission Pattern
### EventEmitter2 Usage
```typescript
// CORRECT - Evolution API pattern
this.eventEmitter.emit(Events.INSTANCE_CREATE, {
instanceName: instance.name,
status: 'created',
});
// Chatwoot event pattern
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {
this.chatwootService.eventWhatsapp(
Events.STATUS_INSTANCE,
{ instanceName: this.instance.name },
{
instance: this.instance.name,
status: 'created',
},
);
}
```
## Service Method Naming
### Standard Method Names
- `create()` - Create new resource
- `find()` - Find single resource
- `findAll()` - Find multiple resources
- `update()` - Update resource
- `delete()` - Delete resource
- `fetch*()` - Fetch from external API
- `send*()` - Send data/messages
- `process*()` - Process data
## Service Testing Pattern
### Unit Test Structure
```typescript
describe('ExampleService', () => {
let service: ExampleService;
let waMonitor: jest.Mocked<WAMonitoringService>;
let prismaRepository: jest.Mocked<PrismaRepository>;
beforeEach(() => {
const mockWaMonitor = {
waInstances: {
'test-instance': {
performAction: jest.fn(),
},
},
};
service = new ExampleService(
mockWaMonitor as any,
prismaRepository,
configService,
);
});
it('should perform action successfully', async () => {
const instance = { instanceName: 'test-instance' };
const data = { test: 'data' };
const result = await service.create(instance, data);
expect(result).toBeDefined();
expect(waMonitor.waInstances['test-instance'].performAction).toHaveBeenCalledWith(data);
});
});
```

View File

@@ -0,0 +1,490 @@
---
description: Type definitions and interfaces for Evolution API
globs:
- "src/api/types/**/*.ts"
- "src/@types/**/*.ts"
alwaysApply: false
---
# Evolution API Type Rules
## Namespace Pattern
### WhatsApp Types Namespace
```typescript
/* eslint-disable @typescript-eslint/no-namespace */
import { JsonValue } from '@prisma/client/runtime/library';
import { AuthenticationState, WAConnectionState } from 'baileys';
export declare namespace wa {
export type QrCode = {
count?: number;
pairingCode?: string;
base64?: string;
code?: string;
};
export type Instance = {
id?: string;
qrcode?: QrCode;
pairingCode?: string;
authState?: { state: AuthenticationState; saveCreds: () => void };
name?: string;
wuid?: string;
profileName?: string;
profilePictureUrl?: string;
token?: string;
number?: string;
integration?: string;
businessId?: string;
};
export type LocalChatwoot = {
enabled?: boolean;
accountId?: string;
token?: string;
url?: string;
nameInbox?: string;
mergeBrazilContacts?: boolean;
importContacts?: boolean;
importMessages?: boolean;
daysLimitImportMessages?: number;
organization?: string;
logo?: string;
};
export type LocalProxy = {
enabled?: boolean;
host?: string;
port?: string;
protocol?: string;
username?: string;
password?: string;
};
export type LocalSettings = {
rejectCall?: boolean;
msgCall?: string;
groupsIgnore?: boolean;
alwaysOnline?: boolean;
readMessages?: boolean;
readStatus?: boolean;
syncFullHistory?: boolean;
};
export type LocalWebHook = {
enabled?: boolean;
url?: string;
events?: string[];
headers?: JsonValue;
byEvents?: boolean;
base64?: boolean;
};
export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED';
}
```
## Enum Definitions
### Events Enum
```typescript
export enum Events {
APPLICATION_STARTUP = 'application.startup',
INSTANCE_CREATE = 'instance.create',
INSTANCE_DELETE = 'instance.delete',
QRCODE_UPDATED = 'qrcode.updated',
CONNECTION_UPDATE = 'connection.update',
STATUS_INSTANCE = 'status.instance',
MESSAGES_SET = 'messages.set',
MESSAGES_UPSERT = 'messages.upsert',
MESSAGES_EDITED = 'messages.edited',
MESSAGES_UPDATE = 'messages.update',
MESSAGES_DELETE = 'messages.delete',
SEND_MESSAGE = 'send.message',
SEND_MESSAGE_UPDATE = 'send.message.update',
CONTACTS_SET = 'contacts.set',
CONTACTS_UPSERT = 'contacts.upsert',
CONTACTS_UPDATE = 'contacts.update',
PRESENCE_UPDATE = 'presence.update',
CHATS_SET = 'chats.set',
CHATS_UPDATE = 'chats.update',
CHATS_UPSERT = 'chats.upsert',
CHATS_DELETE = 'chats.delete',
GROUPS_UPSERT = 'groups.upsert',
GROUPS_UPDATE = 'groups.update',
GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',
CALL = 'call',
TYPEBOT_START = 'typebot.start',
TYPEBOT_CHANGE_STATUS = 'typebot.change-status',
LABELS_EDIT = 'labels.edit',
LABELS_ASSOCIATION = 'labels.association',
CREDS_UPDATE = 'creds.update',
MESSAGING_HISTORY_SET = 'messaging-history.set',
REMOVE_INSTANCE = 'remove.instance',
LOGOUT_INSTANCE = 'logout.instance',
}
```
### Integration Types
```typescript
export const Integration = {
WHATSAPP_BUSINESS: 'WHATSAPP-BUSINESS',
WHATSAPP_BAILEYS: 'WHATSAPP-BAILEYS',
EVOLUTION: 'EVOLUTION',
} as const;
export type IntegrationType = typeof Integration[keyof typeof Integration];
```
## Constant Arrays
### Message Type Constants
```typescript
export const TypeMediaMessage = [
'imageMessage',
'documentMessage',
'audioMessage',
'videoMessage',
'stickerMessage',
'ptvMessage', // Evolution API includes this
];
export const MessageSubtype = [
'ephemeralMessage',
'documentWithCaptionMessage',
'viewOnceMessage',
'viewOnceMessageV2',
];
export type MediaMessageType = typeof TypeMediaMessage[number];
export type MessageSubtypeType = typeof MessageSubtype[number];
```
## Interface Definitions
### Service Interfaces
```typescript
export interface ServiceInterface {
create(instance: InstanceDto, data: any): Promise<any>;
find(instance: InstanceDto): Promise<any>;
update?(instance: InstanceDto, data: any): Promise<any>;
delete?(instance: InstanceDto): Promise<any>;
}
export interface ChannelServiceInterface extends ServiceInterface {
sendMessage(data: SendMessageDto): Promise<any>;
connectToWhatsapp(data?: any): Promise<void>;
receiveWebhook?(data: any): Promise<void>;
}
export interface ChatbotServiceInterface extends ServiceInterface {
processMessage(
instanceName: string,
remoteJid: string,
message: any,
pushName?: string,
): Promise<void>;
}
```
## Configuration Types
### Environment Configuration Types
```typescript
export interface DatabaseConfig {
CONNECTION: {
URI: string;
DB_PREFIX_NAME: string;
CLIENT_NAME?: string;
};
ENABLED: boolean;
SAVE_DATA: {
INSTANCE: boolean;
NEW_MESSAGE: boolean;
MESSAGE_UPDATE: boolean;
CONTACTS: boolean;
CHATS: boolean;
};
}
export interface AuthConfig {
TYPE: 'apikey' | 'jwt';
API_KEY: {
KEY: string;
};
JWT?: {
EXPIRIN_IN: number;
SECRET: string;
};
}
export interface CacheConfig {
REDIS: {
ENABLED: boolean;
URI: string;
PREFIX_KEY: string;
SAVE_INSTANCES: boolean;
};
LOCAL: {
ENABLED: boolean;
TTL: number;
};
}
```
## Message Types
### Message Structure Types
```typescript
export interface MessageContent {
text?: string;
caption?: string;
media?: Buffer | string;
mediatype?: 'image' | 'video' | 'audio' | 'document' | 'sticker';
fileName?: string;
mimetype?: string;
}
export interface MessageOptions {
delay?: number;
presence?: 'unavailable' | 'available' | 'composing' | 'recording' | 'paused';
linkPreview?: boolean;
mentionsEveryOne?: boolean;
mentioned?: string[];
quoted?: {
key: {
remoteJid: string;
fromMe: boolean;
id: string;
};
message: any;
};
}
export interface SendMessageRequest {
number: string;
content: MessageContent;
options?: MessageOptions;
}
```
## Webhook Types
### Webhook Payload Types
```typescript
export interface WebhookPayload {
event: Events;
instance: string;
data: any;
timestamp: string;
server?: {
version: string;
host: string;
};
}
export interface WebhookConfig {
enabled: boolean;
url: string;
events: Events[];
headers?: Record<string, string>;
byEvents?: boolean;
base64?: boolean;
}
```
## Error Types
### Custom Error Types
```typescript
export interface ApiError {
status: number;
message: string;
error?: string;
details?: any;
timestamp: string;
path: string;
}
export interface ValidationError extends ApiError {
status: 400;
validationErrors: Array<{
field: string;
message: string;
value?: any;
}>;
}
export interface AuthenticationError extends ApiError {
status: 401;
message: 'Unauthorized' | 'Invalid API Key' | 'Token Expired';
}
```
## Utility Types
### Generic Utility Types
```typescript
export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
export type RequiredFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
export type NonEmptyArray<T> = [T, ...T[]];
export type StringKeys<T> = {
[K in keyof T]: T[K] extends string ? K : never;
}[keyof T];
```
## Response Types
### API Response Types
```typescript
export interface ApiResponse<T = any> {
success: boolean;
data?: T;
message?: string;
error?: string;
timestamp: string;
}
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
pagination: {
page: number;
limit: number;
total: number;
totalPages: number;
hasNext: boolean;
hasPrev: boolean;
};
}
export interface InstanceResponse extends ApiResponse {
instance: {
instanceName: string;
status: 'connecting' | 'open' | 'close' | 'qr';
qrcode?: string;
profileName?: string;
profilePicUrl?: string;
};
}
```
## Integration-Specific Types
### Baileys Types Extension
```typescript
import { WASocket, ConnectionState, DisconnectReason } from 'baileys';
export interface BaileysInstance {
client: WASocket;
state: ConnectionState;
qrRetry: number;
authPath: string;
}
export interface BaileysConfig {
qrTimeout: number;
maxQrRetries: number;
authTimeout: number;
reconnectInterval: number;
}
```
### Business API Types
```typescript
export interface BusinessApiConfig {
version: string;
baseUrl: string;
timeout: number;
retries: number;
}
export interface BusinessApiMessage {
messaging_product: 'whatsapp';
to: string;
type: 'text' | 'image' | 'document' | 'audio' | 'video' | 'template';
text?: {
body: string;
preview_url?: boolean;
};
image?: {
link?: string;
id?: string;
caption?: string;
};
template?: {
name: string;
language: {
code: string;
};
components?: any[];
};
}
```
## Type Guards
### Type Guard Functions
```typescript
export function isMediaMessage(message: any): message is MediaMessage {
return message && TypeMediaMessage.some(type => message[type]);
}
export function isTextMessage(message: any): message is TextMessage {
return message && message.conversation;
}
export function isValidIntegration(integration: string): integration is IntegrationType {
return Object.values(Integration).includes(integration as IntegrationType);
}
export function isValidEvent(event: string): event is Events {
return Object.values(Events).includes(event as Events);
}
```
## Module Augmentation
### Express Request Extension
```typescript
declare global {
namespace Express {
interface Request {
instanceName?: string;
instanceData?: InstanceDto;
user?: {
id: string;
apiKey: string;
};
}
}
}
```
## Type Documentation
### JSDoc Type Documentation
```typescript
/**
* WhatsApp instance configuration
* @interface InstanceConfig
* @property {string} name - Unique instance name
* @property {IntegrationType} integration - Integration type
* @property {string} [token] - API token for business integrations
* @property {WebhookConfig} [webhook] - Webhook configuration
* @property {ProxyConfig} [proxy] - Proxy configuration
*/
export interface InstanceConfig {
name: string;
integration: IntegrationType;
token?: string;
webhook?: WebhookConfig;
proxy?: ProxyConfig;
}
```

View File

@@ -0,0 +1,653 @@
---
description: Utility functions and helpers for Evolution API
globs:
- "src/utils/**/*.ts"
alwaysApply: false
---
# Evolution API Utility Rules
## Utility Function Structure
### Standard Utility Pattern
```typescript
import { Logger } from '@config/logger.config';
const logger = new Logger('UtilityName');
export function utilityFunction(param: ParamType): ReturnType {
try {
// Utility logic
return result;
} catch (error) {
logger.error(`Utility function failed: ${error.message}`);
throw error;
}
}
export default utilityFunction;
```
## Authentication Utilities
### Multi-File Auth State Pattern
```typescript
import { AuthenticationState } from 'baileys';
import { CacheService } from '@api/services/cache.service';
import fs from 'fs/promises';
import path from 'path';
export default async function useMultiFileAuthStatePrisma(
sessionId: string,
cache: CacheService,
): Promise<{
state: AuthenticationState;
saveCreds: () => Promise<void>;
}> {
const localFolder = path.join(INSTANCE_DIR, sessionId);
const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json');
await fs.mkdir(localFolder, { recursive: true });
async function writeData(data: any, key: string): Promise<any> {
const dataString = JSON.stringify(data, BufferJSON.replacer);
if (key !== 'creds') {
if (process.env.CACHE_REDIS_ENABLED === 'true') {
return await cache.hSet(sessionId, key, data);
} else {
await fs.writeFile(localFile(key), dataString);
return;
}
}
await saveKey(sessionId, dataString);
return;
}
async function readData(key: string): Promise<any> {
try {
let rawData;
if (key !== 'creds') {
if (process.env.CACHE_REDIS_ENABLED === 'true') {
return await cache.hGet(sessionId, key);
} else {
if (!(await fileExists(localFile(key)))) return null;
rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' });
return JSON.parse(rawData, BufferJSON.reviver);
}
} else {
rawData = await getAuthKey(sessionId);
}
const parsedData = JSON.parse(rawData, BufferJSON.reviver);
return parsedData;
} catch (error) {
return null;
}
}
async function removeData(key: string): Promise<any> {
try {
if (key !== 'creds') {
if (process.env.CACHE_REDIS_ENABLED === 'true') {
return await cache.hDelete(sessionId, key);
} else {
await fs.unlink(localFile(key));
}
} else {
await deleteAuthKey(sessionId);
}
} catch (error) {
return;
}
}
let creds = await readData('creds');
if (!creds) {
creds = initAuthCreds();
await writeData(creds, 'creds');
}
return {
state: {
creds,
keys: {
get: async (type, ids) => {
const data = {};
await Promise.all(
ids.map(async (id) => {
let value = await readData(`${type}-${id}`);
if (type === 'app-state-sync-key' && value) {
value = proto.Message.AppStateSyncKeyData.fromObject(value);
}
data[id] = value;
})
);
return data;
},
set: async (data) => {
const tasks = [];
for (const category in data) {
for (const id in data[category]) {
const value = data[category][id];
const key = `${category}-${id}`;
tasks.push(value ? writeData(value, key) : removeData(key));
}
}
await Promise.all(tasks);
},
},
},
saveCreds: () => writeData(creds, 'creds'),
};
}
```
## Message Processing Utilities
### Message Content Extraction
```typescript
export const getConversationMessage = (msg: any): string => {
const types = getTypeMessage(msg);
const messageContent = getMessageContent(types);
return messageContent;
};
const getTypeMessage = (msg: any): any => {
return Object.keys(msg?.message || msg || {})[0];
};
const getMessageContent = (type: string, msg?: any): string => {
const typeKey = type?.replace('Message', '');
const types = {
conversation: msg?.message?.conversation,
extendedTextMessage: msg?.message?.extendedTextMessage?.text,
imageMessage: msg?.message?.imageMessage?.caption || 'Image',
videoMessage: msg?.message?.videoMessage?.caption || 'Video',
audioMessage: 'Audio',
documentMessage: msg?.message?.documentMessage?.caption || 'Document',
stickerMessage: 'Sticker',
contactMessage: 'Contact',
locationMessage: 'Location',
liveLocationMessage: 'Live Location',
viewOnceMessage: 'View Once',
reactionMessage: 'Reaction',
pollCreationMessage: 'Poll',
pollUpdateMessage: 'Poll Update',
};
let result = types[typeKey] || types[type] || 'Unknown';
if (!result || result === 'Unknown') {
result = JSON.stringify(msg);
}
return result;
};
```
### JID Creation Utility
```typescript
export const createJid = (number: string): string => {
if (number.includes('@')) {
return number;
}
// Remove any non-numeric characters except +
let cleanNumber = number.replace(/[^\d+]/g, '');
// Remove + if present
if (cleanNumber.startsWith('+')) {
cleanNumber = cleanNumber.substring(1);
}
// Add country code if missing (assuming Brazil as default)
if (cleanNumber.length === 11 && cleanNumber.startsWith('11')) {
cleanNumber = '55' + cleanNumber;
} else if (cleanNumber.length === 10) {
cleanNumber = '5511' + cleanNumber;
}
// Determine if it's a group or individual
const isGroup = cleanNumber.includes('-');
const domain = isGroup ? 'g.us' : 's.whatsapp.net';
return `${cleanNumber}@${domain}`;
};
```
## Cache Utilities
### WhatsApp Number Cache
```typescript
interface ISaveOnWhatsappCacheParams {
remoteJid: string;
lid?: string;
}
function getAvailableNumbers(remoteJid: string): string[] {
const numbersAvailable: string[] = [];
if (remoteJid.startsWith('+')) {
remoteJid = remoteJid.slice(1);
}
const [number, domain] = remoteJid.split('@');
// Brazilian numbers
if (remoteJid.startsWith('55')) {
const numberWithDigit =
number.slice(4, 5) === '9' && number.length === 13 ? number : `${number.slice(0, 4)}9${number.slice(4)}`;
const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 4) + number.slice(5);
numbersAvailable.push(numberWithDigit);
numbersAvailable.push(numberWithoutDigit);
}
// Mexican/Argentina numbers
else if (number.startsWith('52') || number.startsWith('54')) {
let prefix = '';
if (number.startsWith('52')) {
prefix = '1';
}
if (number.startsWith('54')) {
prefix = '9';
}
const numberWithDigit =
number.slice(2, 3) === prefix && number.length === 13
? number
: `${number.slice(0, 2)}${prefix}${number.slice(2)}`;
const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 2) + number.slice(3);
numbersAvailable.push(numberWithDigit);
numbersAvailable.push(numberWithoutDigit);
}
// Other countries
else {
numbersAvailable.push(remoteJid);
}
return numbersAvailable.map((number) => `${number}@${domain}`);
}
export async function saveOnWhatsappCache(params: ISaveOnWhatsappCacheParams): Promise<void> {
const { remoteJid, lid } = params;
const db = configService.get<Database>('DATABASE');
if (!db.SAVE_DATA.CONTACTS) {
return;
}
try {
const numbersAvailable = getAvailableNumbers(remoteJid);
const existingContact = await prismaRepository.contact.findFirst({
where: {
OR: numbersAvailable.map(number => ({ id: number })),
},
});
if (!existingContact) {
await prismaRepository.contact.create({
data: {
id: remoteJid,
pushName: '',
profilePicUrl: '',
isOnWhatsapp: true,
lid: lid || null,
createdAt: new Date(),
updatedAt: new Date(),
},
});
} else {
await prismaRepository.contact.update({
where: { id: existingContact.id },
data: {
isOnWhatsapp: true,
lid: lid || existingContact.lid,
updatedAt: new Date(),
},
});
}
} catch (error) {
console.error('Error saving WhatsApp cache:', error);
}
}
```
## Search Utilities
### Advanced Search Operators
```typescript
function normalizeString(str: string): string {
return str
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
}
export function advancedOperatorsSearch(data: string, query: string): boolean {
const normalizedData = normalizeString(data);
const normalizedQuery = normalizeString(query);
// Exact phrase search with quotes
if (normalizedQuery.startsWith('"') && normalizedQuery.endsWith('"')) {
const phrase = normalizedQuery.slice(1, -1);
return normalizedData.includes(phrase);
}
// OR operator
if (normalizedQuery.includes(' OR ')) {
const terms = normalizedQuery.split(' OR ');
return terms.some(term => normalizedData.includes(term.trim()));
}
// AND operator (default behavior)
if (normalizedQuery.includes(' AND ')) {
const terms = normalizedQuery.split(' AND ');
return terms.every(term => normalizedData.includes(term.trim()));
}
// NOT operator
if (normalizedQuery.startsWith('NOT ')) {
const term = normalizedQuery.slice(4);
return !normalizedData.includes(term);
}
// Wildcard search
if (normalizedQuery.includes('*')) {
const regex = new RegExp(normalizedQuery.replace(/\*/g, '.*'), 'i');
return regex.test(normalizedData);
}
// Default: simple contains search
return normalizedData.includes(normalizedQuery);
}
```
## Proxy Utilities
### Proxy Agent Creation
```typescript
import { HttpsProxyAgent } from 'https-proxy-agent';
import { SocksProxyAgent } from 'socks-proxy-agent';
type Proxy = {
host: string;
port: string;
protocol: 'http' | 'https' | 'socks4' | 'socks5';
username?: string;
password?: string;
};
function selectProxyAgent(proxyUrl: string): HttpsProxyAgent<string> | SocksProxyAgent {
const url = new URL(proxyUrl);
if (url.protocol === 'socks4:' || url.protocol === 'socks5:') {
return new SocksProxyAgent(proxyUrl);
} else {
return new HttpsProxyAgent(proxyUrl);
}
}
export function makeProxyAgent(proxy: Proxy): HttpsProxyAgent<string> | SocksProxyAgent | null {
if (!proxy.host || !proxy.port) {
return null;
}
let proxyUrl = `${proxy.protocol}://`;
if (proxy.username && proxy.password) {
proxyUrl += `${proxy.username}:${proxy.password}@`;
}
proxyUrl += `${proxy.host}:${proxy.port}`;
try {
return selectProxyAgent(proxyUrl);
} catch (error) {
console.error('Failed to create proxy agent:', error);
return null;
}
}
```
## Telemetry Utilities
### Telemetry Data Collection
```typescript
export interface TelemetryData {
route: string;
apiVersion: string;
timestamp: Date;
method?: string;
statusCode?: number;
responseTime?: number;
userAgent?: string;
instanceName?: string;
}
export const sendTelemetry = async (route: string): Promise<void> => {
try {
const telemetryData: TelemetryData = {
route,
apiVersion: packageJson.version,
timestamp: new Date(),
};
// Only send telemetry if enabled
if (process.env.DISABLE_TELEMETRY === 'true') {
return;
}
// Send to telemetry service (implement as needed)
await axios.post('https://telemetry.evolution-api.com/collect', telemetryData, {
timeout: 5000,
});
} catch (error) {
// Silently fail - don't affect main application
console.debug('Telemetry failed:', error.message);
}
};
```
## Internationalization Utilities
### i18n Setup
```typescript
import { ConfigService, Language } from '@config/env.config';
import fs from 'fs';
import i18next from 'i18next';
import path from 'path';
const __dirname = path.resolve(process.cwd(), 'src', 'utils');
const languages = ['en', 'pt-BR', 'es'];
const translationsPath = path.join(__dirname, 'translations');
const configService: ConfigService = new ConfigService();
const resources: any = {};
languages.forEach((language) => {
const languagePath = path.join(translationsPath, `${language}.json`);
if (fs.existsSync(languagePath)) {
const translationContent = fs.readFileSync(languagePath, 'utf8');
resources[language] = {
translation: JSON.parse(translationContent),
};
}
});
i18next.init({
resources,
fallbackLng: 'en',
lng: configService.get<Language>('LANGUAGE') || 'pt-BR',
interpolation: {
escapeValue: false,
},
});
export const t = i18next.t.bind(i18next);
export default i18next;
```
## Bot Trigger Utilities
### Bot Trigger Matching
```typescript
import { TriggerOperator, TriggerType } from '@prisma/client';
export function findBotByTrigger(
bots: any[],
content: string,
remoteJid: string,
): any | null {
for (const bot of bots) {
if (!bot.enabled) continue;
// Check ignore list
if (bot.ignoreJids && bot.ignoreJids.includes(remoteJid)) {
continue;
}
// Check trigger
if (matchesTrigger(content, bot.triggerType, bot.triggerOperator, bot.triggerValue)) {
return bot;
}
}
return null;
}
function matchesTrigger(
content: string,
triggerType: TriggerType,
triggerOperator: TriggerOperator,
triggerValue: string,
): boolean {
const normalizedContent = content.toLowerCase().trim();
const normalizedValue = triggerValue.toLowerCase().trim();
switch (triggerType) {
case TriggerType.ALL:
return true;
case TriggerType.KEYWORD:
return matchesKeyword(normalizedContent, triggerOperator, normalizedValue);
case TriggerType.REGEX:
try {
const regex = new RegExp(triggerValue, 'i');
return regex.test(content);
} catch {
return false;
}
default:
return false;
}
}
function matchesKeyword(
content: string,
operator: TriggerOperator,
value: string,
): boolean {
switch (operator) {
case TriggerOperator.EQUALS:
return content === value;
case TriggerOperator.CONTAINS:
return content.includes(value);
case TriggerOperator.STARTS_WITH:
return content.startsWith(value);
case TriggerOperator.ENDS_WITH:
return content.endsWith(value);
default:
return false;
}
}
```
## Server Utilities
### Server Status Check
```typescript
export class ServerUP {
private static instance: ServerUP;
private isServerUp: boolean = false;
private constructor() {}
public static getInstance(): ServerUP {
if (!ServerUP.instance) {
ServerUP.instance = new ServerUP();
}
return ServerUP.instance;
}
public setServerStatus(status: boolean): void {
this.isServerUp = status;
}
public getServerStatus(): boolean {
return this.isServerUp;
}
public async waitForServer(timeout: number = 30000): Promise<boolean> {
const startTime = Date.now();
while (!this.isServerUp && (Date.now() - startTime) < timeout) {
await new Promise(resolve => setTimeout(resolve, 100));
}
return this.isServerUp;
}
}
```
## Error Response Utilities
### Standardized Error Responses
```typescript
export function createMetaErrorResponse(error: any, context: string) {
const timestamp = new Date().toISOString();
if (error.response?.data) {
return {
status: error.response.status || 500,
error: {
message: error.response.data.error?.message || 'External API error',
type: error.response.data.error?.type || 'api_error',
code: error.response.data.error?.code || 'unknown_error',
context,
timestamp,
},
};
}
return {
status: 500,
error: {
message: error.message || 'Internal server error',
type: 'internal_error',
code: 'server_error',
context,
timestamp,
},
};
}
export function createValidationErrorResponse(errors: any[], context: string) {
return {
status: 400,
error: {
message: 'Validation failed',
type: 'validation_error',
code: 'invalid_input',
context,
details: errors,
timestamp: new Date().toISOString(),
},
};
}
```

View File

@@ -0,0 +1,498 @@
---
description: Validation schemas and patterns for Evolution API
globs:
- "src/validate/**/*.ts"
alwaysApply: false
---
# Evolution API Validation Rules
## Validation Schema Structure
### JSONSchema7 Pattern (Evolution API Standard)
```typescript
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...fields: string[]) => {
const properties = {};
fields.forEach((field) => {
properties[field] = {
if: { properties: { [field]: { type: 'string' } } },
then: { properties: { [field]: { minLength: 1 } } },
};
});
return {
allOf: Object.values(properties),
};
};
export const exampleSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
name: { type: 'string' },
description: { type: 'string' },
enabled: { type: 'boolean' },
settings: {
type: 'object',
properties: {
timeout: { type: 'number', minimum: 1000, maximum: 60000 },
retries: { type: 'number', minimum: 0, maximum: 5 },
},
},
tags: {
type: 'array',
items: { type: 'string' },
},
},
required: ['name', 'enabled'],
...isNotEmpty('name'),
};
```
## Message Validation Schemas
### Send Message Validation
```typescript
const numberDefinition = {
type: 'string',
pattern: '^\\d+[\\.@\\w-]+',
description: 'Invalid number',
};
export const sendTextSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
number: numberDefinition,
text: { type: 'string', minLength: 1, maxLength: 4096 },
delay: { type: 'number', minimum: 0, maximum: 60000 },
linkPreview: { type: 'boolean' },
mentionsEveryOne: { type: 'boolean' },
mentioned: {
type: 'array',
items: { type: 'string' },
},
},
required: ['number', 'text'],
...isNotEmpty('number', 'text'),
};
export const sendMediaSchema = Joi.object({
number: Joi.string().required().pattern(/^\d+$/),
mediatype: Joi.string().required().valid('image', 'video', 'audio', 'document'),
media: Joi.alternatives().try(
Joi.string().uri(),
Joi.string().base64(),
).required(),
caption: Joi.string().optional().max(1024),
fileName: Joi.string().optional().max(255),
delay: Joi.number().optional().min(0).max(60000),
}).required();
export const sendButtonsSchema = Joi.object({
number: Joi.string().required().pattern(/^\d+$/),
title: Joi.string().required().max(1024),
description: Joi.string().optional().max(1024),
footer: Joi.string().optional().max(60),
buttons: Joi.array().items(
Joi.object({
type: Joi.string().required().valid('replyButton', 'urlButton', 'callButton'),
displayText: Joi.string().required().max(20),
id: Joi.string().when('type', {
is: 'replyButton',
then: Joi.required().max(256),
otherwise: Joi.optional(),
}),
url: Joi.string().when('type', {
is: 'urlButton',
then: Joi.required().uri(),
otherwise: Joi.optional(),
}),
phoneNumber: Joi.string().when('type', {
is: 'callButton',
then: Joi.required().pattern(/^\+?\d+$/),
otherwise: Joi.optional(),
}),
})
).min(1).max(3).required(),
}).required();
```
## Instance Validation Schemas
### Instance Creation Validation
```typescript
export const instanceSchema = Joi.object({
instanceName: Joi.string().required().min(1).max(100).pattern(/^[a-zA-Z0-9_-]+$/),
integration: Joi.string().required().valid('WHATSAPP-BAILEYS', 'WHATSAPP-BUSINESS', 'EVOLUTION'),
token: Joi.string().when('integration', {
is: Joi.valid('WHATSAPP-BUSINESS', 'EVOLUTION'),
then: Joi.required().min(10),
otherwise: Joi.optional(),
}),
qrcode: Joi.boolean().optional().default(false),
number: Joi.string().optional().pattern(/^\d+$/),
businessId: Joi.string().when('integration', {
is: 'WHATSAPP-BUSINESS',
then: Joi.required(),
otherwise: Joi.optional(),
}),
}).required();
export const settingsSchema = Joi.object({
rejectCall: Joi.boolean().optional(),
msgCall: Joi.string().optional().max(500),
groupsIgnore: Joi.boolean().optional(),
alwaysOnline: Joi.boolean().optional(),
readMessages: Joi.boolean().optional(),
readStatus: Joi.boolean().optional(),
syncFullHistory: Joi.boolean().optional(),
wavoipToken: Joi.string().optional(),
}).optional();
export const proxySchema = Joi.object({
host: Joi.string().required().hostname(),
port: Joi.string().required().pattern(/^\d+$/).custom((value) => {
const port = parseInt(value);
if (port < 1 || port > 65535) {
throw new Error('Port must be between 1 and 65535');
}
return value;
}),
protocol: Joi.string().required().valid('http', 'https', 'socks4', 'socks5'),
username: Joi.string().optional(),
password: Joi.string().optional(),
}).optional();
```
## Webhook Validation Schemas
### Webhook Configuration Validation
```typescript
export const webhookSchema = Joi.object({
enabled: Joi.boolean().required(),
url: Joi.string().when('enabled', {
is: true,
then: Joi.required().uri({ scheme: ['http', 'https'] }),
otherwise: Joi.optional(),
}),
events: Joi.array().items(
Joi.string().valid(
'APPLICATION_STARTUP',
'INSTANCE_CREATE',
'INSTANCE_DELETE',
'QRCODE_UPDATED',
'CONNECTION_UPDATE',
'STATUS_INSTANCE',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'CHATS_SET',
'CHATS_UPDATE',
'CHATS_UPSERT',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUPS_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CALL'
)
).min(1).when('enabled', {
is: true,
then: Joi.required(),
otherwise: Joi.optional(),
}),
headers: Joi.object().pattern(
Joi.string(),
Joi.string()
).optional(),
byEvents: Joi.boolean().optional().default(false),
base64: Joi.boolean().optional().default(false),
}).required();
```
## Chatbot Validation Schemas
### Base Chatbot Validation
```typescript
export const baseChatbotSchema = Joi.object({
enabled: Joi.boolean().required(),
description: Joi.string().required().min(1).max(500),
expire: Joi.number().optional().min(0).max(86400), // 24 hours in seconds
keywordFinish: Joi.string().optional().max(100),
delayMessage: Joi.number().optional().min(0).max(10000),
unknownMessage: Joi.string().optional().max(1000),
listeningFromMe: Joi.boolean().optional().default(false),
stopBotFromMe: Joi.boolean().optional().default(false),
keepOpen: Joi.boolean().optional().default(false),
debounceTime: Joi.number().optional().min(0).max(60000),
triggerType: Joi.string().required().valid('ALL', 'KEYWORD', 'REGEX'),
triggerOperator: Joi.string().when('triggerType', {
is: 'KEYWORD',
then: Joi.required().valid('EQUALS', 'CONTAINS', 'STARTS_WITH', 'ENDS_WITH'),
otherwise: Joi.optional(),
}),
triggerValue: Joi.string().when('triggerType', {
is: Joi.valid('KEYWORD', 'REGEX'),
then: Joi.required().min(1).max(500),
otherwise: Joi.optional(),
}),
ignoreJids: Joi.array().items(Joi.string()).optional(),
splitMessages: Joi.boolean().optional().default(false),
timePerChar: Joi.number().optional().min(10).max(1000).default(100),
}).required();
export const typebotSchema = baseChatbotSchema.keys({
url: Joi.string().required().uri({ scheme: ['http', 'https'] }),
typebot: Joi.string().required().min(1).max(100),
apiVersion: Joi.string().optional().valid('v1', 'v2').default('v1'),
}).required();
export const openaiSchema = baseChatbotSchema.keys({
apiKey: Joi.string().required().min(10),
model: Joi.string().optional().valid(
'gpt-3.5-turbo',
'gpt-3.5-turbo-16k',
'gpt-4',
'gpt-4-32k',
'gpt-4-turbo-preview'
).default('gpt-3.5-turbo'),
systemMessage: Joi.string().optional().max(2000),
maxTokens: Joi.number().optional().min(1).max(4000).default(1000),
temperature: Joi.number().optional().min(0).max(2).default(0.7),
}).required();
```
## Business API Validation Schemas
### Template Validation
```typescript
export const templateSchema = Joi.object({
name: Joi.string().required().min(1).max(512).pattern(/^[a-z0-9_]+$/),
category: Joi.string().required().valid('MARKETING', 'UTILITY', 'AUTHENTICATION'),
allowCategoryChange: Joi.boolean().required(),
language: Joi.string().required().pattern(/^[a-z]{2}_[A-Z]{2}$/), // e.g., pt_BR, en_US
components: Joi.array().items(
Joi.object({
type: Joi.string().required().valid('HEADER', 'BODY', 'FOOTER', 'BUTTONS'),
format: Joi.string().when('type', {
is: 'HEADER',
then: Joi.valid('TEXT', 'IMAGE', 'VIDEO', 'DOCUMENT'),
otherwise: Joi.optional(),
}),
text: Joi.string().when('type', {
is: Joi.valid('HEADER', 'BODY', 'FOOTER'),
then: Joi.required().min(1).max(1024),
otherwise: Joi.optional(),
}),
buttons: Joi.array().when('type', {
is: 'BUTTONS',
then: Joi.items(
Joi.object({
type: Joi.string().required().valid('QUICK_REPLY', 'URL', 'PHONE_NUMBER'),
text: Joi.string().required().min(1).max(25),
url: Joi.string().when('type', {
is: 'URL',
then: Joi.required().uri(),
otherwise: Joi.optional(),
}),
phone_number: Joi.string().when('type', {
is: 'PHONE_NUMBER',
then: Joi.required().pattern(/^\+?\d+$/),
otherwise: Joi.optional(),
}),
})
).min(1).max(10),
otherwise: Joi.optional(),
}),
})
).min(1).required(),
webhookUrl: Joi.string().optional().uri({ scheme: ['http', 'https'] }),
}).required();
export const catalogSchema = Joi.object({
number: Joi.string().optional().pattern(/^\d+$/),
limit: Joi.number().optional().min(1).max(1000).default(10),
cursor: Joi.string().optional(),
}).optional();
```
## Group Validation Schemas
### Group Management Validation
```typescript
export const createGroupSchema = Joi.object({
subject: Joi.string().required().min(1).max(100),
description: Joi.string().optional().max(500),
participants: Joi.array().items(
Joi.string().pattern(/^\d+$/)
).min(1).max(256).required(),
promoteParticipants: Joi.boolean().optional().default(false),
}).required();
export const updateGroupSchema = Joi.object({
subject: Joi.string().optional().min(1).max(100),
description: Joi.string().optional().max(500),
}).min(1).required();
export const groupParticipantsSchema = Joi.object({
participants: Joi.array().items(
Joi.string().pattern(/^\d+$/)
).min(1).max(50).required(),
action: Joi.string().required().valid('add', 'remove', 'promote', 'demote'),
}).required();
```
## Label Validation Schemas
### Label Management Validation
```typescript
export const labelSchema = Joi.object({
name: Joi.string().required().min(1).max(100),
color: Joi.string().required().pattern(/^#[0-9A-Fa-f]{6}$/), // Hex color
predefinedId: Joi.string().optional(),
}).required();
export const handleLabelSchema = Joi.object({
number: Joi.string().required().pattern(/^\d+$/),
labelId: Joi.string().required(),
action: Joi.string().required().valid('add', 'remove'),
}).required();
```
## Custom Validation Functions
### Phone Number Validation
```typescript
export function validatePhoneNumber(number: string): boolean {
// Remove any non-digit characters
const cleaned = number.replace(/\D/g, '');
// Check minimum and maximum length
if (cleaned.length < 10 || cleaned.length > 15) {
return false;
}
// Check for valid country codes (basic validation)
const validCountryCodes = ['1', '7', '20', '27', '30', '31', '32', '33', '34', '36', '39', '40', '41', '43', '44', '45', '46', '47', '48', '49', '51', '52', '53', '54', '55', '56', '57', '58', '60', '61', '62', '63', '64', '65', '66', '81', '82', '84', '86', '90', '91', '92', '93', '94', '95', '98'];
// Check if starts with valid country code
const startsWithValidCode = validCountryCodes.some(code => cleaned.startsWith(code));
return startsWithValidCode;
}
export const phoneNumberValidator = Joi.string().custom((value, helpers) => {
if (!validatePhoneNumber(value)) {
return helpers.error('any.invalid');
}
return value;
}, 'Phone number validation');
```
### Base64 Validation
```typescript
export function validateBase64(base64: string): boolean {
try {
// Check if it's a valid base64 string
const decoded = Buffer.from(base64, 'base64').toString('base64');
return decoded === base64;
} catch {
return false;
}
}
export const base64Validator = Joi.string().custom((value, helpers) => {
if (!validateBase64(value)) {
return helpers.error('any.invalid');
}
return value;
}, 'Base64 validation');
```
### URL Validation with Protocol Check
```typescript
export function validateWebhookUrl(url: string): boolean {
try {
const parsed = new URL(url);
return ['http:', 'https:'].includes(parsed.protocol);
} catch {
return false;
}
}
export const webhookUrlValidator = Joi.string().custom((value, helpers) => {
if (!validateWebhookUrl(value)) {
return helpers.error('any.invalid');
}
return value;
}, 'Webhook URL validation');
```
## Validation Error Handling
### Error Message Customization
```typescript
export const validationMessages = {
'any.required': 'O campo {#label} é obrigatório',
'string.empty': 'O campo {#label} não pode estar vazio',
'string.min': 'O campo {#label} deve ter pelo menos {#limit} caracteres',
'string.max': 'O campo {#label} deve ter no máximo {#limit} caracteres',
'string.pattern.base': 'O campo {#label} possui formato inválido',
'number.min': 'O campo {#label} deve ser maior ou igual a {#limit}',
'number.max': 'O campo {#label} deve ser menor ou igual a {#limit}',
'array.min': 'O campo {#label} deve ter pelo menos {#limit} itens',
'array.max': 'O campo {#label} deve ter no máximo {#limit} itens',
'any.only': 'O campo {#label} deve ser um dos valores: {#valids}',
};
export function formatValidationError(error: Joi.ValidationError): any {
return {
message: 'Dados de entrada inválidos',
details: error.details.map(detail => ({
field: detail.path.join('.'),
message: detail.message,
value: detail.context?.value,
})),
};
}
```
## Schema Composition
### Reusable Schema Components
```typescript
export const commonFields = {
instanceName: Joi.string().required().min(1).max(100).pattern(/^[a-zA-Z0-9_-]+$/),
number: phoneNumberValidator.required(),
delay: Joi.number().optional().min(0).max(60000),
enabled: Joi.boolean().optional().default(true),
};
export const mediaFields = {
mediatype: Joi.string().required().valid('image', 'video', 'audio', 'document'),
media: Joi.alternatives().try(
Joi.string().uri(),
base64Validator,
).required(),
caption: Joi.string().optional().max(1024),
fileName: Joi.string().optional().max(255),
};
// Compose schemas using common fields
export const quickMessageSchema = Joi.object({
...commonFields,
text: Joi.string().required().min(1).max(4096),
}).required();
export const quickMediaSchema = Joi.object({
...commonFields,
...mediaFields,
}).required();
```

View File

@@ -1,5 +1,6 @@
.git
*Dockerfile*
*docker-compose*
.env
node_modules
dist

403
.env.example Normal file
View File

@@ -0,0 +1,403 @@
SERVER_NAME=evolution
SERVER_TYPE=http
SERVER_PORT=8080
# Server URL - Set your application url
SERVER_URL=http://localhost:8080
SSL_CONF_PRIVKEY=/path/to/cert.key
SSL_CONF_FULLCHAIN=/path/to/cert.crt
SENTRY_DSN=
# Telemetry - Set to false to disable telemetry
TELEMETRY_ENABLED=true
TELEMETRY_URL=
# Prometheus metrics - Set to true to enable Prometheus metrics
PROMETHEUS_METRICS=false
METRICS_AUTH_REQUIRED=true
METRICS_USER=prometheus
METRICS_PASSWORD=secure_random_password_here
METRICS_ALLOWED_IPS=127.0.0.1,10.0.0.100,192.168.1.50
# Proxy configuration (optional)
PROXY_HOST=
PROXY_PORT=
PROXY_PROTOCOL=
PROXY_USERNAME=
PROXY_PASSWORD=
# Audio converter API (optional)
API_AUDIO_CONVERTER=
API_AUDIO_CONVERTER_KEY=
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
CORS_ORIGIN=*
CORS_METHODS=GET,POST,PUT,DELETE
CORS_CREDENTIALS=true
# Determine the logs to be displayed
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS,WEBSOCKET
LOG_COLOR=true
# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace"
LOG_BAILEYS=error
# Set the maximum number of listeners that can be registered for an event
EVENT_EMITTER_MAX_LISTENERS=50
# Determine how long the instance should be deleted from memory in case of no connection.
# Default time: 5 minutes
# If you don't even want an expiration, enter the value false
DEL_INSTANCE=false
# Provider: postgresql | mysql | psql_bouncer
DATABASE_PROVIDER=postgresql
DATABASE_CONNECTION_URI='postgresql://user:pass@postgres:5432/evolution_db?schema=evolution_api'
# Client name for the database connection
# It is used to separate an API installation from another that uses the same database.
DATABASE_CONNECTION_CLIENT_NAME=evolution_exchange
# Bouncer connection: used only when the database provider is set to 'psql_bouncer'.
# Defines the PostgreSQL URL with pgbouncer enabled (pgbouncer=true).
# DATABASE_BOUNCER_CONNECTION_URI=postgresql://user:pass@pgbouncer:5432/evolution_db?pgbouncer=true&schema=evolution_api
# Choose the data you want to save in the application's database
DATABASE_SAVE_DATA_INSTANCE=true
DATABASE_SAVE_DATA_NEW_MESSAGE=true
DATABASE_SAVE_MESSAGE_UPDATE=true
DATABASE_SAVE_DATA_CONTACTS=true
DATABASE_SAVE_DATA_CHATS=true
DATABASE_SAVE_DATA_LABELS=true
DATABASE_SAVE_DATA_HISTORIC=true
DATABASE_SAVE_IS_ON_WHATSAPP=true
DATABASE_SAVE_IS_ON_WHATSAPP_DAYS=7
DATABASE_DELETE_MESSAGE=true
# RabbitMQ - Environment variables
RABBITMQ_ENABLED=false
RABBITMQ_URI=amqp://localhost
RABBITMQ_EXCHANGE_NAME=evolution
RABBITMQ_FRAME_MAX=8192
# Global events - By enabling this variable, events from all instances are sent in the same event queue.
RABBITMQ_GLOBAL_ENABLED=false
# Prefix key to queue name
RABBITMQ_PREFIX_KEY=evolution
# Choose the events you want to send to RabbitMQ
RABBITMQ_EVENTS_APPLICATION_STARTUP=false
RABBITMQ_EVENTS_INSTANCE_CREATE=false
RABBITMQ_EVENTS_INSTANCE_DELETE=false
RABBITMQ_EVENTS_QRCODE_UPDATED=false
RABBITMQ_EVENTS_MESSAGES_SET=false
RABBITMQ_EVENTS_MESSAGES_UPSERT=false
RABBITMQ_EVENTS_MESSAGES_EDITED=false
RABBITMQ_EVENTS_MESSAGES_UPDATE=false
RABBITMQ_EVENTS_MESSAGES_DELETE=false
RABBITMQ_EVENTS_SEND_MESSAGE=false
RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE=false
RABBITMQ_EVENTS_CONTACTS_SET=false
RABBITMQ_EVENTS_CONTACTS_UPSERT=false
RABBITMQ_EVENTS_CONTACTS_UPDATE=false
RABBITMQ_EVENTS_PRESENCE_UPDATE=false
RABBITMQ_EVENTS_CHATS_SET=false
RABBITMQ_EVENTS_CHATS_UPSERT=false
RABBITMQ_EVENTS_CHATS_UPDATE=false
RABBITMQ_EVENTS_CHATS_DELETE=false
RABBITMQ_EVENTS_GROUPS_UPSERT=false
RABBITMQ_EVENTS_GROUP_UPDATE=false
RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=false
RABBITMQ_EVENTS_CONNECTION_UPDATE=false
RABBITMQ_EVENTS_REMOVE_INSTANCE=false
RABBITMQ_EVENTS_LOGOUT_INSTANCE=false
RABBITMQ_EVENTS_CALL=false
RABBITMQ_EVENTS_TYPEBOT_START=false
RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false
# SQS - Environment variables
SQS_ENABLED=false
SQS_ACCESS_KEY_ID=
SQS_SECRET_ACCESS_KEY=
SQS_ACCOUNT_ID=
SQS_REGION=
SQS_GLOBAL_ENABLED=false
SQS_GLOBAL_FORCE_SINGLE_QUEUE=false
SQS_GLOBAL_APPLICATION_STARTUP=false
SQS_GLOBAL_CALL=false
SQS_GLOBAL_CHATS_DELETE=false
SQS_GLOBAL_CHATS_SET=false
SQS_GLOBAL_CHATS_UPDATE=false
SQS_GLOBAL_CHATS_UPSERT=false
SQS_GLOBAL_CONNECTION_UPDATE=false
SQS_GLOBAL_CONTACTS_SET=false
SQS_GLOBAL_CONTACTS_UPDATE=false
SQS_GLOBAL_CONTACTS_UPSERT=false
SQS_GLOBAL_GROUP_PARTICIPANTS_UPDATE=false
SQS_GLOBAL_GROUPS_UPDATE=false
SQS_GLOBAL_GROUPS_UPSERT=false
SQS_GLOBAL_LABELS_ASSOCIATION=false
SQS_GLOBAL_LABELS_EDIT=false
SQS_GLOBAL_LOGOUT_INSTANCE=false
SQS_GLOBAL_MESSAGES_DELETE=false
SQS_GLOBAL_MESSAGES_EDITED=false
SQS_GLOBAL_MESSAGES_SET=false
SQS_GLOBAL_MESSAGES_UPDATE=false
SQS_GLOBAL_MESSAGES_UPSERT=false
SQS_GLOBAL_PRESENCE_UPDATE=false
SQS_GLOBAL_QRCODE_UPDATED=false
SQS_GLOBAL_REMOVE_INSTANCE=false
SQS_GLOBAL_SEND_MESSAGE=false
SQS_GLOBAL_TYPEBOT_CHANGE_STATUS=false
SQS_GLOBAL_TYPEBOT_START=false
# Websocket - Environment variables
WEBSOCKET_ENABLED=false
WEBSOCKET_GLOBAL_EVENTS=false
WEBSOCKET_ALLOWED_HOSTS=127.0.0.1,::1,::ffff:127.0.0.1
# Pusher - Environment variables
PUSHER_ENABLED=false
PUSHER_GLOBAL_ENABLED=false
PUSHER_GLOBAL_APP_ID=
PUSHER_GLOBAL_KEY=
PUSHER_GLOBAL_SECRET=
PUSHER_GLOBAL_CLUSTER=
PUSHER_GLOBAL_USE_TLS=true
# Choose the events you want to send to Pusher
PUSHER_EVENTS_APPLICATION_STARTUP=true
PUSHER_EVENTS_QRCODE_UPDATED=true
PUSHER_EVENTS_MESSAGES_SET=true
PUSHER_EVENTS_MESSAGES_UPSERT=true
PUSHER_EVENTS_MESSAGES_EDITED=true
PUSHER_EVENTS_MESSAGES_UPDATE=true
PUSHER_EVENTS_MESSAGES_DELETE=true
PUSHER_EVENTS_SEND_MESSAGE=true
PUSHER_EVENTS_SEND_MESSAGE_UPDATE=true
PUSHER_EVENTS_CONTACTS_SET=true
PUSHER_EVENTS_CONTACTS_UPSERT=true
PUSHER_EVENTS_CONTACTS_UPDATE=true
PUSHER_EVENTS_PRESENCE_UPDATE=true
PUSHER_EVENTS_CHATS_SET=true
PUSHER_EVENTS_CHATS_UPSERT=true
PUSHER_EVENTS_CHATS_UPDATE=true
PUSHER_EVENTS_CHATS_DELETE=true
PUSHER_EVENTS_GROUPS_UPSERT=true
PUSHER_EVENTS_GROUPS_UPDATE=true
PUSHER_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
PUSHER_EVENTS_CONNECTION_UPDATE=true
PUSHER_EVENTS_LABELS_EDIT=true
PUSHER_EVENTS_LABELS_ASSOCIATION=true
PUSHER_EVENTS_CALL=true
PUSHER_EVENTS_TYPEBOT_START=false
PUSHER_EVENTS_TYPEBOT_CHANGE_STATUS=false
# Kafka - Environment variables
KAFKA_ENABLED=false
KAFKA_CLIENT_ID=evolution-api
KAFKA_BROKERS=localhost:9092
KAFKA_CONNECTION_TIMEOUT=3000
KAFKA_REQUEST_TIMEOUT=30000
# Global events - By enabling this variable, events from all instances are sent to global Kafka topics.
KAFKA_GLOBAL_ENABLED=false
KAFKA_CONSUMER_GROUP_ID=evolution-api-consumers
KAFKA_TOPIC_PREFIX=evolution
KAFKA_NUM_PARTITIONS=1
KAFKA_REPLICATION_FACTOR=1
KAFKA_AUTO_CREATE_TOPICS=false
# Choose the events you want to send to Kafka
KAFKA_EVENTS_APPLICATION_STARTUP=false
KAFKA_EVENTS_INSTANCE_CREATE=false
KAFKA_EVENTS_INSTANCE_DELETE=false
KAFKA_EVENTS_QRCODE_UPDATED=false
KAFKA_EVENTS_MESSAGES_SET=false
KAFKA_EVENTS_MESSAGES_UPSERT=false
KAFKA_EVENTS_MESSAGES_EDITED=false
KAFKA_EVENTS_MESSAGES_UPDATE=false
KAFKA_EVENTS_MESSAGES_DELETE=false
KAFKA_EVENTS_SEND_MESSAGE=false
KAFKA_EVENTS_SEND_MESSAGE_UPDATE=false
KAFKA_EVENTS_CONTACTS_SET=false
KAFKA_EVENTS_CONTACTS_UPSERT=false
KAFKA_EVENTS_CONTACTS_UPDATE=false
KAFKA_EVENTS_PRESENCE_UPDATE=false
KAFKA_EVENTS_CHATS_SET=false
KAFKA_EVENTS_CHATS_UPSERT=false
KAFKA_EVENTS_CHATS_UPDATE=false
KAFKA_EVENTS_CHATS_DELETE=false
KAFKA_EVENTS_GROUPS_UPSERT=false
KAFKA_EVENTS_GROUPS_UPDATE=false
KAFKA_EVENTS_GROUP_PARTICIPANTS_UPDATE=false
KAFKA_EVENTS_CONNECTION_UPDATE=false
KAFKA_EVENTS_LABELS_EDIT=false
KAFKA_EVENTS_LABELS_ASSOCIATION=false
KAFKA_EVENTS_CALL=false
KAFKA_EVENTS_TYPEBOT_START=false
KAFKA_EVENTS_TYPEBOT_CHANGE_STATUS=false
# SASL Authentication (optional)
KAFKA_SASL_ENABLED=false
KAFKA_SASL_MECHANISM=plain
KAFKA_SASL_USERNAME=
KAFKA_SASL_PASSWORD=
# SSL Configuration (optional)
KAFKA_SSL_ENABLED=false
KAFKA_SSL_REJECT_UNAUTHORIZED=true
KAFKA_SSL_CA=
KAFKA_SSL_KEY=
KAFKA_SSL_CERT=
# WhatsApp Business API - Environment variables
# Token used to validate the webhook on the Facebook APP
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com
WA_BUSINESS_VERSION=v20.0
WA_BUSINESS_LANGUAGE=en_US
# Global Webhook Settings
# Each instance's Webhook URL and events will be requested at the time it is created
WEBHOOK_GLOBAL_ENABLED=false
# Define a global webhook that will listen for enabled events from all instances
WEBHOOK_GLOBAL_URL=''
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
# Set the events you want to hear
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_EDITED=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true
WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=true
WEBHOOK_EVENTS_CONTACTS_SET=true
WEBHOOK_EVENTS_CONTACTS_UPSERT=true
WEBHOOK_EVENTS_CONTACTS_UPDATE=true
WEBHOOK_EVENTS_PRESENCE_UPDATE=true
WEBHOOK_EVENTS_CHATS_SET=true
WEBHOOK_EVENTS_CHATS_UPSERT=true
WEBHOOK_EVENTS_CHATS_UPDATE=true
WEBHOOK_EVENTS_CHATS_DELETE=true
WEBHOOK_EVENTS_GROUPS_UPSERT=true
WEBHOOK_EVENTS_GROUPS_UPDATE=true
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_REMOVE_INSTANCE=false
WEBHOOK_EVENTS_LOGOUT_INSTANCE=false
WEBHOOK_EVENTS_LABELS_EDIT=true
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
WEBHOOK_EVENTS_CALL=true
# This events is used with Typebot
WEBHOOK_EVENTS_TYPEBOT_START=false
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
# This event is used to send errors
WEBHOOK_EVENTS_ERRORS=false
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
WEBHOOK_REQUEST_TIMEOUT_MS=60000
WEBHOOK_RETRY_MAX_ATTEMPTS=10
WEBHOOK_RETRY_INITIAL_DELAY_SECONDS=5
WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF=true
WEBHOOK_RETRY_MAX_DELAY_SECONDS=300
WEBHOOK_RETRY_JITTER_FACTOR=0.2
# Comma separated list of HTTP status codes that should not trigger retries
WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES=400,401,403,404,422
# Name that will be displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT=Evolution API
# Browser Name = Chrome | Firefox | Edge | Opera | Safari
CONFIG_SESSION_PHONE_NAME=Chrome
# Whatsapp Web version for baileys channel
# https://web.whatsapp.com/check-update?version=0&platform=web
# Set qrcode display limit
QRCODE_LIMIT=30
# Color of the QRCode on base64
QRCODE_COLOR='#175197'
# Typebot - Environment variables
TYPEBOT_ENABLED=false
# old | latest
TYPEBOT_API_VERSION=latest
# Chatwoot - Environment variables
CHATWOOT_ENABLED=false
# If you leave this option as false, when deleting the message for everyone on WhatsApp, it will not be deleted on Chatwoot.
CHATWOOT_MESSAGE_READ=true
# If you leave this option as true, when sending a message in Chatwoot, the client's last message will be marked as read on WhatsApp.
CHATWOOT_MESSAGE_DELETE=true
# If you leave this option as true, a contact will be created on Chatwoot to provide the QR Code and update messages about the instance.
CHATWOOT_BOT_CONTACT=true
# This db connection is used to import messages from whatsapp to chatwoot database
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://user:passwprd@host:5432/chatwoot?sslmode=disable
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true
# OpenAI - Environment variables
OPENAI_ENABLED=false
# Dify - Environment variables
DIFY_ENABLED=false
# n8n - Environment variables
N8N_ENABLED=false
# EvoAI - Environment variables
EVOAI_ENABLED=false
# Cache - Environment variables
# Redis Cache enabled
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://localhost:6379/6
CACHE_REDIS_TTL=604800
# Prefix serves to differentiate data from one installation to another that are using the same redis
CACHE_REDIS_PREFIX_KEY=evolution
# Enabling this variable will save the connection information in Redis and not in the database.
CACHE_REDIS_SAVE_INSTANCES=false
# Local Cache enabled
CACHE_LOCAL_ENABLED=false
# Amazon S3 - Environment variables
S3_ENABLED=false
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_BUCKET=evolution
S3_PORT=443
S3_ENDPOINT=s3.domain.com
S3_REGION=eu-west-3
S3_USE_SSL=true
# AMAZON S3 - Environment variables
# S3_ENABLED=true
# S3_BUCKET=bucket_name
# S3_ACCESS_KEY=access_key_id
# S3_SECRET_KEY=secret_access_key
# S3_ENDPOINT=s3.amazonaws.com # region: s3.eu-west-3.amazonaws.com
# S3_REGION=eu-west-3
# MINIO Use SSL - Environment variables
# S3_ENABLED=true
# S3_ACCESS_KEY=access_key_id
# S3_SECRET_KEY=secret_access_key
# S3_BUCKET=bucket_name
# S3_PORT=443
# S3_ENDPOINT=s3.domain.com
# S3_USE_SSL=true
# S3_REGION=eu-south
# Evolution Audio Converter - Environment variables - https://github.com/EvolutionAPI/evolution-audio-converter
# API_AUDIO_CONVERTER=http://localhost:4040/process-audio
# API_AUDIO_CONVERTER_KEY=429683C4C977415CAAFCCE10F7D57E11
# Define a global apikey to access all instances.
# OBS: This key must be inserted in the request header to create an instance.
AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11
# If you leave this option as true, the instances will be exposed in the fetch instances endpoint.
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
LANGUAGE=en
# Define a global proxy to be used if the instance does not have one
# PROXY_HOST=
# PROXY_PORT=80
# PROXY_PROTOCOL=http
# PROXY_USERNAME=
# PROXY_PASSWORD=

View File

@@ -1,50 +1,39 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'CommonJS',
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
warnOnUnsupportedTypeScriptVersion: false,
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,
},
plugins: [
'@typescript-eslint',
'simple-import-sort',
'import'
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended'
],
plugins: ['@typescript-eslint', 'simple-import-sort', 'import'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
root: true,
env: {
node: true,
jest: true,
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'import/first': 'error',
'import/no-duplicates': 'error',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'@typescript-eslint/ban-types': [
'error',
{
extendDefaults: true,
types: {
'{}': false,
Object: false,
},
},
],
'prettier/prettier': ['error', { endOfLine: 'auto' }],
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'import/first': 'error',
'import/no-duplicates': 'error',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-wrapper-object-types': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'prettier/prettier': ['error', { endOfLine: 'auto' }],
},
};
};

81
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: 🐛 Bug Report
description: Report a bug or unexpected behavior
title: "[BUG] "
labels: ["bug", "needs-triage"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please search existing issues before creating a new one.
- type: textarea
id: description
attributes:
label: 📋 Bug Description
description: A clear and concise description of what the bug is.
placeholder: Describe the bug...
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: 🔄 Steps to Reproduce
description: Steps to reproduce the behavior
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
id: expected
attributes:
label: ✅ Expected Behavior
description: A clear and concise description of what you expected to happen.
placeholder: What should happen?
validations:
required: true
- type: textarea
id: actual
attributes:
label: ❌ Actual Behavior
description: A clear and concise description of what actually happened.
placeholder: What actually happened?
validations:
required: true
- type: textarea
id: environment
attributes:
label: 🌍 Environment
description: Please provide information about your environment
value: |
- OS: [e.g. Ubuntu 20.04, Windows 10, macOS 12.0]
- Node.js version: [e.g. 18.17.0]
- Evolution API version: [e.g. 2.3.6]
- Database: [e.g. PostgreSQL 14, MySQL 8.0]
- Connection type: [e.g. Baileys, WhatsApp Business API]
validations:
required: true
- type: textarea
id: logs
attributes:
label: 📋 Logs
description: If applicable, add logs to help explain your problem.
placeholder: Paste relevant logs here...
render: shell
- type: textarea
id: additional
attributes:
label: 📝 Additional Context
description: Add any other context about the problem here.
placeholder: Any additional information...

View File

@@ -0,0 +1,85 @@
name: ✨ Feature Request
description: Suggest a new feature or enhancement
title: "[FEATURE] "
labels: ["enhancement", "needs-triage"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for suggesting a new feature!
Please check our [Feature Requests on Canny](https://evolutionapi.canny.io/feature-requests) first.
- type: textarea
id: problem
attributes:
label: 🎯 Problem Statement
description: Is your feature request related to a problem? Please describe.
placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: true
- type: textarea
id: solution
attributes:
label: 💡 Proposed Solution
description: Describe the solution you'd like
placeholder: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: 🔄 Alternatives Considered
description: Describe alternatives you've considered
placeholder: A clear and concise description of any alternative solutions or features you've considered.
- type: dropdown
id: priority
attributes:
label: 📊 Priority
description: How important is this feature to you?
options:
- Low - Nice to have
- Medium - Would be helpful
- High - Important for my use case
- Critical - Blocking my work
validations:
required: true
- type: dropdown
id: component
attributes:
label: 🧩 Component
description: Which component does this feature relate to?
options:
- WhatsApp Integration (Baileys)
- WhatsApp Business API
- Chatwoot Integration
- Typebot Integration
- OpenAI Integration
- Dify Integration
- API Endpoints
- Database
- Authentication
- Webhooks
- File Storage
- Other
- type: textarea
id: use_case
attributes:
label: 🎯 Use Case
description: Describe your specific use case for this feature
placeholder: How would you use this feature? What problem does it solve for you?
validations:
required: true
- type: textarea
id: additional
attributes:
label: 📝 Additional Context
description: Add any other context, screenshots, or examples about the feature request here.
placeholder: Any additional information, mockups, or examples...

41
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,41 @@
## 📋 Description
<!-- Describe your changes in detail -->
## 🔗 Related Issue
<!-- Link to the issue this PR addresses -->
Closes #(issue_number)
## 🧪 Type of Change
<!-- Mark with an `x` all the checkboxes that apply -->
- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
- [ ] ✨ New feature (non-breaking change which adds functionality)
- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] 📚 Documentation update
- [ ] 🔧 Refactoring (no functional changes)
- [ ] ⚡ Performance improvement
- [ ] 🧹 Code cleanup
- [ ] 🔒 Security fix
## 🧪 Testing
<!-- Describe the testing you performed to verify your changes -->
- [ ] Manual testing completed
- [ ] Functionality verified in development environment
- [ ] No breaking changes introduced
- [ ] Tested with different connection types (if applicable)
## 📸 Screenshots (if applicable)
<!-- Add screenshots to help explain your changes -->
## ✅ Checklist
<!-- Mark with an `x` all the checkboxes that apply -->
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have manually tested my changes thoroughly
- [ ] I have verified the changes work with different scenarios
- [ ] Any dependent changes have been merged and published
## 📝 Additional Notes
<!-- Any additional information, concerns, or questions -->

View File

@@ -0,0 +1,42 @@
name: Check Code Quality
on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main, develop ]
jobs:
check-lint-and-build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
with:
submodules: recursive
- name: Install Node
uses: actions/setup-node@v5
with:
node-version: 20.x
- name: Cache node modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install packages
run: npm ci
- name: Check linting
run: npm run lint:check
- name: Generate Prisma client
run: npm run db:generate
- name: Check build
run: npm run build

View File

@@ -14,13 +14,15 @@ jobs:
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: atendai/evolution-api
images: evoapicloud/evolution-api
tags: type=semver,pattern=v{{version}}
- name: Set up QEMU
@@ -37,7 +39,7 @@ jobs:
- name: Build and push
id: docker_build
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true

View File

@@ -14,13 +14,15 @@ jobs:
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: atendai/evolution-api
images: evoapicloud/evolution-api
tags: homolog
- name: Set up QEMU
@@ -37,7 +39,7 @@ jobs:
- name: Build and push
id: docker_build
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true

View File

@@ -3,7 +3,7 @@ name: Build Docker image
on:
push:
branches:
- v2.0.0
- main
jobs:
build_deploy:
@@ -14,14 +14,16 @@ jobs:
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: atendai/evolution-api
tags: v2.0.0-alpha
images: evoapicloud/evolution-api
tags: latest
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -37,7 +39,7 @@ jobs:
- name: Build and push
id: docker_build
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true

55
.github/workflows/security.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
schedule:
- cron: '0 0 * * 1' # Weekly on Mondays
jobs:
codeql:
name: CodeQL Analysis
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
submodules: recursive
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
submodules: recursive
- name: Dependency Review
uses: actions/dependency-review-action@v4

14
.gitignore vendored
View File

@@ -1,11 +1,11 @@
# Repo
Baileys
# compiled output
/dist
/node_modules
/Docker/.env
.vscode
# Logs
logs/**.json
*.log
@@ -18,11 +18,9 @@ lerna-debug.log*
/docker-compose-data
/docker-data
docker-compose.yaml
# Package
/yarn.lock
/package-lock.json
/pnpm-lock.yaml
# IDEs
.vscode/*
@@ -31,9 +29,7 @@ docker-compose.yaml
!.vscode/launch.json
!.vscode/extensions.json
.nova/*
# Prisma
/prisma/migrations
.idea/*
# Project related
/instances/*
@@ -48,3 +44,5 @@ docker-compose.yaml
.DS_Store
*.DS_Store
.tool-versions
/prisma/migrations/*

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "evolution-manager-v2"]
path = evolution-manager-v2
url = https://github.com/EvolutionAPI/evolution-manager-v2.git

51
.husky/README.md Normal file
View File

@@ -0,0 +1,51 @@
# Git Hooks Configuration
Este projeto usa [Husky](https://typicode.github.io/husky/) para automatizar verificações de qualidade de código.
## Hooks Configurados
### Pre-commit
- **Arquivo**: `.husky/pre-commit`
- **Executa**: `npx lint-staged`
- **Função**: Executa lint e correções automáticas apenas nos arquivos modificados
### Pre-push
- **Arquivo**: `.husky/pre-push`
- **Executa**: `npm run build` + `npm run lint:check`
- **Função**: Verifica se o projeto compila e não tem erros de lint antes do push
## Lint-staged Configuration
Configurado no `package.json`:
```json
"lint-staged": {
"src/**/*.{ts,js}": [
"eslint --fix",
"git add"
],
"src/**/*.ts": [
"npm run build"
]
}
```
## Como funciona
1. **Ao fazer commit**: Executa lint apenas nos arquivos modificados
2. **Ao fazer push**: Executa build completo e verificação de lint
3. **Se houver erros**: O commit/push é bloqueado até correção
## Comandos úteis
```bash
# Pular hooks (não recomendado)
git commit --no-verify
git push --no-verify
# Executar lint manualmente
npm run lint
# Executar build manualmente
npm run build
```

1
.husky/commit-msg Executable file
View File

@@ -0,0 +1 @@
npx --no -- commitlint --edit $1

1
.husky/pre-commit Normal file
View File

@@ -0,0 +1 @@
npx lint-staged

2
.husky/pre-push Executable file
View File

@@ -0,0 +1,2 @@
npm run build
npm run lint:check

355
AGENTS.md Normal file
View File

@@ -0,0 +1,355 @@
# Evolution API - AI Agent Guidelines
This document provides comprehensive guidelines for AI agents (Claude, GPT, Cursor, etc.) working with the Evolution API codebase.
## Project Overview
**Evolution API** is a production-ready, multi-tenant WhatsApp API platform built with Node.js, TypeScript, and Express.js. It supports multiple WhatsApp providers and extensive integrations with chatbots, CRM systems, and messaging platforms.
## Project Structure & Module Organization
### Core Directories
- **`src/`** TypeScript source code with modular architecture
- `api/controllers/` HTTP route handlers (thin layer)
- `api/services/` Business logic (core functionality)
- `api/routes/` Express route definitions (RouterBroker pattern)
- `api/integrations/` External service integrations
- `channel/` WhatsApp providers (Baileys, Business API, Evolution)
- `chatbot/` AI/Bot integrations (OpenAI, Dify, Typebot, Chatwoot)
- `event/` Event systems (WebSocket, RabbitMQ, SQS, NATS, Pusher)
- `storage/` File storage (S3, MinIO)
- `dto/` Data Transfer Objects (simple classes, no decorators)
- `guards/` Authentication/authorization middleware
- `types/` TypeScript type definitions
- `repository/` Data access layer (Prisma)
- **`prisma/`** Database schemas and migrations
- `postgresql-schema.prisma` / `mysql-schema.prisma` Provider-specific schemas
- `postgresql-migrations/` / `mysql-migrations/` Provider-specific migrations
- **`config/`** Environment and application configuration
- **`utils/`** Shared utilities and helper functions
- **`validate/`** JSONSchema7 validation schemas
- **`exceptions/`** Custom HTTP exception classes
- **`cache/`** Redis and local cache implementations
### Build & Deployment
- **`dist/`** Build output (do not edit directly)
- **`public/`** Static assets and media files
- **`Docker*`**, **`docker-compose*.yaml`** Containerization and local development stack
## Build, Test, and Development Commands
### Development Workflow
```bash
# Development server with hot reload
npm run dev:server
# Direct execution for testing
npm start
# Production build and run
npm run build
npm run start:prod
```
### Code Quality
```bash
# Linting and formatting
npm run lint # ESLint with auto-fix
npm run lint:check # ESLint check only
# Commit with conventional commits
npm run commit # Interactive commit with Commitizen
```
### Database Management
```bash
# Set database provider first (CRITICAL)
export DATABASE_PROVIDER=postgresql # or mysql
# Generate Prisma client
npm run db:generate
# Development migrations (with provider sync)
npm run db:migrate:dev # Unix/Mac
npm run db:migrate:dev:win # Windows
# Production deployment
npm run db:deploy # Unix/Mac
npm run db:deploy:win # Windows
# Database tools
npm run db:studio # Open Prisma Studio
```
### Docker Development
```bash
# Start local services (Redis, PostgreSQL, etc.)
docker-compose up -d
# Full development stack
docker-compose -f docker-compose.dev.yaml up -d
```
## Coding Standards & Architecture Patterns
### Code Style (Enforced by ESLint + Prettier)
- **TypeScript strict mode** with full type coverage
- **2-space indentation**, single quotes, trailing commas
- **120-character line limit**
- **Import order** via `simple-import-sort`
- **File naming**: `feature.kind.ts` (e.g., `whatsapp.baileys.service.ts`)
- **Naming conventions**:
- Classes: `PascalCase`
- Functions/variables: `camelCase`
- Constants: `UPPER_SNAKE_CASE`
- Files: `kebab-case.type.ts`
### Architecture Patterns
#### Service Layer Pattern
```typescript
export class ExampleService {
constructor(private readonly waMonitor: WAMonitoringService) {}
private readonly logger = new Logger('ExampleService');
public async create(instance: InstanceDto, data: ExampleDto) {
// Business logic here
return { example: { ...instance, data } };
}
public async find(instance: InstanceDto): Promise<ExampleDto | null> {
try {
const result = await this.waMonitor.waInstances[instance.instanceName].findData();
return result || null; // Return null on not found (Evolution pattern)
} catch (error) {
this.logger.error('Error finding data:', error);
return null; // Return null on error (Evolution pattern)
}
}
}
```
#### Controller Pattern (Thin Layer)
```typescript
export class ExampleController {
constructor(private readonly exampleService: ExampleService) {}
public async createExample(instance: InstanceDto, data: ExampleDto) {
return this.exampleService.create(instance, data);
}
}
```
#### RouterBroker Pattern
```typescript
export class ExampleRouter extends RouterBroker {
constructor(...guards: any[]) {
super();
this.router.post(this.routerPath('create'), ...guards, async (req, res) => {
const response = await this.dataValidate<ExampleDto>({
request: req,
schema: exampleSchema, // JSONSchema7
ClassRef: ExampleDto,
execute: (instance, data) => controller.createExample(instance, data),
});
res.status(201).json(response);
});
}
}
```
#### DTO Pattern (Simple Classes)
```typescript
// CORRECT - Evolution API pattern (no decorators)
export class ExampleDto {
name: string;
description?: string;
enabled: boolean;
}
// INCORRECT - Don't use class-validator decorators
export class BadExampleDto {
@IsString() // ❌ Evolution API doesn't use decorators
name: string;
}
```
#### Validation Pattern (JSONSchema7)
```typescript
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
export const exampleSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
name: { type: 'string' },
description: { type: 'string' },
enabled: { type: 'boolean' },
},
required: ['name', 'enabled'],
};
```
## Multi-Tenant Architecture
### Instance Isolation
- **CRITICAL**: All operations must be scoped by `instanceName` or `instanceId`
- **Database queries**: Always include `where: { instanceId: ... }`
- **Authentication**: Validate instance ownership before operations
- **Data isolation**: Complete separation between tenant instances
### WhatsApp Instance Management
```typescript
// Access instance via WAMonitoringService
const waInstance = this.waMonitor.waInstances[instance.instanceName];
if (!waInstance) {
throw new NotFoundException(`Instance ${instance.instanceName} not found`);
}
```
## Database Patterns
### Multi-Provider Support
- **PostgreSQL**: Uses `@db.Integer`, `@db.JsonB`, `@default(now())`
- **MySQL**: Uses `@db.Int`, `@db.Json`, `@default(now())`
- **Environment**: Set `DATABASE_PROVIDER=postgresql` or `mysql`
- **Migrations**: Provider-specific folders auto-selected
### Prisma Repository Pattern
```typescript
// Always use PrismaRepository for database operations
const result = await this.prismaRepository.instance.findUnique({
where: { name: instanceName },
});
```
## Integration Patterns
### Channel Integration (WhatsApp Providers)
- **Baileys**: WhatsApp Web with QR code authentication
- **Business API**: Official Meta WhatsApp Business API
- **Evolution API**: Custom WhatsApp integration
- **Pattern**: Extend base channel service classes
### Chatbot Integration
- **Base classes**: Extend `BaseChatbotService` and `BaseChatbotController`
- **Trigger system**: Support keyword, regex, and advanced triggers
- **Session management**: Handle conversation state per user
- **Available integrations**: EvolutionBot, OpenAI, Dify, Typebot, Chatwoot, Flowise, N8N, EvoAI
### Event Integration
- **Internal events**: EventEmitter2 for application events
- **External events**: WebSocket, RabbitMQ, SQS, NATS, Pusher
- **Webhook delivery**: Reliable delivery with retry logic
## Testing Guidelines
### Current State
- **No formal test suite** currently implemented
- **Manual testing** is the primary approach
- **Integration testing** in development environment
### Testing Strategy
```typescript
// Place tests in test/ directory as *.test.ts
// Run: npm test (watches test/all.test.ts)
describe('ExampleService', () => {
it('should create example', async () => {
// Mock external dependencies
// Test business logic
// Assert expected behavior
});
});
```
### Recommended Approach
- Focus on **critical business logic** in services
- **Mock external dependencies** (WhatsApp APIs, databases)
- **Integration tests** for API endpoints
- **Manual testing** for WhatsApp connection flows
## Commit & Pull Request Guidelines
### Conventional Commits (Enforced by commitlint)
```bash
# Use interactive commit tool
npm run commit
# Commit format: type(scope): subject (max 100 chars)
# Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert, security
```
### Examples
- `feat(api): add WhatsApp message status endpoint`
- `fix(baileys): resolve connection timeout issue`
- `docs(readme): update installation instructions`
- `refactor(service): extract common message validation logic`
### Pull Request Requirements
- **Clear description** of changes and motivation
- **Linked issues** if applicable
- **Migration impact** (specify database provider)
- **Local testing steps** with screenshots/logs
- **Breaking changes** clearly documented
## Security & Configuration
### Environment Setup
```bash
# Copy example environment file
cp .env.example .env
# NEVER commit secrets to version control
# Set DATABASE_PROVIDER before database commands
export DATABASE_PROVIDER=postgresql # or mysql
```
### Security Best Practices
- **API key authentication** via `apikey` header
- **Input validation** with JSONSchema7
- **Rate limiting** on all endpoints
- **Webhook signature validation**
- **Instance-based access control**
- **Secure defaults** for all configurations
### Vulnerability Reporting
- See `SECURITY.md` for security vulnerability reporting process
- Contact: `contato@evolution-api.com`
## Communication Standards
### Language Requirements
- **User communication**: Always respond in Portuguese (PT-BR)
- **Code/comments**: English for technical documentation
- **API responses**: English for consistency
- **Error messages**: Portuguese for user-facing errors
### Documentation Standards
- **Inline comments**: Document complex business logic
- **API documentation**: Document all public endpoints
- **Integration guides**: Document new integration patterns
- **Migration guides**: Document database schema changes
## Performance & Scalability
### Caching Strategy
- **Redis primary**: Distributed caching for production
- **Node-cache fallback**: Local caching when Redis unavailable
- **TTL strategy**: Appropriate cache expiration per data type
- **Cache invalidation**: Proper invalidation on data changes
### Connection Management
- **Database**: Prisma connection pooling
- **WhatsApp**: One connection per instance with lifecycle management
- **Redis**: Connection pooling and retry logic
- **External APIs**: Rate limiting and retry with exponential backoff
### Monitoring & Observability
- **Structured logging**: Pino logger with correlation IDs
- **Error tracking**: Comprehensive error scenarios
- **Health checks**: Instance status and connection monitoring
- **Telemetry**: Usage analytics (non-sensitive data only)

View File

@@ -1,3 +1,587 @@
# 2.3.6 (2025-10-21)
### Features
* **Baileys, Chatwoot, OnWhatsapp Cache**: Multiple implementations and fixes
- Fixed cache for PN, LID and g.us numbers to send correct number
- Fixed audio and document sending via Chatwoot in Baileys channel
- Multiple fixes in Chatwoot integration
- Fixed ignored messages when receiving leads
### Fixed
* **Baileys**: Fix buffer storage in database
- Correctly save Uint8Array values to database
* **Baileys**: Simplify logging of messageSent object
- Fixed "this.isZero not is function" error
### Chore
* **Version**: Bump version to 2.3.6 and update Baileys dependency to 7.0.0-rc.6
* **Workflows**: Update checkout step to include submodules
- Added 'submodules: recursive' option to checkout step in multiple workflow files to ensure submodules are properly initialized during CI/CD processes
* **Manager**: Update asset files and install process
- Updated subproject reference in evolution-manager-v2 to the latest commit
- Enhanced the manager_install.sh script to include npm install and build steps
- Replaced old JavaScript asset file with a new version for improved performance
- Added a new CSS file for consistent styling across the application
# 2.3.5 (2025-10-15)
### Features
* **Chatwoot Enhancements**: Comprehensive improvements to message handling, editing, deletion and i18n
* **Participants Data**: Add participantsData field maintaining backward compatibility for group participants
* **LID to Phone Number**: Convert LID to phoneNumber on group participants
* **Docker Configurations**: Add Kafka and frontend services to Docker configurations
### Fixed
* **Kafka Migration**: Fixed PostgreSQL migration error for Kafka integration
- Corrected table reference from `"public"."Instance"` to `"Instance"` in foreign key constraint
- Fixed `ERROR: relation "public.Instance" does not exist` issue in migration `20250918182355_add_kafka_integration`
- Aligned table naming convention with other Evolution API migrations for consistency
- Resolved database migration failure that prevented Kafka integration setup
* **Update Baileys Version**: v7.0.0-rc.5 with compatibility fixes
- Fixed assertSessions signature compatibility using type assertion
- Fixed incompatibility in voice call (wavoip) with new Baileys version
- Handle undefined status in update by defaulting to 'DELETED'
* **Chatwoot Improvements**: Multiple fixes for enhanced reliability
- Correct chatId extraction for non-group JIDs
- Resolve webhook timeout on deletion with 5+ images
- Improve error handling in Chatwoot messages
- Adjust conversation verification logic and cache
- Optimize conversation reopening logic and connection notification
- Fix conversation reopening and connection loop
* **Baileys Message Handling**: Enhanced message processing
- Add warning log for messages not found
- Fix message verification in Baileys service
- Simplify linkPreview handling in BaileysStartupService
* **Media Validation**: Fix media content validation
* **PostgreSQL Connection**: Refactor connection with PostgreSQL and improve message handling
### Code Quality & Refactoring
* **Exponential Backoff**: Implement exponential backoff patterns and extract magic numbers to constants
* **TypeScript Build**: Update TypeScript build process and dependencies
###
# 2.3.4 (2025-09-23)
### Features
* **Kafka Integration**: Added Apache Kafka event integration for real-time event streaming
- New Kafka controller, router, and schema for event publishing
- Support for instance-specific and global event topics
- Configurable SASL/SSL authentication and connection settings
- Auto-creation of topics with configurable partitions and replication
- Consumer group management for reliable event processing
- Integration with existing event manager for seamless event distribution
* **Evolution Manager v2 Open Source**: Evolution Manager v2 is now available as open source
- Added as git submodule with HTTPS URL for easy access
- Complete open source setup with Apache 2.0 license + Evolution API custom conditions
- GitHub templates for issues, pull requests, and workflows
- Comprehensive documentation and contribution guidelines
- Docker support for development and production environments
- CI/CD workflows for code quality, security audits, and automated builds
- Multi-language support (English, Portuguese, Spanish, French)
- Modern React + TypeScript + Vite frontend with Tailwind CSS
* **EvolutionBot Enhancements**: Improved EvolutionBot functionality and message handling
- Implemented splitMessages functionality for better message segmentation
- Added linkPreview support for enhanced message presentation
- Centralized split logic across chatbot services for consistency
- Enhanced message formatting and delivery capabilities
### Fixed
* **MySQL Schema**: Fixed invalid default value errors for `createdAt` fields in `Evoai` and `EvoaiSetting` models
- Changed `@default(now())` to `@default(dbgenerated("CURRENT_TIMESTAMP"))` for MySQL compatibility
- Added missing relation fields (`N8n`, `N8nSetting`, `Evoai`, `EvoaiSetting`) in Instance model
- Resolved Prisma schema validation errors for MySQL provider
* **Prisma Schema Validation**: Fixed `instanceName` field error in message creation
- Removed invalid `instanceName` field from message objects before database insertion
- Resolved `Unknown argument 'instanceName'` Prisma validation error
- Streamlined message data structure to match Prisma schema requirements
* **Media Message Processing**: Enhanced media handling across chatbot services
- Fixed base64 conversion in EvoAI service for proper image processing
- Converted ArrayBuffer to base64 string using `Buffer.from().toString('base64')`
- Improved media URL handling and base64 encoding for better chatbot integration
- Enhanced image message detection and processing workflow
* **Evolution Manager v2 Linting**: Resolved ESLint configuration conflicts
- Disabled conflicting Prettier rules in ESLint configuration
- Added comprehensive rule overrides for TypeScript and React patterns
- Fixed import ordering and code formatting issues
- Updated security vulnerabilities in dependencies (Vite, esbuild)
### Code Quality & Refactoring
* **Chatbot Services**: Streamlined media message handling across all chatbot integrations
- Standardized base64 and mediaUrl processing patterns
- Improved code readability and maintainability in media handling logic
- Enhanced error handling for media download and conversion processes
- Unified image message detection across different chatbot services
* **Database Operations**: Improved data consistency and validation
- Enhanced Prisma schema compliance across all message operations
- Removed redundant instance name references for better data integrity
- Optimized message creation workflow with proper field validation
### Environment Variables
* Added comprehensive Kafka configuration options:
- `KAFKA_ENABLED`, `KAFKA_CLIENT_ID`, `KAFKA_BROKERS`
- `KAFKA_CONSUMER_GROUP_ID`, `KAFKA_TOPIC_PREFIX`
- `KAFKA_SASL_*` and `KAFKA_SSL_*` for authentication
- `KAFKA_EVENTS_*` for event type configuration
# 2.3.3 (2025-09-18)
### Features
* Add extra fields to object sent to Flowise bot
* Add Prometheus-compatible /metrics endpoint (gated by PROMETHEUS_METRICS)
* Implement linkPreview support for Evolution Bot
### Fixed
* Address Path Traversal vulnerability in /assets endpoint by implementing security checks
* Configure Husky and lint-staged for automated code quality checks on commits and pushes
* Convert mediaKey from media messages to avoid bad decrypt errors
* Improve code formatting for better readability in WhatsApp service files
* Format messageGroupId assignment for improved readability
* Improve linkPreview implementation based on PR feedback
* Clean up code formatting for linkPreview implementation
* Use 'unknown' as fallback for clientName label
* Remove abort process when status is paused, allowing the chatbot return after the time expires and after being paused due to human interaction (stopBotFromMe)
* Enhance message content sanitization in Baileys service and improve message retrieval logic in Chatwoot service
* Integrate Typebot status change events for webhook in chatbot controller and service
* Mimetype of videos video
### Security
* **CRITICAL**: Fixed Path Traversal vulnerability in /assets endpoint that allowed unauthenticated local file read
* Customizable Websockets Security
### Testing
* Baileys Updates: v7.0.0-rc.3 ([Link](https://github.com/WhiskeySockets/Baileys/releases/tag/v7.0.0-rc.3))
# 2.3.2 (2025-09-02)
### Features
* Add support to socks proxy
### Fixed
* Added key id into webhook payload in n8n service
* Enhance RabbitMQ controller with improved connection management and shutdown procedures
* Convert outgoing images to JPEG before sending with Chatwoot
* Update baileys dependency to version 6.7.19
# 2.3.1 (2025-07-29)
### Feature
* Add BaileysMessageProcessor for improved message handling and integrate rxjs for asynchronous processing
* Enhance message processing with retry logic for error handling
### Fixed
* Update Baileys Version
* Update Dockerhub Repository and Delete Config Session Variable
* Fixed sending variables in typebot
* Add unreadMessages in the response
* Phone number as message ID for Evo AI
* Fix upload to s3 when media message
* Simplify edited message check in BaileysStartupService
* Avoid corrupting URLs with query strings
* Removed CONFIG_SESSION_PHONE_VERSION environment variable
# 2.3.0 (2025-06-17 09:19)
### Feature
* Add support to get Catalogs and Collections with new routes: '{{baseUrl}}/chat/fetchCatalogs' and '{{baseUrl}}/chat/fetchCollections'
* Add NATS integration support to the event system
* Add message location support meta
* Add S3_SKIP_POLICY env variable to disable setBucketPolicy for incompatible providers
* Add EvoAI integration with models, services, and routes
* Add N8n integration with models, services, and routes
### Fixed
* Shell injection vulnerability
* Update Baileys Version v6.7.18
* Audio send duplicate from chatwoot
* Chatwoot csat creating new conversation in another language
* Refactor SQS controller to correct bug in sqs events by instance
* Adjustin cloud api send audio and video
* Preserve animation in GIF and WebP stickers
* Preventing use conversation from other inbox for the same user
* Ensure full WhatsApp compatibility for audio conversion (libopus, 48kHz, mono)
* Enhance message fetching and processing logic
* Added lid on whatsapp numbers router
* Now if the CONFIG_SESSION_PHONE_VERSION variable is not filled in it automatically searches for the most updated version
### Security
* Change execSync to execFileSync
* Enhance WebSocket authentication and connection handling
# 2.2.3 (2025-02-03 11:52)
### Fixed
* Fix cache in local file system
* Update Baileys Version
# 2.2.2 (2025-01-31 06:55)
### Features
* Added prefix key to queue name in RabbitMQ
### Fixed
* Update Baileys Version
# 2.2.1 (2025-01-22 14:37)
### Features
* Retry system for send webhooks
* Message filtering to support timestamp range queries
* Chats filtering to support timestamp range queries
### Fixed
* Correction of webhook global
* Fixed send audio with whatsapp cloud api
* Refactor on fetch chats
* Refactor on Evolution Channel
# 2.2.0 (2024-10-18 10:00)
### Features
* Fake Call function
* Send List with Baileys
* Send Buttons with Baileys
* Added unreadMessages to chats
* Pusher event integration
* Add support for splitMessages and timePerChar in Integrations
* Audio Converter via API
* Send PTV messages with Baileys
### Fixed
* Fixed prefilledVariables in startTypebot
* Fix duplicate file upload
* Mark as read from me and groups
* Fetch chats query
* Ads messages in chatwoot
* Add indexes to improve performance in Evolution
* Add logical or permanent message deletion based on env config
* Add support for fetching multiple instances by key
* Update instance.controller.ts to filter by instanceName
* Receive template button reply message
# 2.1.2 (2024-10-06 10:09)
### Features
* Sync lost messages on chatwoot
* Set the maximum number of listeners that can be registered for events
* Now is possible send medias with form-data
### Fixed
* Fetch status message
* Adjusts in migrations
* Update pushName in chatwoot
* Validate message before sending chatwoot
* Adds the message status to the return of the "prepareMessage" function
* Fixed openai setting when send a message with chatwoot
* Fix buildkey function in hSet and hDelete
* Fix mexico number
* Update baileys version
* Update in Baileys version that fixes timeout when updating profile picture
* Adjusts for fix timeout error on send status message
* Chatwoot verbose logs
* Adjusts on prisma connections
* License terms updated
* Fixed send message to group without no cache (local or redis)
* Fixed startTypebot with startSession = true
* Fixed issue of always creating a new label when saving chatwoot
* Fixed getBase64FromMediaMessage with convertToMp4
* Fixed bug when send message when don't have mentionsEveryOne on payload
* Does not search message without chatwoot Message Id for reply
* Fixed bot fallback not working on integrations
# 2.1.1 (2024-09-22 10:31)
### Features
* Define a global proxy to be used if the instance does not have one
* Save is on whatsapp on the database
* Add headers to the instance's webhook registration
* Debounce message break is now "\n" instead of white space
* Single view messages are now supported in chatwoot
* Chatbots can now send any type of media
### Fixed
* Validate if cache exists before accessing it
* Missing autoCreate chatwoot in instance create
* Fixed bugs in the frontend, on the event screens
* Fixed use chatwoot with evolution channel
* Fix chatwoot reply quote with Cloud API
* Use exchange name from .env on RabbitMQ
* Fixed chatwoot screen
* It is now possible to send images via the Evolution Channel
* Removed "version" from docker-compose as it is obsolete (https://dev.to/ajeetraina/do-we-still-use-version-in-compose-3inp)
* Fixed typebot ignoreJids being used only from default settings
* Fixed Chatwoot inbox creation on save
* Changed axios timeout for manager requests for 30s
* Update in Baileys version that fixes timeout when updating profile picture
* Fixed issue when sending links in markdown by chatbots like Dify
* Fixed issue with chatbots not respecting settings
# 2.1.0 (2024-08-26 15:33)
### Features
* Improved layout manager
* Translation in manager: English, Portuguese, Spanish and French
* Evolution Bot Integration
* Option to disable chatwoot bot contact with CHATWOOT_BOT_CONTACT
* Added flowise integration
* Added evolution channel on instance create
* Change in license to Apache-2.0
* Mark All in events
### Fixed
* Refactor integrations structure for modular system
* Fixed dify agent integration
* Update Baileys Version
* Fixed proxy config in manager
* Fixed send messages in groups
* S3 saving media sent from me
* Fixed duplication bot when use startTypebot
### Break Changes
* Payloads for events changed (create Instance and set events). Check postman to understand
# 2.0.10 (2024-08-16 16:23)
### Features
* OpenAI send images when markdown
* Dify send images when markdown
* Sentry implemented
### Fixed
* Fix on get profilePicture
* Added S3_REGION on minio settings
# 2.0.9 (2024-08-15 12:31)
### Features
* Added ignoreJids in chatwoot settings
* Dify now identifies images
* Openai now identifies images
### Fixed
* Path mapping & deps fix & bundler changed to tsup
* Improve database scripts to retrieve the provider from env file
* Update contacts database with unique index
* Save chat name
* Correction of media as attachments in chatwoot when using a Meta API Instance and not Baileys
* Update Baileys version 6.7.6
* Deprecate buttons and list in new Baileys version
* Changed labels to be unique on the same instance
* Remove instance from redis even if using database
* Unified integration session system so they don't overlap
* Temporary fix for pictureUrl bug in groups
* Fix on migrations
# 2.0.9-rc (2024-08-09 18:00)
### Features
* Added general session button in typebot, dify and openai in manager
* Added compatibility with mysql through prisma
### Fixed
* Import contacts with image in chatwoot
* Fix conversationId when is dify agent
* Fixed loading of selects in the manager
* Add restart button to sessions screen
* Adjustments to docker files
* StopBotFromMe working with chatwoot
# 2.0.8-rc (2024-08-08 20:23)
### Features
* Variables passed to the input in dify
* OwnerJid passed to typebot
* Function for openai assistant added
### Fixed
* Adjusts in telemetry
# 2.0.7-rc (2024-08-03 14:04)
### Fixed
* BusinessId added on create instances in manager
* Adjusts in restart instance
* Resolve issue with connecting to instance
* Session is now individual per instance and remoteJid
* Credentials verify on manager login
* Added description column on typebot, dify and openai
* Fixed dify agent integration
# 2.0.6-rc (2024-08-02 19:23)
### Features
* Get models for OpenAI
### Fixed
* fetchInstances with clientName parameter
* fixed update typebot, openai and dify
# 2.0.5-rc (2024-08-01 18:01)
### Features
* Speech to Text with Openai
### Fixed
* ClientName on infos
* Instance screen scroll bar in manager
# 2.0.4-rc (2024-07-30 14:13)
### Features
* New manager v2.0
* Dify integration
### Fixed
* Update Baileys Version
* Adjusts for new manager
* Corrected openai trigger validation
* Corrected typebot trigger validation
# 2.0.3-beta (2024-07-29 09:03)
### Features
* Webhook url by submitted template to send status updates
* Sending template approval status webhook
### Fixed
* Equations and adjustments for the new manager
* Adjust TriggerType for OpenAI and Typebot integrations
* Fixed Typebot start call with active session
# 2.0.2-beta (2024-07-18 21:33)
### Feature
* Open AI implemented
### Fixed
* Fixed the function of saving or not saving data in the database
* Resolve not find name
* Removed DEL_TEMP_INSTANCES as it is not being used
* Fixed global exchange name
* Add apiKey and serverUrl to prefilledVariables in typebot service
* Correction in start typebot, if it doesn't exist, create it
# 2.0.1-beta (2024-07-17 17:01)
### Fixed
* Resolved issue with Chatwoot not receiving messages sent by Typebot
# 2.0.0-beta (2024-07-14 17:00)
### Feature
* Added prisma orm, connection to postgres and mysql
* Added chatwoot integration activation
* Added typebot integration activation
* Now you can register several typebots with triggers
* Media sent to typebot now goes as a template string, example: imageMessage|MESSAGE_ID
* Organization configuration and logo in chatwoot bot contact
* Added debounce time for typebot messages
* Tagging in chatwoot contact by instance
* Add support for managing WhatsApp templates via official API
* Fixes and implementation of regex and fallback in typebot
* Ignore jids configuration added to typebot (will be used for both groups and contacts)
* Minio and S3 integration
* When S3 integration enabled, the media sent to typebot now goes as a template string, example: imageMessage|MEDIA_URL
### Fixed
* Removed excessive verbose logs
* Optimization in instance registration
* Now in typebot we wait until the terminal block to accept the user's message, if it arrives before the block is sent, it is ignored
* Correction of audio sending, now we can speed it up and have the audio wireframe
* Reply with media message on Chatwoot
* improvements in sending status and groups
* Correction in response returns from buttons, lists and templates
* EvolutionAPI/Baileys implemented
### Break changes
* jwt authentication removed
* Connection to mongodb removed
* Standardized all request bodies to use camelCase
* Change in webhook information from owner to instanceId
* Changed the .env file configuration, removed the yml version and added .env to the repository root
* Removed the mobile type connection with Baileys
* Simplified payloads and endpoints
* Improved Typebot
- Now you can register several typebots
- Start configuration by trigger or for all
- Session search by typebot or remoteJid
- KeepOpen configuration (keeps the session even when the bot ends, to run once per contact)
- StopBotFromMe configuration, allows me to stop the bot if I send a chat message.
* Changed the way the goal webhook is configured
# 1.8.2 (2024-07-03 13:50)
### Fixed
* Corretion in globall rabbitmq queue name
* Improvement in the use of mongodb database for credentials
* Fixed base64 in webhook for documentWithCaption
* Fixed Generate pairing code
# 1.8.1 (2024-06-08 21:32)
### Feature
@@ -8,6 +592,10 @@
* Correction of variables breaking lines in typebot
### Fixed
* Correction of variables breaking lines in typebot
# 1.8.0 (2024-05-27 16:10)
### Feature

223
CLAUDE.md Normal file
View File

@@ -0,0 +1,223 @@
# CLAUDE.md
This file provides comprehensive guidance to Claude AI when working with the Evolution API codebase.
## Project Overview
**Evolution API** is a powerful, production-ready REST API for WhatsApp communication that supports multiple WhatsApp providers:
- **Baileys** (WhatsApp Web) - Open-source WhatsApp Web client
- **Meta Business API** - Official WhatsApp Business API
- **Evolution API** - Custom WhatsApp integration
Built with **Node.js 20+**, **TypeScript 5+**, and **Express.js**, it provides extensive integrations with chatbots, CRM systems, and messaging platforms in a **multi-tenant architecture**.
## Common Development Commands
### Build and Run
```bash
# Development
npm run dev:server # Run in development with hot reload (tsx watch)
# Production
npm run build # TypeScript check + tsup build
npm run start:prod # Run production build
# Direct execution
npm start # Run with tsx
```
### Code Quality
```bash
npm run lint # ESLint with auto-fix
npm run lint:check # ESLint check only
npm run commit # Interactive commit with commitizen
```
### Database Management
```bash
# Set database provider first
export DATABASE_PROVIDER=postgresql # or mysql
# Generate Prisma client (automatically uses DATABASE_PROVIDER env)
npm run db:generate
# Deploy migrations (production)
npm run db:deploy # Unix/Mac
npm run db:deploy:win # Windows
# Development migrations (with sync to provider folder)
npm run db:migrate:dev # Unix/Mac
npm run db:migrate:dev:win # Windows
# Open Prisma Studio
npm run db:studio
# Development migrations
npm run db:migrate:dev # Unix/Mac
npm run db:migrate:dev:win # Windows
```
### Testing
```bash
npm test # Run tests with watch mode
```
## Architecture Overview
### Core Structure
- **Multi-tenant SaaS**: Complete instance isolation with per-tenant authentication
- **Multi-provider database**: PostgreSQL and MySQL via Prisma ORM with provider-specific schemas and migrations
- **WhatsApp integrations**: Baileys, Meta Business API, and Evolution API with unified interface
- **Event-driven architecture**: EventEmitter2 for internal events + WebSocket, RabbitMQ, SQS, NATS, Pusher for external events
- **Microservices pattern**: Modular integrations for chatbots, storage, and external services
### Directory Layout
```
src/
├── api/
│ ├── controllers/ # HTTP route handlers (thin layer)
│ ├── services/ # Business logic (core functionality)
│ ├── repository/ # Data access layer (Prisma)
│ ├── dto/ # Data Transfer Objects (simple classes)
│ ├── guards/ # Authentication/authorization middleware
│ ├── integrations/ # External service integrations
│ │ ├── channel/ # WhatsApp providers (Baileys, Business API, Evolution)
│ │ ├── chatbot/ # AI/Bot integrations (OpenAI, Dify, Typebot, Chatwoot)
│ │ ├── event/ # Event systems (WebSocket, RabbitMQ, SQS, NATS, Pusher)
│ │ └── storage/ # File storage (S3, MinIO)
│ ├── routes/ # Express route definitions (RouterBroker pattern)
│ └── types/ # TypeScript type definitions
├── config/ # Environment and app configuration
├── cache/ # Redis and local cache implementations
├── exceptions/ # Custom HTTP exception classes
├── utils/ # Shared utilities and helpers
└── validate/ # JSONSchema7 validation schemas
```
### Key Integration Points
**Channel Integrations** (`src/api/integrations/channel/`):
- **Baileys**: WhatsApp Web client with QR code authentication
- **Business API**: Official Meta WhatsApp Business API
- **Evolution API**: Custom WhatsApp integration
- Connection lifecycle management per instance with automatic reconnection
**Chatbot Integrations** (`src/api/integrations/chatbot/`):
- **EvolutionBot**: Native chatbot with trigger system
- **Chatwoot**: Customer service platform integration
- **Typebot**: Visual chatbot flow builder
- **OpenAI**: AI capabilities including GPT and Whisper (audio transcription)
- **Dify**: AI agent workflow platform
- **Flowise**: LangChain visual builder
- **N8N**: Workflow automation platform
- **EvoAI**: Custom AI integration
**Event Integrations** (`src/api/integrations/event/`):
- **WebSocket**: Real-time Socket.io connections
- **RabbitMQ**: Message queue for async processing
- **Amazon SQS**: Cloud-based message queuing
- **NATS**: High-performance messaging system
- **Pusher**: Real-time push notifications
**Storage Integrations** (`src/api/integrations/storage/`):
- **AWS S3**: Cloud object storage
- **MinIO**: Self-hosted S3-compatible storage
- Media file management and URL generation
### Database Schema Management
- Separate schema files: `postgresql-schema.prisma` and `mysql-schema.prisma`
- Environment variable `DATABASE_PROVIDER` determines active database
- Migration folders are provider-specific and auto-selected during deployment
### Authentication & Security
- **API key-based authentication** via `apikey` header (global or per-instance)
- **Instance-specific tokens** for WhatsApp connection authentication
- **Guards system** for route protection and authorization
- **Input validation** using JSONSchema7 with RouterBroker `dataValidate`
- **Rate limiting** and security middleware
- **Webhook signature validation** for external integrations
## Important Implementation Details
### WhatsApp Instance Management
- Each WhatsApp connection is an "instance" with unique name
- Instance data stored in database with connection state
- Session persistence in database or file system (configurable)
- Automatic reconnection handling with exponential backoff
### Message Queue Architecture
- Supports RabbitMQ, Amazon SQS, and WebSocket for events
- Event types: message.received, message.sent, connection.update, etc.
- Configurable per instance which events to send
### Media Handling
- Local storage or S3/Minio for media files
- Automatic media download from WhatsApp
- Media URL generation for external access
- Support for audio transcription via OpenAI
### Multi-tenancy Support
- Instance isolation at database level
- Separate webhook configurations per instance
- Independent integration settings per instance
## Environment Configuration
Key environment variables are defined in `.env.example`. The system uses a strongly-typed configuration system via `src/config/env.config.ts`.
Critical configurations:
- `DATABASE_PROVIDER`: postgresql or mysql
- `DATABASE_CONNECTION_URI`: Database connection string
- `AUTHENTICATION_API_KEY`: Global API authentication
- `REDIS_ENABLED`: Enable Redis cache
- `RABBITMQ_ENABLED`/`SQS_ENABLED`: Message queue options
## Development Guidelines
The project follows comprehensive development standards defined in `.cursor/rules/`:
### Core Principles
- **Always respond in Portuguese (PT-BR)** for user communication
- **Follow established architecture patterns** (Service Layer, RouterBroker, etc.)
- **Robust error handling** with retry logic and graceful degradation
- **Multi-database compatibility** (PostgreSQL and MySQL)
- **Security-first approach** with input validation and rate limiting
- **Performance optimizations** with Redis caching and connection pooling
### Code Standards
- **TypeScript strict mode** with full type coverage
- **JSONSchema7** for input validation (not class-validator)
- **Conventional Commits** enforced by commitlint
- **ESLint + Prettier** for code formatting
- **Service Object pattern** for business logic
- **RouterBroker pattern** for route handling with `dataValidate`
### Architecture Patterns
- **Multi-tenant isolation** at database and instance level
- **Event-driven communication** with EventEmitter2
- **Microservices integration** pattern for external services
- **Connection pooling** and lifecycle management
- **Caching strategy** with Redis primary and Node-cache fallback
## Testing Approach
Currently, the project has minimal formal testing infrastructure:
- **Manual testing** is the primary approach
- **Integration testing** in development environment
- **No unit test suite** currently implemented
- Test files can be placed in `test/` directory as `*.test.ts`
- Run `npm test` for watch mode development testing
### Recommended Testing Strategy
- Focus on **critical business logic** in services
- **Mock external dependencies** (WhatsApp APIs, databases)
- **Integration tests** for API endpoints
- **Manual testing** for WhatsApp connection flows
## Deployment Considerations
- Docker support with `Dockerfile` and `docker-compose.yaml`
- Graceful shutdown handling for connections
- Health check endpoints for monitoring
- Sentry integration for error tracking
- Telemetry for usage analytics (non-sensitive data only)

View File

@@ -1,174 +0,0 @@
# Server URL - Set your application url
SERVER_URL=http://localhost:8080
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
CORS_ORIGIN=*
CORS_METHODS=POST,GET,PUT,DELETE
CORS_CREDENTIALS=true
# Determine the logs to be displayed
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS
LOG_COLOR=true
# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace"
LOG_BAILEYS=error
# Determine how long the instance should be deleted from memory in case of no connection.
# Default time: 5 minutes
# If you don't even want an expiration, enter the value false
DEL_INSTANCE=false
DEL_TEMP_INSTANCES=true # Delete instances with status closed on start
# Temporary data storage
STORE_MESSAGES=true
STORE_MESSAGE_UP=true
STORE_CONTACTS=true
STORE_CHATS=true
# Set Store Interval in Seconds (7200 = 2h)
CLEAN_STORE_CLEANING_INTERVAL=7200
CLEAN_STORE_MESSAGES=true
CLEAN_STORE_MESSAGE_UP=true
CLEAN_STORE_CONTACTS=true
CLEAN_STORE_CHATS=true
# Permanent data storage
DATABASE_ENABLED=false
DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true
DATABASE_CONNECTION_DB_PREFIX_NAME=evdocker
# Choose the data you want to save in the application's database or store
DATABASE_SAVE_DATA_INSTANCE=false
DATABASE_SAVE_DATA_NEW_MESSAGE=false
DATABASE_SAVE_MESSAGE_UPDATE=false
DATABASE_SAVE_DATA_CONTACTS=false
DATABASE_SAVE_DATA_CHATS=false
RABBITMQ_ENABLED=false
RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672
RABBITMQ_EXCHANGE_NAME=evolution_exchange
RABBITMQ_GLOBAL_ENABLED=false
RABBITMQ_EVENTS_APPLICATION_STARTUP=false
RABBITMQ_EVENTS_QRCODE_UPDATED=true
RABBITMQ_EVENTS_MESSAGES_SET=true
RABBITMQ_EVENTS_MESSAGES_UPSERT=true
RABBITMQ_EVENTS_MESSAGES_UPDATE=true
RABBITMQ_EVENTS_MESSAGES_DELETE=true
RABBITMQ_EVENTS_SEND_MESSAGE=true
RABBITMQ_EVENTS_CONTACTS_SET=true
RABBITMQ_EVENTS_CONTACTS_UPSERT=true
RABBITMQ_EVENTS_CONTACTS_UPDATE=true
RABBITMQ_EVENTS_PRESENCE_UPDATE=true
RABBITMQ_EVENTS_CHATS_SET=true
RABBITMQ_EVENTS_CHATS_UPSERT=true
RABBITMQ_EVENTS_CHATS_UPDATE=true
RABBITMQ_EVENTS_CHATS_DELETE=true
RABBITMQ_EVENTS_GROUPS_UPSERT=true
RABBITMQ_EVENTS_GROUPS_UPDATE=true
RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
RABBITMQ_EVENTS_CONNECTION_UPDATE=true
RABBITMQ_EVENTS_LABELS_EDIT=true
RABBITMQ_EVENTS_LABELS_ASSOCIATION=true
RABBITMQ_EVENTS_CALL=true
RABBITMQ_EVENTS_TYPEBOT_START=false
RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false
WEBSOCKET_ENABLED=false
WEBSOCKET_GLOBAL_EVENTS=false
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com
WA_BUSINESS_VERSION=v18.0
WA_BUSINESS_LANGUAGE=pt_BR
SQS_ENABLED=false
SQS_ACCESS_KEY_ID=
SQS_SECRET_ACCESS_KEY=
SQS_ACCOUNT_ID=
SQS_REGION=
# Global Webhook Settings
# Each instance's Webhook URL and events will be requested at the time it is created
## Define a global webhook that will listen for enabled events from all instances
WEBHOOK_GLOBAL_URL=''
WEBHOOK_GLOBAL_ENABLED=false
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
## Set the events you want to hear
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true
WEBHOOK_EVENTS_CONTACTS_SET=true
WEBHOOK_EVENTS_CONTACTS_UPSERT=true
WEBHOOK_EVENTS_CONTACTS_UPDATE=true
WEBHOOK_EVENTS_PRESENCE_UPDATE=true
WEBHOOK_EVENTS_CHATS_SET=true
WEBHOOK_EVENTS_CHATS_UPSERT=true
WEBHOOK_EVENTS_CHATS_UPDATE=true
WEBHOOK_EVENTS_CHATS_DELETE=true
WEBHOOK_EVENTS_GROUPS_UPSERT=true
WEBHOOK_EVENTS_GROUPS_UPDATE=true
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_LABELS_EDIT=true
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
WEBHOOK_EVENTS_CALL=true
# This event fires every time a new token is requested via the refresh route
WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
# This events is used with Typebot
WEBHOOK_EVENTS_TYPEBOT_START=false
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
# This event is used with Chama AI
WEBHOOK_EVENTS_CHAMA_AI_ACTION=false
# This event is used to send errors
WEBHOOK_EVENTS_ERRORS=false
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
# Name that will be displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI
# Browser Name = Chrome | Firefox | Edge | Opera | Safari
CONFIG_SESSION_PHONE_NAME=Chrome
# Set qrcode display limit
QRCODE_LIMIT=30
QRCODE_COLOR='#198754'
# old | latest
TYPEBOT_API_VERSION=latest
TYPEBOT_KEEP_OPEN=false
#Chatwoot
# If you leave this option as false, when deleting the message for everyone on WhatsApp, it will not be deleted on Chatwoot.
CHATWOOT_MESSAGE_DELETE=false # false | true
# If you leave this option as true, when sending a message in Chatwoot, the client's last message will be marked as read on WhatsApp.
CHATWOOT_MESSAGE_READ=false # false | true
# This db connection is used to import messages from whatsapp to chatwoot database
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgres://user:password@hostname:port/dbname?sslmode=disable
CHATWOOT_IMPORT_DATABASE_PLACEHOLDER_MEDIA_MESSAGE=true
CACHE_REDIS_ENABLED=false
CACHE_REDIS_URI=redis://redis:6379
CACHE_REDIS_PREFIX_KEY=evolution
CACHE_REDIS_TTL=604800
CACHE_REDIS_SAVE_INSTANCES=false
CACHE_LOCAL_ENABLED=false
CACHE_LOCAL_TTL=604800
# Defines an authentication type for the api
# We recommend using the apikey because it will allow you to use a custom token,
# if you use jwt, a random token will be generated and may be expired and you will have to generate a new token
# jwt or 'apikey'
AUTHENTICATION_TYPE=apikey
## Define a global apikey to access all instances.
### OBS: This key must be inserted in the request header to create an instance.
AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
## Set the secret key to encrypt and decrypt your token and its expiration time
# seconds - 3600s ===1h | zero (0) - never expires
AUTHENTICATION_JWT_EXPIRIN_IN=0
AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`'
LANGUAGE=en # pt-BR, en

View File

@@ -1,22 +0,0 @@
version: '3.3'
services:
api:
container_name: evolution_api
image: atendai/evolution-api
restart: always
ports:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
env_file:
- .env
command: ['node', './dist/src/main.js']
expose:
- 8080
volumes:
evolution_instances:
evolution_store:

View File

@@ -1,119 +0,0 @@
# Server URL - Set your application url
SERVER_URL='http://localhost:8080'
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
CORS_ORIGIN='*'
CORS_METHODS='POST,GET,PUT,DELETE'
CORS_CREDENTIALS=true
# Determine the logs to be displayed
LOG_LEVEL='ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS'
LOG_COLOR=true
# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace"
LOG_BAILEYS=error
# Determine how long the instance should be deleted from memory in case of no connection.
# Default time: 5 minutes
# If you don't even want an expiration, enter the value false
DEL_INSTANCE=false
DEL_TEMP_INSTANCES=true # Delete instances with status closed on start
# Temporary data storage
STORE_MESSAGES=true
STORE_MESSAGE_UP=true
STORE_CONTACTS=true
STORE_CHATS=true
# Set Store Interval in Seconds (7200 = 2h)
CLEAN_STORE_CLEANING_INTERVAL=7200
CLEAN_STORE_MESSAGES=true
CLEAN_STORE_MESSAGE_UP=true
CLEAN_STORE_CONTACTS=true
CLEAN_STORE_CHATS=true
# Permanent data storage
DATABASE_ENABLED=true
DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin &
readPreference=primary &
ssl=false &
directConnection=true
DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
# Choose the data you want to save in the application's database or store
DATABASE_SAVE_DATA_INSTANCE=false
DATABASE_SAVE_DATA_NEW_MESSAGE=false
DATABASE_SAVE_MESSAGE_UPDATE=false
DATABASE_SAVE_DATA_CONTACTS=false
DATABASE_SAVE_DATA_CHATS=false
# Global Webhook Settings
# Each instance's Webhook URL and events will be requested at the time it is created
## Define a global webhook that will listen for enabled events from all instances
WEBHOOK_GLOBAL_URL=''
WEBHOOK_GLOBAL_ENABLED=false
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
## Set the events you want to hear
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true
WEBHOOK_EVENTS_CONTACTS_SET=true
WEBHOOK_EVENTS_CONTACTS_UPSERT=true
WEBHOOK_EVENTS_CONTACTS_UPDATE=true
WEBHOOK_EVENTS_PRESENCE_UPDATE=true
WEBHOOK_EVENTS_CHATS_SET=true
WEBHOOK_EVENTS_CHATS_UPSERT=true
WEBHOOK_EVENTS_CHATS_UPDATE=true
WEBHOOK_EVENTS_CHATS_DELETE=true
WEBHOOK_EVENTS_GROUPS_UPSERT=true
WEBHOOK_EVENTS_GROUPS_UPDATE=true
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_LABELS_EDIT=true
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
# This event fires every time a new token is requested via the refresh route
WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
# Name that will be displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT='Evolution API'
# Browser Name = chrome | firefox | edge | opera | safari
CONFIG_SESSION_PHONE_NAME=chrome
# Set qrcode display limit
QRCODE_LIMIT=30
CACHE_REDIS_ENABLED=false
CACHE_REDIS_URI=redis://redis:6379
CACHE_REDIS_PREFIX_KEY=evolution
CACHE_REDIS_TTL=604800
CACHE_REDIS_SAVE_INSTANCES=false
CACHE_LOCAL_ENABLED=false
CACHE_LOCAL_TTL=604800
# Defines an authentication type for the api
# We recommend using the apikey because it will allow you to use a custom token,
# if you use jwt, a random token will be generated and may be expired and you will have to generate a new token
# jwt or 'apikey'
AUTHENTICATION_TYPE='apikey'
## Define a global apikey to access all instances.
### OBS: This key must be inserted in the request header to create an instance.
AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976'
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
## Set the secret key to encrypt and decrypt your token and its expiration time
# seconds - 3600s ===1h | zero (0) - never expires
AUTHENTICATION_JWT_EXPIRIN_IN=0
AUTHENTICATION_JWT_SECRET='L0YWtjb2w554WFqPG'
# Set the instance name and webhook url to create an instance in init the application
# With this option activated, you work with a url per webhook event, respecting the local url and the name of each event
# container or server
AUTHENTICATION_INSTANCE_MODE=server
# if you are using container mode, set the container name and the webhook url to default instance
AUTHENTICATION_INSTANCE_NAME=evolution
AUTHENTICATION_INSTANCE_WEBHOOK_URL=''
AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1
AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456
AUTHENTICATION_INSTANCE_CHATWOOT_URL=''

View File

@@ -1,91 +0,0 @@
version: '3.3'
services:
mongodb:
container_name: mongodb
image: mongo
restart: on-failure
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
- PUID=1000
- PGID=1000
volumes:
- evolution_mongodb_data:/data/db
- evolution_mongodb_configdb:/data/configdb
expose:
- 27017
mongo-express:
container_name: mongodb-express
image: mongo-express
restart: on-failure
ports:
- 8081:8081
depends_on:
- mongodb
environment:
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: root
links:
- mongodb
redis:
container_name: redis
image: redis:latest
restart: on-failure
ports:
- 6379:6379
command: >
redis-server
--port 6379
--appendonly yes
volumes:
- evolution_redis:/data
rebrow:
container_name: rebrow
image: marian/rebrow
restart: on-failure
depends_on:
- redis
ports:
- 5001:5001
links:
- redis
api:
container_name: evolution_api
image: atendai/evolution-api
restart: always
depends_on:
- mongodb
- redis
ports:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
env_file:
- .env
command: ['node', './dist/src/main.js']
expose:
- 8080
volumes:
evolution_mongodb_data:
evolution_mongodb_configdb:
evolution_redis:
evolution_instances:
evolution_store:
networks:
evolution-net:
external: true

View File

@@ -0,0 +1,51 @@
version: '3.3'
services:
zookeeper:
container_name: zookeeper
image: confluentinc/cp-zookeeper:7.5.0
environment:
- ZOOKEEPER_CLIENT_PORT=2181
- ZOOKEEPER_TICK_TIME=2000
- ZOOKEEPER_SYNC_LIMIT=2
volumes:
- zookeeper_data:/var/lib/zookeeper/
ports:
- 2181:2181
kafka:
container_name: kafka
image: confluentinc/cp-kafka:7.5.0
depends_on:
- zookeeper
environment:
- KAFKA_BROKER_ID=1
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,OUTSIDE:PLAINTEXT
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092,OUTSIDE://host.docker.internal:9094
- KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
- KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
- KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1
- KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1
- KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS=0
- KAFKA_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_LOG_RETENTION_HOURS=168
- KAFKA_LOG_SEGMENT_BYTES=1073741824
- KAFKA_LOG_RETENTION_CHECK_INTERVAL_MS=300000
- KAFKA_COMPRESSION_TYPE=gzip
ports:
- 29092:29092
- 9092:9092
- 9094:9094
volumes:
- kafka_data:/var/lib/kafka/data
volumes:
zookeeper_data:
kafka_data:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -0,0 +1,31 @@
version: '3.3'
services:
minio:
container_name: minio
image: quay.io/minio/minio
networks:
- evolution-net
command: server /data --console-address ":9001"
restart: always
ports:
- 5432:5432
environment:
- MINIO_ROOT_USER=USER
- MINIO_ROOT_PASSWORD=PASSWORD
- MINIO_BROWSER_REDIRECT_URL=http:/localhost:9001
- MINIO_SERVER_URL=http://localhost:9000
volumes:
- minio_data:/data
expose:
- 9000
- 9001
volumes:
minio_data:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -1,42 +0,0 @@
version: '3.3'
services:
mongodb:
container_name: mongodb
image: mongo
restart: always
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
- PUID=1000
- PGID=1000
volumes:
- evolution_mongodb_data:/data/db
- evolution_mongodb_configdb:/data/configdb
expose:
- 27017
mongo-express:
image: mongo-express
environment:
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: root
ports:
- 8081:8081
links:
- mongodb
volumes:
evolution_mongodb_data:
evolution_mongodb_configdb:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -0,0 +1,27 @@
version: '3.3'
services:
mysql:
container_name: mysql
image: percona/percona-server:8.0
networks:
- evolution-net
restart: always
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- TZ=America/Bahia
volumes:
- mysql_data:/var/lib/mysql
expose:
- 3306
volumes:
mysql_data:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -0,0 +1,42 @@
version: '3.3'
services:
postgres:
container_name: postgres
image: postgres:15
networks:
- evolution-net
command: ["postgres", "-c", "max_connections=1000"]
restart: always
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=PASSWORD
volumes:
- postgres_data:/var/lib/postgresql/data
expose:
- 5432
pgadmin:
image: dpage/pgadmin4:latest
networks:
- evolution-net
environment:
- PGADMIN_DEFAULT_EMAIL=EMAIL
- PGADMIN_DEFAULT_PASSWORD=PASSWORD
volumes:
- pgadmin_data:/var/lib/pgadmin
ports:
- 4000:80
links:
- postgres
volumes:
postgres_data:
pgadmin_data:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -0,0 +1,25 @@
version: '3.3'
services:
rabbitmq:
container_name: rabbitmq
image: rabbitmq:management
environment:
- RABBITMQ_ERLANG_COOKIE=33H2CdkzF5WrnJ4ud6nkUdRTKXvbCHeFjvVL71p
- RABBITMQ_DEFAULT_VHOST=default
- RABBITMQ_DEFAULT_USER=USER
- RABBITMQ_DEFAULT_PASS=PASSWORD
volumes:
- rabbitmq_data:/var/lib/rabbitmq/
ports:
- 5672:5672
- 15672:15672
volumes:
rabbitmq_data:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -3,6 +3,8 @@ version: '3.3'
services:
redis:
image: redis:latest
networks:
- evolution-net
container_name: redis
command: >
redis-server --port 6379 --appendonly yes

View File

@@ -0,0 +1,32 @@
#!/bin/bash
source ./Docker/scripts/env_functions.sh
if [ "$DOCKER_ENV" != "true" ]; then
export_env_vars
fi
if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" || "$DATABASE_PROVIDER" == "psql_bouncer" ]]; then
export DATABASE_URL
echo "Deploying migrations for $DATABASE_PROVIDER"
echo "Database URL: $DATABASE_URL"
# rm -rf ./prisma/migrations
# cp -r ./prisma/$DATABASE_PROVIDER-migrations ./prisma/migrations
npm run db:deploy
if [ $? -ne 0 ]; then
echo "Migration failed"
exit 1
else
echo "Migration succeeded"
fi
npm run db:generate
if [ $? -ne 0 ]; then
echo "Prisma generate failed"
exit 1
else
echo "Prisma generate succeeded"
fi
else
echo "Error: Database provider $DATABASE_PROVIDER invalid."
exit 1
fi

18
Docker/scripts/env_functions.sh Executable file
View File

@@ -0,0 +1,18 @@
export_env_vars() {
if [ -f .env ]; then
while IFS='=' read -r key value; do
if [[ -z "$key" || "$key" =~ ^\s*# || -z "$value" ]]; then
continue
fi
key=$(echo "$key" | tr -d '[:space:]')
value=$(echo "$value" | tr -d '[:space:]')
value=$(echo "$value" | tr -d "'" | tr -d "\"")
export "$key=$value"
done < .env
else
echo ".env file not found"
exit 1
fi
}

View File

@@ -0,0 +1,23 @@
#!/bin/bash
source ./Docker/scripts/env_functions.sh
if [ "$DOCKER_ENV" != "true" ]; then
export_env_vars
fi
if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" || "$DATABASE_PROVIDER" == "psql_bouncer" ]]; then
export DATABASE_URL
echo "Generating database for $DATABASE_PROVIDER"
echo "Database URL: $DATABASE_URL"
npm run db:generate
if [ $? -ne 0 ]; then
echo "Prisma generate failed"
exit 1
else
echo "Prisma generate succeeded"
fi
else
echo "Error: Database provider $DATABASE_PROVIDER invalid."
exit 1
fi

View File

@@ -0,0 +1,146 @@
version: "3.7"
services:
evolution_v2:
image: evoapicloud/evolution-api:v2.3.6
volumes:
- evolution_instances:/evolution/instances
networks:
- network_public
environment:
- SERVER_URL=https://evo2.site.com
- DEL_INSTANCE=false
- DATABASE_PROVIDER=postgresql
- DATABASE_CONNECTION_URI=postgresql://postgres:SENHA@postgres:5432/evolution
- DATABASE_SAVE_DATA_INSTANCE=true
- DATABASE_SAVE_DATA_NEW_MESSAGE=true
- DATABASE_SAVE_MESSAGE_UPDATE=true
- DATABASE_SAVE_DATA_CONTACTS=true
- DATABASE_SAVE_DATA_CHATS=true
- DATABASE_SAVE_DATA_LABELS=true
- DATABASE_SAVE_DATA_HISTORIC=true
- DATABASE_CONNECTION_CLIENT_NAME=evolution_v2
- RABBITMQ_ENABLED=false
- RABBITMQ_URI=amqp://admin:admin@rabbitmq:5672/default
- RABBITMQ_EXCHANGE_NAME=evolution_v2
- RABBITMQ_GLOBAL_ENABLED=false
- RABBITMQ_EVENTS_APPLICATION_STARTUP=false
- RABBITMQ_EVENTS_INSTANCE_CREATE=false
- RABBITMQ_EVENTS_INSTANCE_DELETE=false
- RABBITMQ_EVENTS_QRCODE_UPDATED=false
- RABBITMQ_EVENTS_MESSAGES_SET=false
- RABBITMQ_EVENTS_MESSAGES_UPSERT=true
- RABBITMQ_EVENTS_MESSAGES_EDITED=false
- RABBITMQ_EVENTS_MESSAGES_UPDATE=false
- RABBITMQ_EVENTS_MESSAGES_DELETE=false
- RABBITMQ_EVENTS_SEND_MESSAGE=false
- RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE=false
- RABBITMQ_EVENTS_CONTACTS_SET=false
- RABBITMQ_EVENTS_CONTACTS_UPSERT=false
- RABBITMQ_EVENTS_CONTACTS_UPDATE=false
- RABBITMQ_EVENTS_PRESENCE_UPDATE=false
- RABBITMQ_EVENTS_CHATS_SET=false
- RABBITMQ_EVENTS_CHATS_UPSERT=false
- RABBITMQ_EVENTS_CHATS_UPDATE=false
- RABBITMQ_EVENTS_CHATS_DELETE=false
- RABBITMQ_EVENTS_GROUPS_UPSERT=false
- RABBITMQ_EVENTS_GROUP_UPDATE=false
- RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=false
- RABBITMQ_EVENTS_CONNECTION_UPDATE=true
- RABBITMQ_EVENTS_CALL=false
- RABBITMQ_EVENTS_TYPEBOT_START=false
- RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false
- SQS_ENABLED=false
- SQS_ACCESS_KEY_ID=
- SQS_SECRET_ACCESS_KEY=
- SQS_ACCOUNT_ID=
- SQS_REGION=
- WEBSOCKET_ENABLED=false
- WEBSOCKET_GLOBAL_EVENTS=false
- WA_BUSINESS_TOKEN_WEBHOOK=evolution
- WA_BUSINESS_URL=https://graph.facebook.com
- WA_BUSINESS_VERSION=v20.0
- WA_BUSINESS_LANGUAGE=pt_BR
- WEBHOOK_GLOBAL_URL=''
- WEBHOOK_GLOBAL_ENABLED=false
- WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
- WEBHOOK_EVENTS_APPLICATION_STARTUP=false
- WEBHOOK_EVENTS_QRCODE_UPDATED=true
- WEBHOOK_EVENTS_MESSAGES_SET=true
- WEBHOOK_EVENTS_MESSAGES_UPSERT=true
- WEBHOOK_EVENTS_MESSAGES_EDITED=true
- WEBHOOK_EVENTS_MESSAGES_UPDATE=true
- WEBHOOK_EVENTS_MESSAGES_DELETE=true
- WEBHOOK_EVENTS_SEND_MESSAGE=true
- WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=true
- WEBHOOK_EVENTS_CONTACTS_SET=true
- WEBHOOK_EVENTS_CONTACTS_UPSERT=true
- WEBHOOK_EVENTS_CONTACTS_UPDATE=true
- WEBHOOK_EVENTS_PRESENCE_UPDATE=true
- WEBHOOK_EVENTS_CHATS_SET=true
- WEBHOOK_EVENTS_CHATS_UPSERT=true
- WEBHOOK_EVENTS_CHATS_UPDATE=true
- WEBHOOK_EVENTS_CHATS_DELETE=true
- WEBHOOK_EVENTS_GROUPS_UPSERT=true
- WEBHOOK_EVENTS_GROUPS_UPDATE=true
- WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
- WEBHOOK_EVENTS_CONNECTION_UPDATE=true
- WEBHOOK_EVENTS_LABELS_EDIT=true
- WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
- WEBHOOK_EVENTS_CALL=true
- WEBHOOK_EVENTS_TYPEBOT_START=false
- WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
- WEBHOOK_EVENTS_ERRORS=false
- WEBHOOK_EVENTS_ERRORS_WEBHOOK=
- CONFIG_SESSION_PHONE_CLIENT=Evolution API V2
- CONFIG_SESSION_PHONE_NAME=Chrome
- QRCODE_LIMIT=30
- OPENAI_ENABLED=true
- DIFY_ENABLED=true
- TYPEBOT_ENABLED=true
- TYPEBOT_API_VERSION=latest
- CHATWOOT_ENABLED=true
- CHATWOOT_MESSAGE_READ=true
- CHATWOOT_MESSAGE_DELETE=true
- CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://postgres:PASSWORD@postgres:5432/chatwoot?sslmode=disable
- CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true
- CACHE_REDIS_ENABLED=true
- CACHE_REDIS_URI=redis://evo_redis:6379/1
- CACHE_REDIS_PREFIX_KEY=evolution_v2
- CACHE_REDIS_SAVE_INSTANCES=false
- CACHE_LOCAL_ENABLED=false
- S3_ENABLED=true
- S3_ACCESS_KEY=
- S3_SECRET_KEY=
- S3_BUCKET=evolution
- S3_PORT=443
- S3_ENDPOINT=files.site.com
- S3_USE_SSL=true
- AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11
- AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
- LANGUAGE=en
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.hostname == evolution-manager
labels:
- traefik.enable=true
- traefik.http.routers.evolution_v2.rule=Host(`evo2.site.com`)
- traefik.http.routers.evolution_v2.entrypoints=websecure
- traefik.http.routers.evolution_v2.tls.certresolver=letsencryptresolver
- traefik.http.routers.evolution_v2.priority=1
- traefik.http.routers.evolution_v2.service=evolution_v2
- traefik.http.services.evolution_v2.loadbalancer.server.port=8080
- traefik.http.services.evolution_v2.loadbalancer.passHostHeader=true
volumes:
evolution_instances:
external: true
name: evolution_v2_data
networks:
network_public:
external: true
name: network_public

View File

@@ -1,182 +1,60 @@
FROM node:20.7.0-alpine AS builder
FROM node:24-alpine AS builder
LABEL version="1.8.0" description="Api to control whatsapp features through http requests."
RUN apk update && \
apk add --no-cache git ffmpeg wget curl bash openssl
LABEL version="2.3.1" description="Api to control whatsapp features through http requests."
LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes"
LABEL contact="contato@agenciadgcode.com"
RUN apk update && apk upgrade && \
apk add --no-cache git tzdata ffmpeg wget curl
LABEL contact="contato@evolution-api.com"
WORKDIR /evolution
COPY ./package.json .
COPY ./package*.json ./
COPY ./tsconfig.json ./
COPY ./tsup.config.ts ./
RUN npm install
RUN npm ci --silent
COPY . .
COPY ./src ./src
COPY ./public ./public
COPY ./prisma ./prisma
COPY ./manager ./manager
COPY ./.env.example ./.env
COPY ./runWithProvider.js ./
COPY ./Docker ./Docker
RUN chmod +x ./Docker/scripts/* && dos2unix ./Docker/scripts/*
RUN ./Docker/scripts/generate_database.sh
RUN npm run build
FROM node:20.7.0-alpine AS final
FROM node:24-alpine AS final
RUN apk update && \
apk add tzdata ffmpeg bash openssl
ENV TZ=America/Sao_Paulo
ENV DOCKER_ENV=true
ENV SERVER_TYPE=http
ENV SERVER_PORT=8080
ENV SERVER_URL=http://localhost:8080
ENV CORS_ORIGIN=*
ENV CORS_METHODS=POST,GET,PUT,DELETE
ENV CORS_CREDENTIALS=true
ENV LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS
ENV LOG_COLOR=true
ENV LOG_BAILEYS=error
ENV DEL_INSTANCE=false
ENV DEL_TEMP_INSTANCES=true
ENV STORE_MESSAGES=true
ENV STORE_MESSAGE_UP=true
ENV STORE_CONTACTS=true
ENV STORE_CHATS=true
ENV CLEAN_STORE_CLEANING_INTERVAL=7200
ENV CLEAN_STORE_MESSAGES=true
ENV CLEAN_STORE_MESSAGE_UP=true
ENV CLEAN_STORE_CONTACTS=true
ENV CLEAN_STORE_CHATS=true
ENV DATABASE_ENABLED=false
ENV DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true
ENV DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
ENV DATABASE_SAVE_DATA_INSTANCE=false
ENV DATABASE_SAVE_DATA_NEW_MESSAGE=false
ENV DATABASE_SAVE_MESSAGE_UPDATE=false
ENV DATABASE_SAVE_DATA_CONTACTS=false
ENV DATABASE_SAVE_DATA_CHATS=false
ENV RABBITMQ_ENABLED=false
ENV RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672
ENV RABBITMQ_EXCHANGE_NAME=evolution_exchange
ENV RABBITMQ_GLOBAL_ENABLED=false
ENV RABBITMQ_EVENTS_APPLICATION_STARTUP=false
ENV RABBITMQ_EVENTS_INSTANCE_CREATE=false
ENV RABBITMQ_EVENTS_INSTANCE_DELETE=false
ENV RABBITMQ_EVENTS_QRCODE_UPDATED=true
ENV RABBITMQ_EVENTS_MESSAGES_SET=true
ENV RABBITMQ_EVENTS_MESSAGES_UPSERT=true
ENV RABBITMQ_EVENTS_MESSAGES_UPDATE=true
ENV RABBITMQ_EVENTS_MESSAGES_DELETE=true
ENV RABBITMQ_EVENTS_SEND_MESSAGE=true
ENV RABBITMQ_EVENTS_CONTACTS_SET=true
ENV RABBITMQ_EVENTS_CONTACTS_UPSERT=true
ENV RABBITMQ_EVENTS_CONTACTS_UPDATE=true
ENV RABBITMQ_EVENTS_PRESENCE_UPDATE=true
ENV RABBITMQ_EVENTS_CHATS_SET=true
ENV RABBITMQ_EVENTS_CHATS_UPSERT=true
ENV RABBITMQ_EVENTS_CHATS_UPDATE=true
ENV RABBITMQ_EVENTS_CHATS_DELETE=true
ENV RABBITMQ_EVENTS_GROUPS_UPSERT=true
ENV RABBITMQ_EVENTS_GROUPS_UPDATE=true
ENV RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
ENV RABBITMQ_EVENTS_CONNECTION_UPDATE=true
ENV RABBITMQ_EVENTS_LABELS_EDIT=true
ENV RABBITMQ_EVENTS_LABELS_ASSOCIATION=true
ENV RABBITMQ_EVENTS_CALL=true
ENV RABBITMQ_EVENTS_TYPEBOT_START=false
ENV RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false
ENV WEBSOCKET_ENABLED=false
ENV WEBSOCKET_GLOBAL_EVENTS=false
ENV WA_BUSINESS_TOKEN_WEBHOOK=evolution
ENV WA_BUSINESS_URL=https://graph.facebook.com
ENV WA_BUSINESS_VERSION=v18.0
ENV WA_BUSINESS_LANGUAGE=pt_BR
ENV SQS_ENABLED=false
ENV SQS_ACCESS_KEY_ID=
ENV SQS_SECRET_ACCESS_KEY=
ENV SQS_ACCOUNT_ID=
ENV SQS_REGION=
ENV WEBHOOK_GLOBAL_URL=
ENV WEBHOOK_GLOBAL_ENABLED=false
ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
ENV WEBHOOK_EVENTS_APPLICATION_STARTUP=false
ENV WEBHOOK_EVENTS_INSTANCE_CREATE=false
ENV WEBHOOK_EVENTS_INSTANCE_DELETE=false
ENV WEBHOOK_EVENTS_QRCODE_UPDATED=true
ENV WEBHOOK_EVENTS_MESSAGES_SET=true
ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=true
ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=true
ENV WEBHOOK_EVENTS_MESSAGES_DELETE=true
ENV WEBHOOK_EVENTS_SEND_MESSAGE=true
ENV WEBHOOK_EVENTS_CONTACTS_SET=true
ENV WEBHOOK_EVENTS_CONTACTS_UPSERT=true
ENV WEBHOOK_EVENTS_CONTACTS_UPDATE=true
ENV WEBHOOK_EVENTS_PRESENCE_UPDATE=true
ENV WEBHOOK_EVENTS_CHATS_SET=true
ENV WEBHOOK_EVENTS_CHATS_UPSERT=true
ENV WEBHOOK_EVENTS_CHATS_UPDATE=true
ENV WEBHOOK_EVENTS_CHATS_DELETE=true
ENV WEBHOOK_EVENTS_GROUPS_UPSERT=true
ENV WEBHOOK_EVENTS_GROUPS_UPDATE=true
ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true
ENV WEBHOOK_EVENTS_LABELS_EDIT=true
ENV WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
ENV WEBHOOK_EVENTS_CALL=true
ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
ENV WEBHOOK_EVENTS_TYPEBOT_START=false
ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
ENV WEBHOOK_EVENTS_CHAMA_AI_ACTION=false
ENV WEBHOOK_EVENTS_ERRORS=false
ENV WEBHOOK_EVENTS_ERRORS_WEBHOOK=
ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI
ENV CONFIG_SESSION_PHONE_NAME=Chrome
ENV QRCODE_LIMIT=30
ENV QRCODE_COLOR=#198754
ENV TYPEBOT_API_VERSION=latest
ENV CACHE_REDIS_ENABLED=false
ENV CACHE_REDIS_URI=redis://redis:6379
ENV CACHE_REDIS_PREFIX_KEY=evolution
ENV CACHE_REDIS_TTL=604800
ENV CACHE_REDIS_SAVE_INSTANCES=false
ENV CACHE_LOCAL_ENABLED=false
ENV CACHE_LOCAL_TTL=604800
ENV AUTHENTICATION_TYPE=apikey
ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
ENV AUTHENTICATION_JWT_EXPIRIN_IN=0
ENV AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`'
ENV AUTHENTICATION_INSTANCE_MODE=server
ENV AUTHENTICATION_INSTANCE_NAME=evolution
ENV AUTHENTICATION_INSTANCE_WEBHOOK_URL=<url>
ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1
ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456
ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL=<url>
WORKDIR /evolution
COPY --from=builder /evolution .
COPY --from=builder /evolution/package.json ./package.json
COPY --from=builder /evolution/package-lock.json ./package-lock.json
CMD [ "node", "./dist/src/main.js" ]
COPY --from=builder /evolution/node_modules ./node_modules
COPY --from=builder /evolution/dist ./dist
COPY --from=builder /evolution/prisma ./prisma
COPY --from=builder /evolution/manager ./manager
COPY --from=builder /evolution/public ./public
COPY --from=builder /evolution/.env ./.env
COPY --from=builder /evolution/Docker ./Docker
COPY --from=builder /evolution/runWithProvider.js ./runWithProvider.js
COPY --from=builder /evolution/tsup.config.ts ./tsup.config.ts
ENV DOCKER_ENV=true
EXPOSE 8080
ENTRYPOINT ["/bin/bash", "-c", ". ./Docker/scripts/deploy_database.sh && npm run start:prod" ]

19
Dockerfile.metrics Normal file
View File

@@ -0,0 +1,19 @@
FROM evoapicloud/evolution-api:latest AS base
WORKDIR /evolution
# Copiamos apenas o necessário para recompilar o dist com as mudanças locais
COPY tsconfig.json tsup.config.ts package.json ./
COPY src ./src
# Recompila usando os node_modules já presentes na imagem base
RUN npm run build
# Runtime final: reaproveita a imagem oficial e apenas sobrepõe o dist
FROM evoapicloud/evolution-api:latest AS final
WORKDIR /evolution
COPY --from=base /evolution/dist ./dist
ENV PROMETHEUS_METRICS=true
# Entrada original da imagem oficial já sobe o app em /evolution

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,6 @@
{
"name": "[Evolution] Criador de Inbox",
"name": "criador_de_inbox_evo_v2.0",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "inbox_whatsapp",
"options": {}
},
"id": "8205b929-73e9-456a-9b0d-e1474991663a",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
320,
300
],
"webhookId": "cf37002d-3869-4bb1-af3a-739fdd3c1756"
},
{
"parameters": {
"method": "POST",
@@ -39,108 +23,140 @@
"parameters": [
{
"name": "instanceName",
"value": "={{ $json.instance_name }}"
"value": "={{ $json.instanceName }}"
},
{
"name": "qrcode",
"value": "={{ $json.qrcode }}"
},
{
"name": "chatwoot_account_id",
"value": "={{ $json.chatwoot_account_id }}"
"name": "chatwootAccountId",
"value": "={{ $json.chatwootAccountId }}"
},
{
"name": "chatwoot_token",
"value": "={{ $json.chatwoot_token }}"
"name": "chatwootToken",
"value": "={{ $json.chatwootToken }}"
},
{
"name": "chatwoot_url",
"value": "={{ $json.chatwoot_url }}"
"name": "chatwootUrl",
"value": "={{ $json.chatwootUrl }}"
},
{
"name": "chatwoot_sign_msg",
"value": "={{ $json.chatwoot_sign_msg }}"
"name": "chatwootSignMsg",
"value": "={{ $json.chatwootSignMsg }}"
},
{
"name": "chatwoot_reopen_conversation",
"value": "={{ $json.chatwoot_reopen_conversation }}"
"name": "chatwootReopenConversation",
"value": "={{ $json.chatwootReopenConversation }}"
},
{
"name": "chatwoot_conversation_pending",
"value": "={{ $json.chatwoot_conversation_pending }}"
"name": "chatwootConversationPending",
"value": "={{ $json.chatwootConversationPending }}"
},
{
"name": "reject_call",
"value": "={{ $json.reject_call }}"
"name": "rejectCall",
"value": "={{ $json.rejectCall }}"
},
{
"name": "msg_call",
"value": "={{ $json.msg_call }}"
"name": "msgCall",
"value": "={{ $json.msgCall }}"
},
{
"name": "groups_ignore",
"value": "={{ $json.groups_ignore }}"
"name": "groupsIgnore",
"value": "={{ $json.groupsIgnore }}"
},
{
"name": "always_online",
"value": "={{ $json.always_online }}"
"name": "alwaysOnline",
"value": "={{ $json.alwaysOnline }}"
},
{
"name": "read_messages",
"value": "={{ $json.read_messages }}"
"name": "readMessages",
"value": "={{ $json.readMessages }}"
},
{
"name": "read_status",
"value": "={{ $json.read_status }}"
"name": "readStatus",
"value": "={{ $json.readStatus }}"
},
{
"name": "chatwootImportContacts",
"value": "={{ $json.chatwootImportContacts }}"
},
{
"name": "chatwootImportMessages",
"value": "={{ $json.chatwootImportMessages }}"
},
{
"name": "chatwootDaysLimitImportMessages",
"value": "={{ $json.chatwootDaysLimitImportMessages }}"
},
{
"name": "syncFullHistory",
"value": "={{ $json.syncFullHistory }}"
},
{
"name": "chatwootMergeBrazilContacts",
"value": "={{ $json.chatwootMergeBrazilContacts }}"
},
{
"name": "integration",
"value": "={{ $json.integration }}"
},
{
"name": "chatwootNameInbox",
"value": "={{ $json.chatwootNameInbox }}"
},
{
"name": "token",
"value": "={{ $json.token }}"
}
]
},
"options": {}
},
"id": "275aa370-2fdb-42f4-844a-2fb3051301bd",
"id": "7da41431-cc8e-4eb4-9894-7bf413819fe3",
"name": "Cria Instancia",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
760,
300
900,
680
]
},
{
"parameters": {
"url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/",
"url": "={{ $('Info Base').item.json[\"chatwootUrl\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwootAccountId\"] }}/inboxes/",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "api_access_token",
"value": "={{ $('Info Base').item.json.chatwoot_token }}"
"value": "={{ $('Info Base').item.json.chatwootToken }}"
}
]
},
"options": {}
},
"id": "e4650812-ba0a-4f72-8bd8-a235eca4b2de",
"id": "d51fbbfe-4579-4fba-949f-c29e0b806feb",
"name": "Lista Inboxes",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
980,
300
1120,
680
]
},
{
"parameters": {
"content": "## Workflow Para Criar Inbox\n**Aqui você configura a comunicação entre o chatwoot e a Evolution API para criar novas instâncias a partir do chatwoot**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e Evolution API**",
"content": "## Workflow Para Criar Inbox - Evolution 2.0 ou superior\n**Aqui você configura a comunicação entre o chatwoot e a Evolution API para criar novas instâncias a partir do chatwoot**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e Evolution API**",
"width": 1129.7777777777778
},
"id": "aa763d9e-d973-44fc-8399-277bb24718a5",
"id": "7c66af51-b01e-4b76-8a8c-0193e87ec9d5",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
320,
80
460,
460
]
},
{
@@ -149,32 +165,48 @@
"values": {
"string": [
{
"name": "chatwoot_url",
"value": "CHATWOOT_URL"
"name": "chatwootUrl",
"value": "https://chatwootUrl - preencha"
},
{
"name": "evolution_url",
"value": "EVOLUTION_URL"
"value": "https://evolution_url - preencha"
},
{
"name": "global_api_key",
"value": "EVOLUTION_GLOBAL_API_KEY"
"value": "global_api_key - preencha"
},
{
"name": "organization",
"value": "={{ $json.query.organization }}"
},
{
"name": "instance_name",
"name": "instanceName",
"value": "={{ $json.body.messages[0].content.split(':')[1] }}-cwId-{{ $json.body.messages[0].account_id }}"
},
{
"name": "chatwoot_token",
"name": "chatwootToken",
"value": "={{ $json.query.utoken }}"
},
{
"name": "msg_call",
"name": "msgCall",
"value": "Não aceitamos chamadas, por favor deixe uma mensagem!"
},
{
"name": "integration",
"value": "WHATSAPP-BAILEYS"
},
{
"name": "chatwootNameInbox",
"value": "={{ $json.body.messages[0].content.split(':')[1] }}"
},
{
"name": "chatwootAccountId",
"value": "={{ $json.body.messages[0].account_id.toString() }}"
},
{
"name": "token",
"value": "=AfRw{{ Date.now() }}BeH4"
}
],
"boolean": [
@@ -183,51 +215,67 @@
"value": true
},
{
"name": "chatwoot_sign_msg",
"name": "chatwootSignMsg",
"value": true
},
{
"name": "chatwoot_reopen_conversation",
"name": "chatwootReopenConversation",
"value": true
},
{
"name": "chatwoot_conversation_pending"
"name": "chatwootConversationPending"
},
{
"name": "reject_call",
"name": "rejectCall"
},
{
"name": "groupsIgnore"
},
{
"name": "alwaysOnline",
"value": true
},
{
"name": "groups_ignore"
},
{
"name": "always_online",
"name": "readMessages",
"value": true
},
{
"name": "read_messages",
"name": "readStatus"
},
{
"name": "chatwootImportMessages",
"value": true
},
{
"name": "read_status"
"name": "chatwootImportContacts",
"value": true
},
{
"name": "syncFullHistory"
},
{
"name": "chatwootMergeBrazilContacts",
"value": true
}
],
"number": [
{
"name": "chatwoot_account_id",
"value": "={{ $json.body.messages[0].account_id }}"
"name": "chatwootDaysLimitImportMessages",
"value": 60
}
]
},
"options": {}
"options": {
"dotNotation": false
}
},
"id": "297df325-ecc4-4a34-817c-092d16d5753b",
"id": "eaffbc44-3701-4f8d-b923-92061cfb995f",
"name": "Info Base",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
540,
300
680,
680
]
},
{
@@ -241,13 +289,13 @@
]
}
},
"id": "a8d955e6-ac51-4316-aeec-09d4d65e943a",
"id": "82eb24c8-2269-4622-b012-d6f6ad35c149",
"name": "é Start Inbox?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1660,
200
1800,
600
]
},
{
@@ -255,15 +303,80 @@
"batchSize": 1,
"options": {}
},
"id": "0d2d2194-aa4a-4241-9022-217d88bb581f",
"id": "b9de1318-ab0b-4529-b30a-2daea64dbcfe",
"name": "Split In Batches",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 2,
"position": [
1420,
300
1560,
680
]
},
{
"parameters": {
"method": "DELETE",
"url": "={{ $('Info Base').item.json[\"chatwootUrl\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwootAccountId\"] }}/inboxes/{{ $json.id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "api_access_token",
"value": "={{ $('Info Base').item.json.chatwootToken }}"
}
]
},
"options": {}
},
"id": "db2ad958-7642-41eb-8e9a-e8b1668230d1",
"name": "Deleta Inbox Start",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
2040,
480
]
},
{
"parameters": {},
"id": "6d68d3a7-d613-471f-8492-9ec473481521",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1800,
780
]
},
{
"parameters": {
"fieldToSplitOut": "payload",
"options": {}
},
"id": "be833e77-b2ae-44c6-b4fc-ad24ffc8ad9a",
"name": "Ajusta lista",
"type": "n8n-nodes-base.itemLists",
"typeVersion": 2.2,
"position": [
1340,
680
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "inbox_whatsapp",
"options": {}
},
"id": "faae80e0-9070-4a0c-83bc-d47643a64653",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
460,
680
],
"webhookId": "85cb0c27-4223-4339-b7b4-35a16c0a04b8"
},
{
"parameters": {
"conditions": {
@@ -275,25 +388,25 @@
]
}
},
"id": "0bfbc2cb-eff5-423c-bd3a-b266aaf6a943",
"id": "4ea7b74f-bdc5-4619-8e99-1f5d33c7e28e",
"name": "é_pre-existente?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1900,
340
1980,
700
]
},
{
"parameters": {
"method": "PATCH",
"url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.id }}",
"url": "={{ $('Info Base').item.json[\"chatwootUrl\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwootAccountId\"] }}/inboxes/{{ $json.id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "api_access_token",
"value": "={{ $('Info Base').item.json.chatwoot_token }}"
"value": "={{ $('Info Base').item.json.chatwootToken }}"
},
{
"name": "Content-Type",
@@ -303,75 +416,26 @@
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n\"channel\": {\n\"webhook_url\": \"{{ $('Info Base').item.json[\"evolution_url\"] }}/chatwoot/webhook/{{ encodeURIComponent($('Info Base').item.json[\"instance_name\"]) }}\"\n}\n}",
"jsonBody": "={\n\"channel\": {\n\"webhook_url\": \"{{ $('Info Base').item.json[\"evolution_url\"] }}/chatwoot/webhook/{{ encodeURIComponent($('Info Base').item.json[\"instanceName\"]) }}\"\n}\n}",
"options": {}
},
"id": "fb589456-5566-4a45-96a7-75986d0aa1d5",
"id": "74d6db21-d49e-48d6-b1a8-ff8bddca67d1",
"name": "Update_webhook_url",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
2120,
340
]
},
{
"parameters": {
"method": "DELETE",
"url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "api_access_token",
"value": "={{ $('Info Base').item.json.chatwoot_token }}"
}
]
},
"options": {}
},
"id": "e6094941-410f-496c-9c9c-7b95fd9349af",
"name": "Deleta Inbox Start",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 3,
"position": [
1900,
100
]
},
{
"parameters": {},
"id": "8cf9a78f-9e8a-4288-9d7b-801790af68d5",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1660,
400
]
},
{
"parameters": {
"fieldToSplitOut": "payload",
"options": {}
},
"id": "9468896a-5f86-4598-9d20-e8f495cae859",
"name": "Ajusta lista",
"type": "n8n-nodes-base.itemLists",
"typeVersion": 2.2,
"position": [
1200,
300
2200,
700
]
}
],
"pinData": {},
"connections": {
"Webhook": {
"Cria Instancia": {
"main": [
[
{
"node": "Info Base",
"node": "Lista Inboxes",
"type": "main",
"index": 0
}
@@ -389,17 +453,6 @@
]
]
},
"Cria Instancia": {
"main": [
[
{
"node": "Lista Inboxes",
"type": "main",
"index": 0
}
]
]
},
"Info Base": {
"main": [
[
@@ -447,6 +500,39 @@
]
]
},
"Deleta Inbox Start": {
"main": [
[
{
"node": "Split In Batches",
"type": "main",
"index": 0
}
]
]
},
"Ajusta lista": {
"main": [
[
{
"node": "Split In Batches",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Info Base",
"type": "main",
"index": 0
}
]
]
},
"é_pre-existente?": {
"main": [
[
@@ -475,36 +561,17 @@
}
]
]
},
"Deleta Inbox Start": {
"main": [
[
{
"node": "Split In Batches",
"type": "main",
"index": 0
}
]
]
},
"Ajusta lista": {
"main": [
[
{
"node": "Split In Batches",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {},
"versionId": "ab910349-b559-4738-9ac6-de6b06d6bbce",
"id": "ByW2ccjR4XPrOyio",
"meta": {
"instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906"
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "68f9fa60-e295-4b74-8cb3-c4723d6cb2b2",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "8ed3edb9203bfe03a4b94f63390235285fbb1c230430fdae73a456b9fae762d5"
},
"id": "f6dLbF7I7nrjcDc4",
"tags": []
}
}

File diff suppressed because one or more lines are too long

675
LICENSE
View File

@@ -1,674 +1,21 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
# Evolution API License
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Evolution API is licensed under the Apache License 2.0, with the following additional conditions:
Preamble
1. Evolution API may be utilized commercially, including as a backend service for other applications or as an application development platform for enterprises. Should the conditions below be met, a commercial license must be obtained from the producer:
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
a. LOGO and copyright information: In the process of using Evolution API's frontend components, you may not remove or modify the LOGO or copyright information in the Evolution API console or applications. This restriction is inapplicable to uses of Evolution API that do not involve its frontend components.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
b. Usage Notification Requirement: If Evolution API is used as part of any project, including closed-source systems (e.g., proprietary software), the user is required to display a clear notification within the system that Evolution API is being utilized. This notification should be visible to system administrators and accessible from the system's documentation or settings page. Failure to comply with this requirement may result in the necessity for a commercial license, as determined by the producer.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Please contact contato@evolution-api.com to inquire about licensing matters.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
2. As a contributor, you should agree that:
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
a. The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
b. Your contributed code may be used for commercial purposes, including but not limited to its cloud business operations.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0. Detailed information about the Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
© 2025 Evolution API
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

141
README.md
View File

@@ -2,50 +2,143 @@
<div align="center">
[![Docker Image](https://img.shields.io/badge/Docker-image-blue)](https://hub.docker.com/r/evoapicloud/evolution-api)
[![Whatsapp Group](https://img.shields.io/badge/Group-WhatsApp-%2322BC18)](https://evolution-api.com/whatsapp)
[![Discord Community](https://img.shields.io/badge/Discord-Community-blue)](https://evolution-api.com/discord)
[![Postman Collection](https://img.shields.io/badge/Postman-Collection-orange)](https://evolution-api.com/postman)
[![Documentation](https://img.shields.io/badge/Documentation-Official-green)](https://doc.evolution-api.com)
[![License](https://img.shields.io/badge/license-GPL--3.0-orange)](./LICENSE)
[![Feature Requests](https://img.shields.io/badge/Feature-Requests-purple)](https://evolutionapi.canny.io/feature-requests)
[![Roadmap](https://img.shields.io/badge/Roadmap-Community-blue)](https://evolutionapi.canny.io/feature-requests)
[![Changelog](https://img.shields.io/badge/Changelog-Updates-green)](https://evolutionapi.canny.io/changelog)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE)
[![Support](https://img.shields.io/badge/Donation-picpay-green)](https://app.picpay.com/user/davidsongomes1998)
[![Support](https://img.shields.io/badge/Buy%20me-coffe-orange)](https://bmc.link/evolutionapi)
[![Sponsors](https://img.shields.io/badge/Github-sponsor-orange)](https://github.com/sponsors/EvolutionAPI)
</div>
<div align="center"><img src="./public/images/cover.png"></div>
## WhatsApp-Api-NodeJs
## Evolution API
This project is based on the [CodeChat](https://github.com/code-chat-br/whatsapp-api). The original project is an implementation of [Baileys](https://github.com/WhiskeySockets/Baileys), serving as a Restful API service that controls WhatsApp functions.</br>
The code allows the creation of multiservice chats, service bots, or any other system that utilizes WhatsApp. The documentation provides instructions on how to set up and use the project, as well as additional information about its features and configuration options.
Evolution API began as a WhatsApp controller API based on [CodeChat](https://github.com/code-chat-br/whatsapp-api), which in turn implemented the [Baileys](https://github.com/WhiskeySockets/Baileys) library. While originally focused on WhatsApp, Evolution API has grown into a comprehensive platform supporting multiple messaging services and integrations. We continue to acknowledge CodeChat for laying the groundwork.
## SSL
Today, Evolution API is not limited to WhatsApp. It integrates with various platforms such as Typebot, Chatwoot, Dify, and OpenAI, offering a broad array of functionalities beyond messaging. Evolution API supports both the Baileys-based WhatsApp API and the official WhatsApp Business API, with upcoming support for Instagram and Messenger.
To install the SSL certificate, follow the **[instructions](https://certbot.eff.org/instructions?ws=other&os=ubuntufocal)** below.
## Looking for a Lightweight Version?
For those who need a more streamlined and performance-optimized version, check out [Evolution API Lite](https://github.com/EvolutionAPI/evolution-api-lite). It's designed specifically for microservices, focusing solely on connectivity without integrations or audio conversion features. Ideal for environments that prioritize simplicity and efficiency.
# Note
## Types of Connections
This code is in no way affiliated with WhatsApp. Use at your own discretion. Don't spam this.
Evolution API supports multiple types of connections to WhatsApp, enabling flexible and powerful integration options:
This code was produced based on the baileys library and it is still under development.
- *WhatsApp API - Baileys*:
- A free API based on WhatsApp Web, leveraging the [Baileys library](https://github.com/WhiskeySockets/Baileys).
- This connection type allows control over WhatsApp Web functionalities through a RESTful API, suitable for multi-service chats, service bots, and other WhatsApp-integrated systems.
- Note: This method relies on the web version of WhatsApp and may have limitations compared to official APIs.
- *WhatsApp Cloud API*:
- The official API provided by Meta (formerly Facebook).
- This connection type offers a robust and reliable solution designed for businesses needing higher volumes of messaging and better integration support.
- The Cloud API supports features such as end-to-end encryption, advanced analytics, and more comprehensive customer service tools.
- To use this API, you must comply with Meta's policies and potentially pay for usage based on message volume and other factors.
## Integrations
Evolution API supports various integrations to enhance its functionality. Below is a list of available integrations and their uses:
- [Typebot](https://typebot.io/):
- Build conversational bots using Typebot, integrated directly into Evolution with trigger management.
- [Chatwoot](https://www.chatwoot.com/):
- Direct integration with Chatwoot for handling customer service for your business.
- [RabbitMQ](https://www.rabbitmq.com/):
- Receive events from the Evolution API via RabbitMQ.
- [Apache Kafka](https://kafka.apache.org/):
- Receive events from the Evolution API via Apache Kafka for real-time event streaming and processing.
- [Amazon SQS](https://aws.amazon.com/pt/sqs/):
- Receive events from the Evolution API via Amazon SQS.
- [Socket.io](https://socket.io/):
- Receive events from the Evolution API via WebSocket.
- [Dify](https://dify.ai/):
- Integrate your Evolution API directly with Dify AI for seamless trigger management and multiple agents.
- [OpenAI](https://openai.com/):
- Integrate your Evolution API with OpenAI for AI capabilities, including audio-to-text conversion, available across all Evolution integrations.
- Amazon S3 / Minio:
- Store media files received in [Amazon S3](https://aws.amazon.com/pt/s3/) or [Minio](https://min.io/).
## Community & Feedback
We value community input and feedback to continuously improve Evolution API:
### 🚀 Feature Requests & Roadmap
- **[Feature Requests](https://evolutionapi.canny.io/feature-requests)**: Submit new feature ideas and vote on community proposals
- **[Roadmap](https://evolutionapi.canny.io/feature-requests)**: View planned features and development progress
- **[Changelog](https://evolutionapi.canny.io/changelog)**: Stay updated with the latest releases and improvements
### 💬 Community Support
- **[WhatsApp Group](https://evolution-api.com/whatsapp)**: Join our community for support and discussions
- **[Discord Community](https://evolution-api.com/discord)**: Real-time chat with developers and users
- **[GitHub Issues](https://github.com/EvolutionAPI/evolution-api/issues)**: Report bugs and technical issues
### 🔒 Security
- **[Security Policy](./SECURITY.md)**: Guidelines for reporting security vulnerabilities
- **Security Contact**: contato@evolution-api.com
## Telemetry Notice
To continuously improve our services, we have implemented telemetry that collects data on the routes used, the most accessed routes, and the version of the API in use. We would like to assure you that no sensitive or personal data is collected during this process. The telemetry helps us identify improvements and provide a better experience for users.
## Evolution Support Premium
Join our Evolution Pro community for expert support and a weekly call to answer questions. Visit the link below to learn more and subscribe:
[Click here to learn more](https://evolution-api.com/suporte-pro)
# Donate to the project.
#### PicPay
#### Github Sponsors
<div align="center">
<a href="https://app.picpay.com/user/davidsongomes1998" target="_blank" rel="noopener noreferrer">
<img src="./public/images/picpay-qr.jpeg" style="width: 50% !important;">
</a>
</div>
https://github.com/sponsors/EvolutionAPI
#### Buy me coffe - PIX
# Content Creator Partners
<div align="center">
<a href="https://bmc.link/evolutionapi" target="_blank" rel="noopener noreferrer">
<img src="./public/images/qrcode-pix.png" style="width: 50% !important;">
</a>
<p><b>CHAVE PIX (Telefone):</b> (74)99987-9409</p>
</div>
We are proud to collaborate with the following content creators who have contributed valuable insights and tutorials about Evolution API:
</br>
- [Promovaweb](https://www.youtube.com/@promovaweb)
- [Sandeco](https://www.youtube.com/@canalsandeco)
- [Comunidade ZDG](https://www.youtube.com/@ComunidadeZDG)
- [Francis MNO](https://www.youtube.com/@FrancisMNO)
- [Pablo Cabral](https://youtube.com/@pablocabral)
- [XPop Digital](https://www.youtube.com/@xpopdigital)
- [Costar Wagner Dev](https://www.youtube.com/@costarwagnerdev)
- [Dante Testa](https://youtube.com/@dantetesta_)
- [Rubén Salazar](https://youtube.com/channel/UCnYGZIE2riiLqaN9sI6riig)
- [OrionDesign](youtube.com/OrionDesign_Oficial)
- [IMPA 365](youtube.com/@impa365_ofc)
- [Comunidade Hub Connect](https://youtube.com/@comunidadehubconnect)
- [dSantana Automações](https://www.youtube.com/channel/UCG7DjUmAxtYyURlOGAIryNQ?view_as=subscriber)
- [Edison Martins](https://www.youtube.com/@edisonmartinsmkt)
- [Astra Online](https://www.youtube.com/@astraonlineweb)
- [MKT Seven Automações](https://www.youtube.com/@sevenautomacoes)
- [Vamos automatizar](https://www.youtube.com/vamosautomatizar)
## License
Evolution API is licensed under the Apache License 2.0, with the following additional conditions:
1. **LOGO and copyright information**: In the process of using Evolution API's frontend components, you may not remove or modify the LOGO or copyright information in the Evolution API console or applications. This restriction is inapplicable to uses of Evolution API that do not involve its frontend components.
2. **Usage Notification Requirement**: If Evolution API is used as part of any project, including closed-source systems (e.g., proprietary software), the user is required to display a clear notification within the system that Evolution API is being utilized. This notification should be visible to system administrators and accessible from the system's documentation or settings page. Failure to comply with this requirement may result in the necessity for a commercial license, as determined by the producer.
Please contact contato@evolution-api.com to inquire about licensing matters.
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0. Detailed information about the Apache License 2.0 can be found at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0).
© 2025 Evolution API

99
SECURITY.md Normal file
View File

@@ -0,0 +1,99 @@
# Security Policy
## Supported Versions
We actively support the following versions of Evolution API with security updates:
| Version | Supported |
| ------- | ------------------ |
| 2.3.x | ✅ Yes |
| 2.2.x | ✅ Yes |
| 2.1.x | ⚠️ Critical fixes only |
| < 2.1 | ❌ No |
## Reporting a Vulnerability
We take security vulnerabilities seriously. If you discover a security vulnerability in Evolution API, please help us by reporting it responsibly.
### 🔒 Private Disclosure Process
**Please DO NOT create a public GitHub issue for security vulnerabilities.**
Instead, please report security vulnerabilities via email to:
**📧 contato@evolution-api.com**
### 📋 What to Include
When reporting a vulnerability, please include:
- **Description**: A clear description of the vulnerability
- **Impact**: What an attacker could achieve by exploiting this vulnerability
- **Steps to Reproduce**: Detailed steps to reproduce the issue
- **Proof of Concept**: If possible, include a minimal proof of concept
- **Environment**: Version of Evolution API, OS, Node.js version, etc.
- **Suggested Fix**: If you have ideas for how to fix the issue
### 🕐 Response Timeline
We will acknowledge receipt of your vulnerability report within **48 hours** and will send you regular updates about our progress.
- **Initial Response**: Within 48 hours
- **Status Update**: Within 7 days
- **Resolution Timeline**: Varies based on complexity, typically 30-90 days
### 🎯 Scope
This security policy applies to:
- Evolution API core application
- Official Docker images
- Documentation that could lead to security issues
### 🚫 Out of Scope
The following are generally considered out of scope:
- Third-party integrations (Chatwoot, Typebot, etc.) - please report to respective projects
- Issues in dependencies - please report to the dependency maintainers
- Social engineering attacks
- Physical attacks
- Denial of Service attacks
### 🏆 Recognition
We believe in recognizing security researchers who help us keep Evolution API secure:
- We will acknowledge your contribution in our security advisories (unless you prefer to remain anonymous)
- For significant vulnerabilities, we may feature you in our Hall of Fame
- We will work with you on coordinated disclosure timing
### 📚 Security Best Practices
For users deploying Evolution API:
- Always use the latest supported version
- Keep your dependencies up to date
- Use strong authentication methods
- Implement proper network security
- Monitor your logs for suspicious activity
- Follow the principle of least privilege
### 🔄 Security Updates
Security updates will be:
- Released as patch versions (e.g., 2.3.1 → 2.3.2)
- Documented in our [CHANGELOG.md](./CHANGELOG.md)
- Announced in our community channels
- Tagged with security labels in GitHub releases
## Contact
For any questions about this security policy, please contact:
- **Email**: contato@evolution-api.com
---
Thank you for helping keep Evolution API and our community safe! 🛡️

34
commitlint.config.js Normal file
View File

@@ -0,0 +1,34 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // New feature
'fix', // Bug fix
'docs', // Documentation changes
'style', // Code style changes (formatting, etc)
'refactor', // Code refactoring
'perf', // Performance improvements
'test', // Adding or updating tests
'chore', // Maintenance tasks
'ci', // CI/CD changes
'build', // Build system changes
'revert', // Reverting changes
'security', // Security fixes
],
],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'header-max-length': [2, 'always', 100],
'body-leading-blank': [1, 'always'],
'body-max-line-length': [0, 'always', 150],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [0, 'always', 150],
},
};

View File

@@ -1,5 +1,3 @@
version: '3.3'
services:
api:
container_name: evolution_api
@@ -10,18 +8,26 @@ services:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
networks:
- evolution-net
env_file:
- ./Docker/.env
command: ['node', './dist/src/main.js']
- .env
expose:
- 8080
frontend:
container_name: evolution_frontend
image: evolution/manager:local
build: ./evolution-manager-v2
restart: always
ports:
- "3000:80"
networks:
- evolution-net
volumes:
evolution_instances:
evolution_store:
networks:
evolution-net:

84
docker-compose.yaml Normal file
View File

@@ -0,0 +1,84 @@
version: "3.8"
services:
api:
container_name: evolution_api
image: evoapicloud/evolution-api:latest
restart: always
depends_on:
- redis
- evolution-postgres
ports:
- "127.0.0.1:8080:8080"
volumes:
- evolution_instances:/evolution/instances
networks:
- evolution-net
- dokploy-network
env_file:
- .env
expose:
- "8080"
frontend:
container_name: evolution_frontend
image: evoapicloud/evolution-manager:latest
restart: always
ports:
- "3000:80"
networks:
- evolution-net
redis:
container_name: evolution_redis
image: redis:latest
restart: always
command: >
redis-server --port 6379 --appendonly yes
volumes:
- evolution_redis:/data
networks:
evolution-net:
aliases:
- evolution-redis
dokploy-network:
aliases:
- evolution-redis
expose:
- "6379"
evolution-postgres:
container_name: evolution_postgres
image: postgres:15
restart: always
env_file:
- .env
command:
- postgres
- -c
- max_connections=1000
- -c
- listen_addresses=*
environment:
- POSTGRES_DB=${POSTGRES_DATABASE}
- POSTGRES_USER=${POSTGRES_USERNAME}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- evolution-net
- dokploy-network
expose:
- "5432"
volumes:
evolution_instances:
evolution_redis:
postgres_data:
networks:
evolution-net:
name: evolution-net
driver: bridge
dokploy-network:
external: true

View File

@@ -1,80 +0,0 @@
version: '3.3'
services:
api:
container_name: evolution_api
image: evolution/api:local
build: .
restart: always
ports:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
networks:
- evolution-net
env_file:
- ./Docker/.env
command: ['node', './dist/src/main.js']
expose:
- 8080
mongodb:
container_name: mongodb
image: mongo
restart: always
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
- PUID=1000
- PGID=1000
volumes:
- evolution_mongodb_data:/data/db
- evolution_mongodb_configdb:/data/configdb
networks:
- evolution-net
expose:
- 27017
mongo-express:
image: mongo-express
networks:
- evolution-net
environment:
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: root
ports:
- 8081:8081
links:
- mongodb
redis:
image: redis:latest
container_name: redis
command: >
redis-server
--port 6379
--appendonly yes
volumes:
- evolution_redis:/data
networks:
- evolution-net
ports:
- 6379:6379
volumes:
evolution_instances:
evolution_store:
evolution_mongodb_data:
evolution_mongodb_configdb:
evolution_redis:
networks:
evolution-net:
name: evolution-net
driver: bridge

View File

@@ -1,28 +0,0 @@
version: '3.3'
services:
api:
container_name: evolution_api
image: atendai/evolution-api:latest
restart: always
ports:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
networks:
- evolution-net
env_file:
- ./Docker/.env
command: ['node', './dist/src/main.js']
expose:
- 8080
volumes:
evolution_instances:
evolution_store:
networks:
evolution-net:
name: evolution-net
driver: bridge

302
env.example Normal file
View File

@@ -0,0 +1,302 @@
# ===========================================
# EVOLUTION API - CONFIGURAÇÃO DE AMBIENTE
# ===========================================
# ===========================================
# SERVIDOR
# ===========================================
SERVER_NAME=evolution
SERVER_TYPE=http
SERVER_PORT=8080
SERVER_URL=http://localhost:8080
SERVER_DISABLE_DOCS=false
SERVER_DISABLE_MANAGER=false
# ===========================================
# CORS
# ===========================================
CORS_ORIGIN=*
CORS_METHODS=POST,GET,PUT,DELETE
CORS_CREDENTIALS=true
# ===========================================
# SSL (opcional)
# ===========================================
SSL_CONF_PRIVKEY=
SSL_CONF_FULLCHAIN=
# ===========================================
# BANCO DE DADOS
# ===========================================
DATABASE_PROVIDER=postgresql
DATABASE_CONNECTION_URI=postgresql://username:password@localhost:5432/evolution_api
DATABASE_CONNECTION_CLIENT_NAME=evolution
# Configurações de salvamento de dados
DATABASE_SAVE_DATA_INSTANCE=true
DATABASE_SAVE_DATA_NEW_MESSAGE=true
DATABASE_SAVE_MESSAGE_UPDATE=true
DATABASE_SAVE_DATA_CONTACTS=true
DATABASE_SAVE_DATA_CHATS=true
DATABASE_SAVE_DATA_HISTORIC=true
DATABASE_SAVE_DATA_LABELS=true
DATABASE_SAVE_IS_ON_WHATSAPP=true
DATABASE_SAVE_IS_ON_WHATSAPP_DAYS=7
DATABASE_DELETE_MESSAGE=false
# ===========================================
# REDIS
# ===========================================
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://localhost:6379
CACHE_REDIS_PREFIX_KEY=evolution-cache
CACHE_REDIS_TTL=604800
CACHE_REDIS_SAVE_INSTANCES=true
# Cache local (fallback)
CACHE_LOCAL_ENABLED=true
CACHE_LOCAL_TTL=86400
# ===========================================
# AUTENTICAÇÃO
# ===========================================
AUTHENTICATION_API_KEY=BQYHJGJHJ
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=false
# ===========================================
# LOGS
# ===========================================
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS,WEBSOCKET
LOG_COLOR=true
LOG_BAILEYS=error
# ===========================================
# INSTÂNCIAS
# ===========================================
DEL_INSTANCE=false
DEL_TEMP_INSTANCES=true
# ===========================================
# IDIOMA
# ===========================================
LANGUAGE=pt-BR
# ===========================================
# WEBHOOK
# ===========================================
WEBHOOK_GLOBAL_URL=
WEBHOOK_GLOBAL_ENABLED=false
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
# Eventos de webhook
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_INSTANCE_CREATE=false
WEBHOOK_EVENTS_INSTANCE_DELETE=false
WEBHOOK_EVENTS_QRCODE_UPDATED=false
WEBHOOK_EVENTS_MESSAGES_SET=false
WEBHOOK_EVENTS_MESSAGES_UPSERT=false
WEBHOOK_EVENTS_MESSAGES_EDITED=false
WEBHOOK_EVENTS_MESSAGES_UPDATE=false
WEBHOOK_EVENTS_MESSAGES_DELETE=false
WEBHOOK_EVENTS_SEND_MESSAGE=false
WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=false
WEBHOOK_EVENTS_CONTACTS_SET=false
WEBHOOK_EVENTS_CONTACTS_UPDATE=false
WEBHOOK_EVENTS_CONTACTS_UPSERT=false
WEBHOOK_EVENTS_PRESENCE_UPDATE=false
WEBHOOK_EVENTS_CHATS_SET=false
WEBHOOK_EVENTS_CHATS_UPDATE=false
WEBHOOK_EVENTS_CHATS_UPSERT=false
WEBHOOK_EVENTS_CHATS_DELETE=false
WEBHOOK_EVENTS_CONNECTION_UPDATE=false
WEBHOOK_EVENTS_LABELS_EDIT=false
WEBHOOK_EVENTS_LABELS_ASSOCIATION=false
WEBHOOK_EVENTS_GROUPS_UPSERT=false
WEBHOOK_EVENTS_GROUPS_UPDATE=false
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=false
WEBHOOK_EVENTS_CALL=false
WEBHOOK_EVENTS_TYPEBOT_START=false
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
WEBHOOK_EVENTS_ERRORS=false
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
# Configurações de webhook
WEBHOOK_REQUEST_TIMEOUT_MS=30000
WEBHOOK_RETRY_MAX_ATTEMPTS=10
WEBHOOK_RETRY_INITIAL_DELAY_SECONDS=5
WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF=true
WEBHOOK_RETRY_MAX_DELAY_SECONDS=300
WEBHOOK_RETRY_JITTER_FACTOR=0.2
WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES=400,401,403,404,422
# ===========================================
# WEBSOCKET
# ===========================================
WEBSOCKET_ENABLED=true
WEBSOCKET_GLOBAL_EVENTS=true
WEBSOCKET_ALLOWED_HOSTS=
# ===========================================
# RABBITMQ
# ===========================================
RABBITMQ_ENABLED=false
RABBITMQ_GLOBAL_ENABLED=false
RABBITMQ_PREFIX_KEY=
RABBITMQ_EXCHANGE_NAME=evolution_exchange
RABBITMQ_URI=
RABBITMQ_FRAME_MAX=8192
# ===========================================
# NATS
# ===========================================
NATS_ENABLED=false
NATS_GLOBAL_ENABLED=false
NATS_PREFIX_KEY=
NATS_EXCHANGE_NAME=evolution_exchange
NATS_URI=
# ===========================================
# SQS
# ===========================================
SQS_ENABLED=false
SQS_GLOBAL_ENABLED=false
SQS_GLOBAL_FORCE_SINGLE_QUEUE=false
SQS_GLOBAL_PREFIX_NAME=global
SQS_ACCESS_KEY_ID=
SQS_SECRET_ACCESS_KEY=
SQS_ACCOUNT_ID=
SQS_REGION=
SQS_MAX_PAYLOAD_SIZE=1048576
# ===========================================
# PUSHER
# ===========================================
PUSHER_ENABLED=false
PUSHER_GLOBAL_ENABLED=false
PUSHER_GLOBAL_APP_ID=
PUSHER_GLOBAL_KEY=
PUSHER_GLOBAL_SECRET=
PUSHER_GLOBAL_CLUSTER=
PUSHER_GLOBAL_USE_TLS=false
# ===========================================
# WHATSAPP BUSINESS
# ===========================================
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com
WA_BUSINESS_VERSION=v18.0
WA_BUSINESS_LANGUAGE=en
# ===========================================
# CONFIGURAÇÕES DE SESSÃO
# ===========================================
CONFIG_SESSION_PHONE_CLIENT=Evolution API
CONFIG_SESSION_PHONE_NAME=Chrome
# ===========================================
# QR CODE
# ===========================================
QRCODE_LIMIT=30
QRCODE_COLOR=#198754
# ===========================================
# INTEGRAÇÕES
# ===========================================
# Typebot
TYPEBOT_ENABLED=false
TYPEBOT_API_VERSION=old
TYPEBOT_SEND_MEDIA_BASE64=false
# Chatwoot
CHATWOOT_ENABLED=false
CHATWOOT_MESSAGE_DELETE=false
CHATWOOT_MESSAGE_READ=false
CHATWOOT_BOT_CONTACT=true
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=false
# OpenAI
OPENAI_ENABLED=false
OPENAI_API_KEY_GLOBAL=
# Dify
DIFY_ENABLED=false
# N8N
N8N_ENABLED=false
# EvoAI
EVOAI_ENABLED=false
# Flowise
FLOWISE_ENABLED=false
# ===========================================
# S3 / MINIO
# ===========================================
S3_ENABLED=false
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_ENDPOINT=
S3_BUCKET=
S3_PORT=9000
S3_USE_SSL=false
S3_REGION=
S3_SKIP_POLICY=false
S3_SAVE_VIDEO=false
# ===========================================
# MÉTRICAS
# ===========================================
PROMETHEUS_METRICS=false
METRICS_AUTH_REQUIRED=false
METRICS_USER=
METRICS_PASSWORD=
METRICS_ALLOWED_IPS=
# ===========================================
# TELEMETRIA
# ===========================================
TELEMETRY_ENABLED=true
TELEMETRY_URL=
# ===========================================
# PROXY
# ===========================================
PROXY_HOST=
PROXY_PORT=
PROXY_PROTOCOL=
PROXY_USERNAME=
PROXY_PASSWORD=
# ===========================================
# CONVERSOR DE ÁUDIO
# ===========================================
API_AUDIO_CONVERTER=
API_AUDIO_CONVERTER_KEY=
# ===========================================
# FACEBOOK
# ===========================================
FACEBOOK_APP_ID=
FACEBOOK_CONFIG_ID=
FACEBOOK_USER_TOKEN=
# ===========================================
# SENTRY
# ===========================================
SENTRY_DSN=
# ===========================================
# EVENT EMITTER
# ===========================================
EVENT_EMITTER_MAX_LISTENERS=50
# ===========================================
# PROVIDER
# ===========================================
PROVIDER_ENABLED=false
PROVIDER_HOST=
PROVIDER_PORT=5656
PROVIDER_PREFIX=evolution

1
evolution-manager-v2 Submodule

Submodule evolution-manager-v2 added at f054b9bc28

View File

@@ -0,0 +1,238 @@
{
"dashboard": {
"id": null,
"title": "Evolution API Monitoring",
"tags": ["evolution-api", "whatsapp", "monitoring"],
"style": "dark",
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "API Status",
"type": "stat",
"targets": [
{
"expr": "up{job=\"evolution-api\"}",
"legendFormat": "API Status"
}
],
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"0": {
"text": "DOWN",
"color": "red"
},
"1": {
"text": "UP",
"color": "green"
}
},
"type": "value"
}
]
}
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
}
},
{
"id": 2,
"title": "Total Instances",
"type": "stat",
"targets": [
{
"expr": "evolution_instances_total",
"legendFormat": "Total Instances"
}
],
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
}
},
{
"id": 3,
"title": "Instance Status Overview",
"type": "piechart",
"targets": [
{
"expr": "sum by (state) (evolution_instance_state)",
"legendFormat": "{{ state }}"
}
],
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 8
}
},
{
"id": 4,
"title": "Instances by Integration Type",
"type": "piechart",
"targets": [
{
"expr": "sum by (integration) (evolution_instance_up)",
"legendFormat": "{{ integration }}"
}
],
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 8
}
},
{
"id": 5,
"title": "Instance Uptime",
"type": "table",
"targets": [
{
"expr": "evolution_instance_up",
"format": "table",
"instant": true
}
],
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true,
"__name__": true
},
"renameByName": {
"instance": "Instance Name",
"integration": "Integration Type",
"Value": "Status"
}
}
}
],
"fieldConfig": {
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Status"
},
"properties": [
{
"id": "mappings",
"value": [
{
"options": {
"0": {
"text": "DOWN",
"color": "red"
},
"1": {
"text": "UP",
"color": "green"
}
},
"type": "value"
}
]
}
]
}
]
},
"gridPos": {
"h": 9,
"w": 24,
"x": 0,
"y": 17
}
},
{
"id": 6,
"title": "Instance Status Timeline",
"type": "timeseries",
"targets": [
{
"expr": "evolution_instance_up",
"legendFormat": "{{ instance }} ({{ integration }})"
}
],
"fieldConfig": {
"defaults": {
"custom": {
"drawStyle": "line",
"lineInterpolation": "stepAfter",
"lineWidth": 2,
"fillOpacity": 10,
"gradientMode": "none",
"spanNulls": false,
"insertNulls": false,
"showPoints": "never",
"pointSize": 5,
"stacking": {
"mode": "none",
"group": "A"
},
"axisPlacement": "auto",
"axisLabel": "",
"scaleDistribution": {
"type": "linear"
},
"hideFrom": {
"legend": false,
"tooltip": false,
"vis": false
},
"thresholdsStyle": {
"mode": "off"
}
},
"min": 0,
"max": 1
}
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 26
}
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"templating": {
"list": []
},
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"refresh": "30s",
"schemaVersion": 27,
"version": 0,
"links": []
}
}

View File

150
local_install.sh Executable file
View File

@@ -0,0 +1,150 @@
#!/bin/bash
# Definir cores para melhor legibilidade
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Função para log
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Verificar se está rodando como root
if [ "$(id -u)" = "0" ]; then
log_error "Este script não deve ser executado como root"
exit 1
fi
# Verificar sistema operacional
OS="$(uname -s)"
case "${OS}" in
Linux*)
if [ ! -x "$(command -v curl)" ]; then
log_warning "Curl não está instalado. Tentando instalar..."
if [ -x "$(command -v apt-get)" ]; then
sudo apt-get update && sudo apt-get install -y curl
elif [ -x "$(command -v yum)" ]; then
sudo yum install -y curl
else
log_error "Não foi possível instalar curl automaticamente. Por favor, instale manualmente."
exit 1
fi
fi
;;
Darwin*)
if [ ! -x "$(command -v curl)" ]; then
log_error "Curl não está instalado. Por favor, instale o Xcode Command Line Tools."
exit 1
fi
;;
*)
log_error "Sistema operacional não suportado: ${OS}"
exit 1
;;
esac
# Verificar conexão com a internet antes de prosseguir
if ! ping -c 1 8.8.8.8 &> /dev/null; then
log_error "Sem conexão com a internet. Por favor, verifique sua conexão."
exit 1
fi
# Adicionar verificação de espaço em disco
REQUIRED_SPACE=1000000 # 1GB em KB
AVAILABLE_SPACE=$(df -k . | awk 'NR==2 {print $4}')
if [ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]; then
log_error "Espaço em disco insuficiente. Necessário pelo menos 1GB livre."
exit 1
fi
# Adicionar tratamento de erro para comandos npm
npm_install_with_retry() {
local max_attempts=3
local attempt=1
while [ $attempt -le $max_attempts ]; do
log "Tentativa $attempt de $max_attempts para npm install"
if npm install; then
return 0
fi
attempt=$((attempt + 1))
[ $attempt -le $max_attempts ] && log_warning "Falha na instalação. Tentando novamente em 5 segundos..." && sleep 5
done
log_error "Falha ao executar npm install após $max_attempts tentativas"
return 1
}
# Adicionar timeout para comandos
execute_with_timeout() {
timeout 300 $@ || log_error "Comando excedeu o tempo limite de 5 minutos: $@"
}
# Verificar se o NVM já está instalado
if [ -d "$HOME/.nvm" ]; then
log "NVM já está instalado."
else
log "Instalando NVM..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
fi
# Carregar o NVM no ambiente atual
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# Verificar se a versão do Node.js já está instalada
if command -v node >/dev/null 2>&1 && [ "$(node -v)" = "v20.10.0" ]; then
log "Node.js v20.10.0 já está instalado."
else
log "Instalando Node.js v20.10.0..."
nvm install v20.10.0
fi
nvm use v20.10.0
# Verificar as versões instaladas
log "Verificando as versões instaladas:"
log "Node.js: $(node -v)"
log "npm: $(npm -v)"
# Instala dependências do projeto
log "Instalando dependências do projeto..."
rm -rf node_modules
npm install
# Deploy do banco de dados
log "Deploy do banco de dados..."
npm run db:generate
npm run db:deploy
# Iniciar o projeto
log "Iniciando o projeto..."
if [ "$1" = "-dev" ]; then
npm run dev:server
else
npm run build
npm run start:prod
fi
log "Instalação concluída com sucesso!"
# Criar arquivo de log
LOGFILE="./installation_log_$(date +%Y%m%d_%H%M%S).log"
exec 1> >(tee -a "$LOGFILE")
exec 2>&1
# Adicionar trap para limpeza em caso de interrupção
cleanup() {
log "Limpando recursos temporários..."
# Adicione comandos de limpeza aqui
}
trap cleanup EXIT

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

485
manager/dist/assets/index-CO3NSIFj.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14
manager/dist/index.html vendored Normal file
View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="https://evolution-api.com/files/evo/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Evolution Manager</title>
<script type="module" crossorigin src="/assets/index-CO3NSIFj.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DsIrum0U.css">
</head>
<body>
<div id="root"></div>
</body>
</html>

8
manager_install.sh Executable file
View File

@@ -0,0 +1,8 @@
#! /bin/bash
cd evolution-manager-v2
npm install
npm run build
cd ..
rm -rf manager/dist
cp -r evolution-manager-v2/dist manager/dist

16053
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,26 @@
{
"name": "evolution-api",
"version": "1.8.1",
"version": "2.3.6",
"description": "Rest api for communication with WhatsApp",
"main": "./dist/src/main.js",
"main": "./dist/main.js",
"type": "commonjs",
"scripts": {
"build": "tsc",
"start": "ts-node --files --transpile-only ./src/main.ts",
"start:prod": "bash start.sh",
"dev:server": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./src/main.ts",
"test": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./test/all.test.ts",
"lint": "eslint --fix --ext .ts src"
"build": "tsc --noEmit && tsup",
"start": "tsx ./src/main.ts",
"start:prod": "node dist/main",
"dev:server": "tsx watch ./src/main.ts",
"test": "tsx watch ./test/all.test.ts",
"lint": "eslint --fix --ext .ts src",
"lint:check": "eslint --ext .ts src",
"commit": "cz",
"commitlint": "commitlint --edit",
"db:generate": "node runWithProvider.js \"npx prisma generate --schema ./prisma/DATABASE_PROVIDER-schema.prisma\"",
"db:deploy": "node runWithProvider.js \"rm -rf ./prisma/migrations && cp -r ./prisma/DATABASE_PROVIDER-migrations ./prisma/migrations && npx prisma migrate deploy --schema ./prisma/DATABASE_PROVIDER-schema.prisma\"",
"db:deploy:win": "node runWithProvider.js \"xcopy /E /I prisma\\DATABASE_PROVIDER-migrations prisma\\migrations && npx prisma migrate deploy --schema prisma\\DATABASE_PROVIDER-schema.prisma\"",
"db:studio": "node runWithProvider.js \"npx prisma studio --schema ./prisma/DATABASE_PROVIDER-schema.prisma\"",
"db:migrate:dev": "node runWithProvider.js \"rm -rf ./prisma/migrations && cp -r ./prisma/DATABASE_PROVIDER-migrations ./prisma/migrations && npx prisma migrate dev --schema ./prisma/DATABASE_PROVIDER-schema.prisma && cp -r ./prisma/migrations/* ./prisma/DATABASE_PROVIDER-migrations\"",
"db:migrate:dev:win": "node runWithProvider.js \"xcopy /E /I prisma\\DATABASE_PROVIDER-migrations prisma\\migrations && npx prisma migrate dev --schema prisma\\DATABASE_PROVIDER-schema.prisma\"",
"prepare": "husky"
},
"repository": {
"type": "git",
@@ -33,84 +44,112 @@
],
"author": {
"name": "Davidson Gomes",
"email": "contato@agenciadgcode.com"
"email": "contato@evolution-api.com"
},
"license": "GPL-3.0",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/EvolutionAPI/evolution-api/issues"
},
"homepage": "https://github.com/EvolutionAPI/evolution-api#readme",
"lint-staged": {
"src/**/*.{ts,js}": [
"eslint --fix"
],
"src/**/*.ts": [
"sh -c 'tsc --noEmit'"
]
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"dependencies": {
"@adiwajshing/keyed-db": "^0.2.4",
"@aws-sdk/client-sqs": "^3.891.0",
"@ffmpeg-installer/ffmpeg": "^1.1.0",
"@figuro/chatwoot-sdk": "^1.1.16",
"@hapi/boom": "^10.0.1",
"@sentry/node": "^7.59.2",
"amqplib": "^0.10.3",
"@aws-sdk/client-sqs": "^3.569.0",
"axios": "^1.6.5",
"@whiskeysockets/baileys": "6.7.5",
"@paralleldrive/cuid2": "^2.2.2",
"@prisma/client": "^6.16.2",
"@sentry/node": "^10.12.0",
"@types/uuid": "^10.0.0",
"amqplib": "^0.10.5",
"audio-decode": "^2.2.3",
"axios": "^1.7.9",
"baileys": "7.0.0-rc.6",
"class-validator": "^0.14.1",
"compression": "^1.7.4",
"compression": "^1.7.5",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dayjs": "^1.11.7",
"dayjs": "^1.11.13",
"dotenv": "^16.4.7",
"emoji-regex": "^10.4.0",
"eventemitter2": "^6.4.9",
"evolution-manager": "^0.4.13",
"exiftool-vendored": "^22.0.0",
"express": "^4.18.2",
"express": "^4.21.2",
"express-async-errors": "^3.1.1",
"fluent-ffmpeg": "^2.1.2",
"form-data": "^4.0.0",
"hbs": "^4.2.0",
"https-proxy-agent": "^7.0.2",
"fluent-ffmpeg": "^2.1.3",
"form-data": "^4.0.1",
"https-proxy-agent": "^7.0.6",
"i18next": "^23.7.19",
"jimp": "^0.16.13",
"join": "^3.0.0",
"js-yaml": "^4.1.0",
"jimp": "^1.6.0",
"json-schema": "^0.4.0",
"jsonschema": "^1.4.1",
"jsonwebtoken": "^9.0.2",
"libphonenumber-js": "^1.10.39",
"link-preview-js": "^3.0.4",
"mongoose": "^6.10.5",
"kafkajs": "^2.2.4",
"link-preview-js": "^3.0.13",
"long": "^5.2.3",
"mediainfo.js": "^0.3.4",
"mime": "^4.0.0",
"mime-types": "^2.1.35",
"minio": "^8.0.3",
"multer": "^2.0.2",
"nats": "^2.29.1",
"node-cache": "^5.1.2",
"node-mime-types": "^1.1.0",
"node-windows": "^1.0.0-beta.8",
"parse-bmfont-xml": "^1.1.4",
"pg": "^8.11.3",
"pino": "^8.11.0",
"qrcode": "^1.5.1",
"node-cron": "^3.0.3",
"openai": "^4.77.3",
"pg": "^8.13.1",
"pino": "^9.10.0",
"prisma": "^6.1.0",
"pusher": "^5.2.0",
"qrcode": "^1.5.4",
"qrcode-terminal": "^0.12.0",
"redis": "^4.6.5",
"sharp": "^0.32.2",
"socket.io": "^4.7.1",
"socks-proxy-agent": "^8.0.1",
"swagger-ui-express": "^5.0.0",
"uuid": "^9.0.0",
"xml2js": "^0.6.2",
"yamljs": "^0.3.0"
"redis": "^4.7.0",
"rxjs": "^7.8.2",
"sharp": "^0.34.2",
"socket.io": "^4.8.1",
"socket.io-client": "^4.8.1",
"socks-proxy-agent": "^8.0.5",
"swagger-ui-express": "^5.0.1",
"tsup": "^8.3.5",
"uuid": "^13.0.0"
},
"devDependencies": {
"@types/compression": "^1.7.2",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/js-yaml": "^4.0.5",
"@types/jsonwebtoken": "^8.5.9",
"@types/mime-types": "^2.1.1",
"@types/node": "^18.15.11",
"@types/node-windows": "^0.1.2",
"@types/qrcode": "^1.5.0",
"@types/qrcode-terminal": "^0.12.0",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@types/compression": "^1.7.5",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.18",
"@types/json-schema": "^7.0.15",
"@types/mime": "^4.0.0",
"@types/mime-types": "^2.1.4",
"@types/node": "^24.5.2",
"@types/node-cron": "^3.0.11",
"@types/qrcode": "^1.5.5",
"@types/qrcode-terminal": "^0.12.2",
"@typescript-eslint/eslint-plugin": "^8.44.0",
"@typescript-eslint/parser": "^8.44.0",
"commitizen": "^4.3.1",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"prettier": "^2.8.8",
"ts-node-dev": "^2.0.0",
"typescript": "^4.9.5"
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"husky": "^9.1.7",
"lint-staged": "^16.1.6",
"prettier": "^3.4.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.20.5",
"typescript": "^5.7.2"
}
}

View File

@@ -0,0 +1,588 @@
-- CreateTable
CREATE TABLE `Instance` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`connectionStatus` ENUM('open', 'close', 'connecting') NOT NULL DEFAULT 'open',
`ownerJid` VARCHAR(100) NULL,
`profileName` VARCHAR(100) NULL,
`profilePicUrl` VARCHAR(500) NULL,
`integration` VARCHAR(100) NULL,
`number` VARCHAR(100) NULL,
`businessId` VARCHAR(100) NULL,
`token` VARCHAR(255) NULL,
`clientName` VARCHAR(100) NULL,
`disconnectionReasonCode` INTEGER NULL,
`disconnectionObject` JSON NULL,
`disconnectionAt` TIMESTAMP NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NULL,
UNIQUE INDEX `Instance_name_key`(`name`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Session` (
`id` VARCHAR(191) NOT NULL,
`sessionId` VARCHAR(191) NOT NULL,
`creds` TEXT NULL,
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `Session_sessionId_key`(`sessionId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Chat` (
`id` VARCHAR(191) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`labels` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Contact` (
`id` VARCHAR(191) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`pushName` VARCHAR(100) NULL,
`profilePicUrl` VARCHAR(500) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Message` (
`id` VARCHAR(191) NOT NULL,
`key` JSON NOT NULL,
`pushName` VARCHAR(100) NULL,
`participant` VARCHAR(100) NULL,
`messageType` VARCHAR(100) NOT NULL,
`message` JSON NOT NULL,
`contextInfo` JSON NULL,
`source` ENUM('ios', 'android', 'web', 'unknown', 'desktop') NOT NULL,
`messageTimestamp` INTEGER NOT NULL,
`chatwootMessageId` INTEGER NULL,
`chatwootInboxId` INTEGER NULL,
`chatwootConversationId` INTEGER NULL,
`chatwootContactInboxSourceId` VARCHAR(100) NULL,
`chatwootIsRead` BOOLEAN NULL DEFAULT false,
`instanceId` VARCHAR(191) NOT NULL,
`typebotSessionId` VARCHAR(191) NULL,
`openaiSessionId` VARCHAR(191) NULL,
`webhookUrl` VARCHAR(500) NULL,
`difySessionId` VARCHAR(191) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `MessageUpdate` (
`id` VARCHAR(191) NOT NULL,
`keyId` VARCHAR(100) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`fromMe` BOOLEAN NOT NULL,
`participant` VARCHAR(100) NULL,
`pollUpdates` JSON NULL,
`status` VARCHAR(30) NOT NULL,
`messageId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Webhook` (
`id` VARCHAR(191) NOT NULL,
`url` VARCHAR(500) NOT NULL,
`enabled` BOOLEAN NULL DEFAULT true,
`events` JSON NULL,
`webhookByEvents` BOOLEAN NULL DEFAULT false,
`webhookBase64` BOOLEAN NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Webhook_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Chatwoot` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NULL DEFAULT true,
`accountId` VARCHAR(100) NULL,
`token` VARCHAR(100) NULL,
`url` VARCHAR(500) NULL,
`nameInbox` VARCHAR(100) NULL,
`signMsg` BOOLEAN NULL DEFAULT false,
`signDelimiter` VARCHAR(100) NULL,
`number` VARCHAR(100) NULL,
`reopenConversation` BOOLEAN NULL DEFAULT false,
`conversationPending` BOOLEAN NULL DEFAULT false,
`mergeBrazilContacts` BOOLEAN NULL DEFAULT false,
`importContacts` BOOLEAN NULL DEFAULT false,
`importMessages` BOOLEAN NULL DEFAULT false,
`daysLimitImportMessages` INTEGER NULL,
`organization` VARCHAR(100) NULL,
`logo` VARCHAR(500) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Chatwoot_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Label` (
`id` VARCHAR(191) NOT NULL,
`labelId` VARCHAR(100) NULL,
`name` VARCHAR(100) NOT NULL,
`color` VARCHAR(100) NOT NULL,
`predefinedId` VARCHAR(100) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Label_labelId_key`(`labelId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Proxy` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`host` VARCHAR(100) NOT NULL,
`port` VARCHAR(100) NOT NULL,
`protocol` VARCHAR(100) NOT NULL,
`username` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Proxy_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Setting` (
`id` VARCHAR(191) NOT NULL,
`rejectCall` BOOLEAN NOT NULL DEFAULT false,
`msgCall` VARCHAR(100) NULL,
`groupsIgnore` BOOLEAN NOT NULL DEFAULT false,
`alwaysOnline` BOOLEAN NOT NULL DEFAULT false,
`readMessages` BOOLEAN NOT NULL DEFAULT false,
`readStatus` BOOLEAN NOT NULL DEFAULT false,
`syncFullHistory` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Setting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Rabbitmq` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Rabbitmq_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Sqs` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Sqs_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Websocket` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Websocket_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Typebot` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`url` VARCHAR(500) NOT NULL,
`typebot` VARCHAR(100) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `TypebotSession` (
`id` VARCHAR(191) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`pushName` VARCHAR(100) NULL,
`sessionId` VARCHAR(100) NOT NULL,
`status` ENUM('opened', 'closed', 'paused') NOT NULL,
`prefilledVariables` JSON NULL,
`awaitUser` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`typebotId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `TypebotSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`typebotIdFallback` VARCHAR(100) NULL,
`ignoreJids` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `TypebotSetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Media` (
`id` VARCHAR(191) NOT NULL,
`fileName` VARCHAR(500) NOT NULL,
`type` VARCHAR(100) NOT NULL,
`mimetype` VARCHAR(100) NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`messageId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Media_fileName_key`(`fileName`),
UNIQUE INDEX `Media_messageId_key`(`messageId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `OpenaiCreds` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(255) NULL,
`apiKey` VARCHAR(255) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `OpenaiCreds_name_key`(`name`),
UNIQUE INDEX `OpenaiCreds_apiKey_key`(`apiKey`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `OpenaiBot` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`botType` ENUM('assistant', 'chatCompletion') NOT NULL,
`assistantId` VARCHAR(255) NULL,
`functionUrl` VARCHAR(500) NULL,
`model` VARCHAR(100) NULL,
`systemMessages` JSON NULL,
`assistantMessages` JSON NULL,
`userMessages` JSON NULL,
`maxTokens` INTEGER NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`openaiCredsId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `OpenaiSession` (
`id` VARCHAR(191) NOT NULL,
`sessionId` VARCHAR(255) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`status` ENUM('opened', 'closed', 'paused') NOT NULL,
`awaitUser` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`openaiBotId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `OpenaiSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`speechToText` BOOLEAN NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`openaiCredsId` VARCHAR(191) NOT NULL,
`openaiIdFallback` VARCHAR(100) NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `OpenaiSetting_openaiCredsId_key`(`openaiCredsId`),
UNIQUE INDEX `OpenaiSetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Template` (
`id` VARCHAR(191) NOT NULL,
`templateId` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`template` JSON NOT NULL,
`webhookUrl` VARCHAR(500) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Template_templateId_key`(`templateId`),
UNIQUE INDEX `Template_name_key`(`name`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Dify` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`botType` ENUM('chatBot', 'textGenerator', 'agent', 'workflow') NOT NULL,
`apiUrl` VARCHAR(255) NULL,
`apiKey` VARCHAR(255) NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `DifySession` (
`id` VARCHAR(191) NOT NULL,
`sessionId` VARCHAR(255) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`status` ENUM('opened', 'closed', 'paused') NOT NULL,
`awaitUser` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`difyId` VARCHAR(191) NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `DifySetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`difyIdFallback` VARCHAR(100) NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `DifySetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Session` ADD CONSTRAINT `Session_sessionId_fkey` FOREIGN KEY (`sessionId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Chat` ADD CONSTRAINT `Chat_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Contact` ADD CONSTRAINT `Contact_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_typebotSessionId_fkey` FOREIGN KEY (`typebotSessionId`) REFERENCES `TypebotSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_openaiSessionId_fkey` FOREIGN KEY (`openaiSessionId`) REFERENCES `OpenaiSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_difySessionId_fkey` FOREIGN KEY (`difySessionId`) REFERENCES `DifySession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `MessageUpdate` ADD CONSTRAINT `MessageUpdate_messageId_fkey` FOREIGN KEY (`messageId`) REFERENCES `Message`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `MessageUpdate` ADD CONSTRAINT `MessageUpdate_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Webhook` ADD CONSTRAINT `Webhook_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Chatwoot` ADD CONSTRAINT `Chatwoot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Label` ADD CONSTRAINT `Label_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Proxy` ADD CONSTRAINT `Proxy_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Setting` ADD CONSTRAINT `Setting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Rabbitmq` ADD CONSTRAINT `Rabbitmq_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Sqs` ADD CONSTRAINT `Sqs_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Websocket` ADD CONSTRAINT `Websocket_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Typebot` ADD CONSTRAINT `Typebot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `TypebotSession` ADD CONSTRAINT `TypebotSession_typebotId_fkey` FOREIGN KEY (`typebotId`) REFERENCES `Typebot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `TypebotSession` ADD CONSTRAINT `TypebotSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `TypebotSetting` ADD CONSTRAINT `TypebotSetting_typebotIdFallback_fkey` FOREIGN KEY (`typebotIdFallback`) REFERENCES `Typebot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `TypebotSetting` ADD CONSTRAINT `TypebotSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Media` ADD CONSTRAINT `Media_messageId_fkey` FOREIGN KEY (`messageId`) REFERENCES `Message`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Media` ADD CONSTRAINT `Media_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiCreds` ADD CONSTRAINT `OpenaiCreds_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiBot` ADD CONSTRAINT `OpenaiBot_openaiCredsId_fkey` FOREIGN KEY (`openaiCredsId`) REFERENCES `OpenaiCreds`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiBot` ADD CONSTRAINT `OpenaiBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiSession` ADD CONSTRAINT `OpenaiSession_openaiBotId_fkey` FOREIGN KEY (`openaiBotId`) REFERENCES `OpenaiBot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiSession` ADD CONSTRAINT `OpenaiSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_openaiCredsId_fkey` FOREIGN KEY (`openaiCredsId`) REFERENCES `OpenaiCreds`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_openaiIdFallback_fkey` FOREIGN KEY (`openaiIdFallback`) REFERENCES `OpenaiBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Template` ADD CONSTRAINT `Template_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Dify` ADD CONSTRAINT `Dify_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `DifySession` ADD CONSTRAINT `DifySession_difyId_fkey` FOREIGN KEY (`difyId`) REFERENCES `Dify`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `DifySession` ADD CONSTRAINT `DifySession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `DifySetting` ADD CONSTRAINT `DifySetting_difyIdFallback_fkey` FOREIGN KEY (`difyIdFallback`) REFERENCES `Dify`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `DifySetting` ADD CONSTRAINT `DifySetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,173 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Contact` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE `Chat`
ADD COLUMN `name` VARCHAR(100) NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySession`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance`
MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Label`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSession`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session`
MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSession`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `TypebotSetting`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket`
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX `Contact_remoteJid_instanceId_key` ON `Contact` (`remoteJid`, `instanceId`);

View File

@@ -0,0 +1,150 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- DropIndex
DROP INDEX `Label_labelId_key` ON `Label`;
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` ADD COLUMN `ignoreJids` JSON NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;

View File

@@ -0,0 +1,208 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the column `difySessionId` on the `Message` table. All the data in the column will be lost.
- You are about to drop the column `openaiSessionId` on the `Message` table. All the data in the column will be lost.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the `DifySession` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `OpenaiSession` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `TypebotSession` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE `DifySession` DROP FOREIGN KEY `DifySession_difyId_fkey`;
-- DropForeignKey
ALTER TABLE `DifySession` DROP FOREIGN KEY `DifySession_instanceId_fkey`;
-- DropForeignKey
ALTER TABLE `Message` DROP FOREIGN KEY `Message_difySessionId_fkey`;
-- DropForeignKey
ALTER TABLE `Message` DROP FOREIGN KEY `Message_openaiSessionId_fkey`;
-- DropForeignKey
ALTER TABLE `Message` DROP FOREIGN KEY `Message_typebotSessionId_fkey`;
-- DropForeignKey
ALTER TABLE `OpenaiSession` DROP FOREIGN KEY `OpenaiSession_instanceId_fkey`;
-- DropForeignKey
ALTER TABLE `OpenaiSession` DROP FOREIGN KEY `OpenaiSession_openaiBotId_fkey`;
-- DropForeignKey
ALTER TABLE `TypebotSession` DROP FOREIGN KEY `TypebotSession_instanceId_fkey`;
-- DropForeignKey
ALTER TABLE `TypebotSession` DROP FOREIGN KEY `TypebotSession_typebotId_fkey`;
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Message` DROP COLUMN `difySessionId`,
DROP COLUMN `openaiSessionId`,
ADD COLUMN `sessionId` VARCHAR(191) NULL;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- DropTable
DROP TABLE `DifySession`;
-- DropTable
DROP TABLE `OpenaiSession`;
-- DropTable
DROP TABLE `TypebotSession`;
-- CreateTable
CREATE TABLE `IntegrationSession` (
`id` VARCHAR(191) NOT NULL,
`sessionId` VARCHAR(255) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`pushName` VARCHAR(191) NULL,
`status` ENUM('opened', 'closed', 'paused') NOT NULL,
`awaitUser` BOOLEAN NOT NULL DEFAULT false,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
`parameters` JSON NULL,
`openaiBotId` VARCHAR(191) NULL,
`difyId` VARCHAR(191) NULL,
`typebotId` VARCHAR(191) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_sessionId_fkey` FOREIGN KEY (`sessionId`) REFERENCES `IntegrationSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_openaiBotId_fkey` FOREIGN KEY (`openaiBotId`) REFERENCES `OpenaiBot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_difyId_fkey` FOREIGN KEY (`difyId`) REFERENCES `Dify`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_typebotId_fkey` FOREIGN KEY (`typebotId`) REFERENCES `Typebot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,269 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the column `difyId` on the `IntegrationSession` table. All the data in the column will be lost.
- You are about to drop the column `openaiBotId` on the `IntegrationSession` table. All the data in the column will be lost.
- You are about to drop the column `typebotId` on the `IntegrationSession` table. All the data in the column will be lost.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- DropForeignKey
ALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_difyId_fkey`;
-- DropForeignKey
ALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_openaiBotId_fkey`;
-- DropForeignKey
ALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_typebotId_fkey`;
-- DropIndex
DROP INDEX `Message_typebotSessionId_fkey` ON `Message`;
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` DROP COLUMN `difyId`,
DROP COLUMN `openaiBotId`,
DROP COLUMN `typebotId`,
ADD COLUMN `botId` VARCHAR(191) NULL,
ADD COLUMN `context` JSON NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL,
MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateTable
CREATE TABLE `GenericBot` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`apiUrl` VARCHAR(255) NULL,
`apiKey` VARCHAR(255) NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `GenericSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`botIdFallback` VARCHAR(100) NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `GenericSetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Flowise` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`apiUrl` VARCHAR(255) NULL,
`apiKey` VARCHAR(255) NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `FlowiseSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`flowiseIdFallback` VARCHAR(100) NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `FlowiseSetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `GenericBot` ADD CONSTRAINT `GenericBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `GenericSetting` ADD CONSTRAINT `GenericSetting_botIdFallback_fkey` FOREIGN KEY (`botIdFallback`) REFERENCES `GenericBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `GenericSetting` ADD CONSTRAINT `GenericSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Flowise` ADD CONSTRAINT `Flowise_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `FlowiseSetting` ADD CONSTRAINT `FlowiseSetting_flowiseIdFallback_fkey` FOREIGN KEY (`flowiseIdFallback`) REFERENCES `Flowise`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `FlowiseSetting` ADD CONSTRAINT `FlowiseSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,159 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `GenericBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `GenericBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `GenericSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `GenericSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `GenericBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `GenericSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` ADD COLUMN `type` VARCHAR(100) NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;

View File

@@ -0,0 +1,219 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the `GenericBot` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `GenericSetting` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE `GenericBot` DROP FOREIGN KEY `GenericBot_instanceId_fkey`;
-- DropForeignKey
ALTER TABLE `GenericSetting` DROP FOREIGN KEY `GenericSetting_botIdFallback_fkey`;
-- DropForeignKey
ALTER TABLE `GenericSetting` DROP FOREIGN KEY `GenericSetting_instanceId_fkey`;
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- DropTable
DROP TABLE `GenericBot`;
-- DropTable
DROP TABLE `GenericSetting`;
-- CreateTable
CREATE TABLE `EvolutionBot` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255) NULL,
`apiUrl` VARCHAR(255) NULL,
`apiKey` VARCHAR(255) NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `EvolutionBotSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER NULL DEFAULT 0,
`keywordFinish` VARCHAR(100) NULL,
`delayMessage` INTEGER NULL,
`unknownMessage` VARCHAR(100) NULL,
`listeningFromMe` BOOLEAN NULL DEFAULT false,
`stopBotFromMe` BOOLEAN NULL DEFAULT false,
`keepOpen` BOOLEAN NULL DEFAULT false,
`debounceTime` INTEGER NULL,
`ignoreJids` JSON NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`botIdFallback` VARCHAR(100) NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `EvolutionBotSetting_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `EvolutionBot` ADD CONSTRAINT `EvolutionBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `EvolutionBotSetting` ADD CONSTRAINT `EvolutionBotSetting_botIdFallback_fkey` FOREIGN KEY (`botIdFallback`) REFERENCES `EvolutionBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `EvolutionBotSetting` ADD CONSTRAINT `EvolutionBotSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,174 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Message` ADD COLUMN `status` INTEGER NULL;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` ADD COLUMN `headers` JSON NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateTable
CREATE TABLE `IsOnWhatsapp` (
`id` VARCHAR(191) NOT NULL,
`remoteJid` VARCHAR(100) NOT NULL,
`jidOptions` VARCHAR(191) NOT NULL,
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
UNIQUE INDEX `IsOnWhatsapp_remoteJid_key`(`remoteJid`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@@ -0,0 +1,232 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- AlterTable
ALTER TABLE `Chat` ADD COLUMN `unreadMessages` INTEGER NOT NULL DEFAULT 0,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBot` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBotSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `IsOnWhatsapp` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Message` MODIFY `status` VARCHAR(30) NULL;
-- AlterTable
ALTER TABLE `OpenaiBot` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,
ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateTable
CREATE TABLE `Pusher` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`appId` VARCHAR(100) NOT NULL,
`key` VARCHAR(100) NOT NULL,
`secret` VARCHAR(100) NOT NULL,
`cluster` VARCHAR(100) NOT NULL,
`useTLS` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Pusher_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateIndex
CREATE INDEX `Chat_remoteJid_idx` ON `Chat`(`remoteJid`);
-- CreateIndex
CREATE INDEX `Contact_remoteJid_idx` ON `Contact`(`remoteJid`);
-- CreateIndex
CREATE INDEX `Setting_instanceId_idx` ON `Setting`(`instanceId`);
-- CreateIndex
CREATE INDEX `Webhook_instanceId_idx` ON `Webhook`(`instanceId`);
-- AddForeignKey
ALTER TABLE `Pusher` ADD CONSTRAINT `Pusher_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- RenameIndex
ALTER TABLE `Chat` RENAME INDEX `Chat_instanceId_fkey` TO `Chat_instanceId_idx`;
-- RenameIndex
ALTER TABLE `Contact` RENAME INDEX `Contact_instanceId_fkey` TO `Contact_instanceId_idx`;
-- RenameIndex
ALTER TABLE `Message` RENAME INDEX `Message_instanceId_fkey` TO `Message_instanceId_idx`;
-- RenameIndex
ALTER TABLE `MessageUpdate` RENAME INDEX `MessageUpdate_instanceId_fkey` TO `MessageUpdate_instanceId_idx`;
-- RenameIndex
ALTER TABLE `MessageUpdate` RENAME INDEX `MessageUpdate_messageId_fkey` TO `MessageUpdate_messageId_idx`;

View File

@@ -0,0 +1,175 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- A unique constraint covering the columns `[instanceId,remoteJid]` on the table `Chat` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `IsOnWhatsapp` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Pusher` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` ADD COLUMN `wavoipToken` VARCHAR(100) NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX `Chat_instanceId_remoteJid_key` ON `Chat`(`instanceId`, `remoteJid`);

View File

@@ -0,0 +1,17 @@
-- CreateTable
CREATE TABLE `Nats` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateIndex
CREATE UNIQUE INDEX `Nats_instanceId_key` ON `Nats`(`instanceId`);
-- AddForeignKey
ALTER TABLE `Nats` ADD CONSTRAINT `Nats_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,26 @@
/*
Warnings:
- A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Chat` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
SET @column_exists := (
SELECT COUNT(*)
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = 'Setting'
AND column_name = 'wavoipToken'
);
SET @sql := IF(@column_exists = 0,
'ALTER TABLE Setting ADD COLUMN wavoipToken VARCHAR(100);',
'SELECT "Column already exists";'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
ALTER TABLE Chat ADD CONSTRAINT unique_remote_instance UNIQUE (remoteJid, instanceId);

View File

@@ -0,0 +1,62 @@
-- CreateTable
CREATE TABLE `N8n` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255),
`webhookUrl` VARCHAR(255),
`basicAuthUser` VARCHAR(255),
`basicAuthPass` VARCHAR(255),
`expire` INTEGER DEFAULT 0,
`keywordFinish` VARCHAR(100),
`delayMessage` INTEGER,
`unknownMessage` VARCHAR(100),
`listeningFromMe` BOOLEAN DEFAULT false,
`stopBotFromMe` BOOLEAN DEFAULT false,
`keepOpen` BOOLEAN DEFAULT false,
`debounceTime` INTEGER,
`ignoreJids` JSON,
`splitMessages` BOOLEAN DEFAULT false,
`timePerChar` INTEGER DEFAULT 50,
`triggerType` ENUM('all', 'keyword', 'none') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `N8nSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER DEFAULT 0,
`keywordFinish` VARCHAR(100),
`delayMessage` INTEGER,
`unknownMessage` VARCHAR(100),
`listeningFromMe` BOOLEAN DEFAULT false,
`stopBotFromMe` BOOLEAN DEFAULT false,
`keepOpen` BOOLEAN DEFAULT false,
`debounceTime` INTEGER,
`ignoreJids` JSON,
`splitMessages` BOOLEAN DEFAULT false,
`timePerChar` INTEGER DEFAULT 50,
`createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`n8nIdFallback` VARCHAR(100),
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateIndex
CREATE UNIQUE INDEX `N8nSetting_instanceId_key` ON `N8nSetting`(`instanceId`);
-- AddForeignKey
ALTER TABLE `N8n` ADD CONSTRAINT `N8n_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `N8nSetting` ADD CONSTRAINT `N8nSetting_n8nIdFallback_fkey` FOREIGN KEY (`n8nIdFallback`) REFERENCES `N8n`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `N8nSetting` ADD CONSTRAINT `N8nSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,61 @@
-- CreateTable
CREATE TABLE `Evoai` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT true,
`description` VARCHAR(255),
`agentUrl` VARCHAR(255),
`apiKey` VARCHAR(255),
`expire` INTEGER DEFAULT 0,
`keywordFinish` VARCHAR(100),
`delayMessage` INTEGER,
`unknownMessage` VARCHAR(100),
`listeningFromMe` BOOLEAN DEFAULT false,
`stopBotFromMe` BOOLEAN DEFAULT false,
`keepOpen` BOOLEAN DEFAULT false,
`debounceTime` INTEGER,
`ignoreJids` JSON,
`splitMessages` BOOLEAN DEFAULT false,
`timePerChar` INTEGER DEFAULT 50,
`triggerType` ENUM('all', 'keyword', 'none') NULL,
`triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,
`triggerValue` VARCHAR(191) NULL,
`createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `EvoaiSetting` (
`id` VARCHAR(191) NOT NULL,
`expire` INTEGER DEFAULT 0,
`keywordFinish` VARCHAR(100),
`delayMessage` INTEGER,
`unknownMessage` VARCHAR(100),
`listeningFromMe` BOOLEAN DEFAULT false,
`stopBotFromMe` BOOLEAN DEFAULT false,
`keepOpen` BOOLEAN DEFAULT false,
`debounceTime` INTEGER,
`ignoreJids` JSON,
`splitMessages` BOOLEAN DEFAULT false,
`timePerChar` INTEGER DEFAULT 50,
`createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`evoaiIdFallback` VARCHAR(100),
`instanceId` VARCHAR(191) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateIndex
CREATE UNIQUE INDEX `EvoaiSetting_instanceId_key` ON `EvoaiSetting`(`instanceId`);
-- AddForeignKey
ALTER TABLE `Evoai` ADD CONSTRAINT `Evoai_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `EvoaiSetting` ADD CONSTRAINT `EvoaiSetting_evoaiIdFallback_fkey` FOREIGN KEY (`evoaiIdFallback`) REFERENCES `Evoai`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `EvoaiSetting` ADD CONSTRAINT `EvoaiSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,2 @@
-- DropIndex
ALTER TABLE `Media` DROP INDEX `Media_fileName_key`;

View File

@@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE `Typebot` ADD COLUMN `splitMessages` BOOLEAN DEFAULT false,
ADD COLUMN `timePerChar` INTEGER DEFAULT 50;
-- AlterTable
ALTER TABLE `TypebotSetting` ADD COLUMN `splitMessages` BOOLEAN DEFAULT false,
ADD COLUMN `timePerChar` INTEGER DEFAULT 50;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `IsOnWhatsapp` ADD COLUMN `lid` VARCHAR(100);

View File

@@ -0,0 +1,231 @@
/*
Warnings:
- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Evoai` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Evoai` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvoaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvoaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the column `lid` on the `IsOnWhatsapp` table. All the data in the column will be lost.
- You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `N8n` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `N8n` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `N8nSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `N8nSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Nats` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Nats` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the column `splitMessages` on the `Typebot` table. All the data in the column will be lost.
- You are about to drop the column `timePerChar` on the `Typebot` table. All the data in the column will be lost.
- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to drop the column `splitMessages` on the `TypebotSetting` table. All the data in the column will be lost.
- You are about to drop the column `timePerChar` on the `TypebotSetting` table. All the data in the column will be lost.
- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.
*/
-- DropIndex
DROP INDEX `unique_remote_instance` ON `Chat`;
-- AlterTable
ALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Evoai` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvoaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `IsOnWhatsapp` DROP COLUMN `lid`,
MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `N8n` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `N8nSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Nats` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Pusher` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Typebot` DROP COLUMN `splitMessages`,
DROP COLUMN `timePerChar`,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NULL;
-- AlterTable
ALTER TABLE `TypebotSetting` DROP COLUMN `splitMessages`,
DROP COLUMN `timePerChar`,
MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- AlterTable
ALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
MODIFY `updatedAt` TIMESTAMP NOT NULL;
-- CreateTable
CREATE TABLE `Kafka` (
`id` VARCHAR(191) NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT false,
`events` JSON NOT NULL,
`createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` TIMESTAMP NOT NULL,
`instanceId` VARCHAR(191) NOT NULL,
UNIQUE INDEX `Kafka_instanceId_key`(`instanceId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Kafka` ADD CONSTRAINT `Kafka_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "mysql"

757
prisma/mysql-schema.prisma Normal file
View File

@@ -0,0 +1,757 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_CONNECTION_URI")
}
enum InstanceConnectionStatus {
open
close
connecting
}
enum DeviceMessage {
ios
android
web
unknown
desktop
}
enum SessionStatus {
opened
closed
paused
}
enum TriggerType {
all
keyword
none
advanced
}
enum TriggerOperator {
contains
equals
startsWith
endsWith
regex
}
enum OpenaiBotType {
assistant
chatCompletion
}
enum DifyBotType {
chatBot
textGenerator
agent
workflow
}
model Instance {
id String @id @default(cuid())
name String @unique @db.VarChar(255)
connectionStatus InstanceConnectionStatus @default(open)
ownerJid String? @db.VarChar(100)
profileName String? @db.VarChar(100)
profilePicUrl String? @db.VarChar(500)
integration String? @db.VarChar(100)
number String? @db.VarChar(100)
businessId String? @db.VarChar(100)
token String? @db.VarChar(255)
clientName String? @db.VarChar(100)
disconnectionReasonCode Int? @db.Int
disconnectionObject Json? @db.Json
disconnectionAt DateTime? @db.Timestamp
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime? @updatedAt @db.Timestamp
Chat Chat[]
Contact Contact[]
Message Message[]
Webhook Webhook?
Chatwoot Chatwoot?
Label Label[]
Proxy Proxy?
Setting Setting?
Rabbitmq Rabbitmq?
Nats Nats?
Sqs Sqs?
Kafka Kafka?
Websocket Websocket?
Typebot Typebot[]
Session Session?
MessageUpdate MessageUpdate[]
TypebotSetting TypebotSetting?
Media Media[]
OpenaiCreds OpenaiCreds[]
OpenaiBot OpenaiBot[]
OpenaiSetting OpenaiSetting?
Template Template[]
Dify Dify[]
DifySetting DifySetting?
IntegrationSession IntegrationSession[]
EvolutionBot EvolutionBot[]
EvolutionBotSetting EvolutionBotSetting?
Flowise Flowise[]
FlowiseSetting FlowiseSetting?
N8n N8n[]
N8nSetting N8nSetting?
Evoai Evoai[]
EvoaiSetting EvoaiSetting?
Pusher Pusher?
}
model Session {
id String @id @default(cuid())
sessionId String @unique
creds String? @db.Text
createdAt DateTime @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
Instance Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade)
}
model Chat {
id String @id @default(cuid())
remoteJid String @db.VarChar(100)
name String? @db.VarChar(100)
labels Json? @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime? @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
unreadMessages Int @default(0)
@@unique([instanceId, remoteJid])
@@index([instanceId])
@@index([remoteJid])
}
model Contact {
id String @id @default(cuid())
remoteJid String @db.VarChar(100)
pushName String? @db.VarChar(100)
profilePicUrl String? @db.VarChar(500)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime? @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
@@unique([remoteJid, instanceId])
@@index([remoteJid])
@@index([instanceId])
}
model Message {
id String @id @default(cuid())
key Json @db.Json
pushName String? @db.VarChar(100)
participant String? @db.VarChar(100)
messageType String @db.VarChar(100)
message Json @db.Json
contextInfo Json? @db.Json
source DeviceMessage
messageTimestamp Int @db.Int
chatwootMessageId Int? @db.Int
chatwootInboxId Int? @db.Int
chatwootConversationId Int? @db.Int
chatwootContactInboxSourceId String? @db.VarChar(100)
chatwootIsRead Boolean? @default(false)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
typebotSessionId String?
MessageUpdate MessageUpdate[]
Media Media?
webhookUrl String? @db.VarChar(500)
status String? @db.VarChar(30)
sessionId String?
session IntegrationSession? @relation(fields: [sessionId], references: [id])
@@index([instanceId])
}
model MessageUpdate {
id String @id @default(cuid())
keyId String @db.VarChar(100)
remoteJid String @db.VarChar(100)
fromMe Boolean
participant String? @db.VarChar(100)
pollUpdates Json? @db.Json
status String @db.VarChar(30)
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
messageId String
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
@@index([instanceId])
@@index([messageId])
}
model Webhook {
id String @id @default(cuid())
url String @db.VarChar(500)
headers Json? @db.Json
enabled Boolean? @default(true)
events Json? @db.Json
webhookByEvents Boolean? @default(false)
webhookBase64 Boolean? @default(false)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
@@index([instanceId])
}
model Chatwoot {
id String @id @default(cuid())
enabled Boolean? @default(true)
accountId String? @db.VarChar(100)
token String? @db.VarChar(100)
url String? @db.VarChar(500)
nameInbox String? @db.VarChar(100)
signMsg Boolean? @default(false)
signDelimiter String? @db.VarChar(100)
number String? @db.VarChar(100)
reopenConversation Boolean? @default(false)
conversationPending Boolean? @default(false)
mergeBrazilContacts Boolean? @default(false)
importContacts Boolean? @default(false)
importMessages Boolean? @default(false)
daysLimitImportMessages Int? @db.Int
organization String? @db.VarChar(100)
logo String? @db.VarChar(500)
ignoreJids Json?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Label {
id String @id @default(cuid())
labelId String? @db.VarChar(100)
name String @db.VarChar(100)
color String @db.VarChar(100)
predefinedId String? @db.VarChar(100)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
}
model Proxy {
id String @id @default(cuid())
enabled Boolean @default(false)
host String @db.VarChar(100)
port String @db.VarChar(100)
protocol String @db.VarChar(100)
username String @db.VarChar(100)
password String @db.VarChar(100)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Setting {
id String @id @default(cuid())
rejectCall Boolean @default(false)
msgCall String? @db.VarChar(100)
groupsIgnore Boolean @default(false)
alwaysOnline Boolean @default(false)
readMessages Boolean @default(false)
readStatus Boolean @default(false)
syncFullHistory Boolean @default(false)
wavoipToken String? @db.VarChar(100)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
@@index([instanceId])
}
model Rabbitmq {
id String @id @default(cuid())
enabled Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Nats {
id String @id @default(cuid())
enabled Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Sqs {
id String @id @default(cuid())
enabled Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Kafka {
id String @id @default(cuid())
enabled Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Websocket {
id String @id @default(cuid())
enabled Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Pusher {
id String @id @default(cuid())
enabled Boolean @default(false)
appId String @db.VarChar(100)
key String @db.VarChar(100)
secret String @db.VarChar(100)
cluster String @db.VarChar(100)
useTLS Boolean @default(false)
events Json @db.Json
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Typebot {
id String @id @default(cuid())
enabled Boolean @default(true)
description String? @db.VarChar(255)
url String @db.VarChar(500)
typebot String @db.VarChar(100)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime? @updatedAt @db.Timestamp
ignoreJids Json?
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
TypebotSetting TypebotSetting[]
}
model TypebotSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
typebotIdFallback String? @db.VarChar(100)
ignoreJids Json?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback Typebot? @relation(fields: [typebotIdFallback], references: [id])
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model IntegrationSession {
id String @id @default(cuid())
sessionId String @db.VarChar(255)
remoteJid String @db.VarChar(100)
pushName String?
status SessionStatus
awaitUser Boolean @default(false)
context Json?
type String? @db.VarChar(100)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Message Message[]
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
parameters Json?
botId String?
}
model Media {
id String @id @default(cuid())
fileName String @db.VarChar(500)
type String @db.VarChar(100)
mimetype String @db.VarChar(100)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
messageId String @unique
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
}
model OpenaiCreds {
id String @id @default(cuid())
name String? @unique @db.VarChar(255)
apiKey String? @unique @db.VarChar(255)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
OpenaiAssistant OpenaiBot[]
OpenaiSetting OpenaiSetting?
}
model OpenaiBot {
id String @id @default(cuid())
enabled Boolean @default(true)
description String? @db.VarChar(255)
botType OpenaiBotType
assistantId String? @db.VarChar(255)
functionUrl String? @db.VarChar(500)
model String? @db.VarChar(100)
systemMessages Json? @db.Json
assistantMessages Json? @db.Json
userMessages Json? @db.Json
maxTokens Int? @db.Int
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiCreds OpenaiCreds @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)
openaiCredsId String
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
OpenaiSetting OpenaiSetting[]
}
model OpenaiSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
speechToText Boolean? @default(false)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiCreds OpenaiCreds? @relation(fields: [openaiCredsId], references: [id])
openaiCredsId String @unique
Fallback OpenaiBot? @relation(fields: [openaiIdFallback], references: [id])
openaiIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Template {
id String @id @default(cuid())
templateId String @unique @db.VarChar(255)
name String @unique @db.VarChar(255)
template Json @db.Json
webhookUrl String? @db.VarChar(500)
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
}
model Dify {
id String @id @default(cuid())
enabled Boolean @default(true)
description String? @db.VarChar(255)
botType DifyBotType
apiUrl String? @db.VarChar(255)
apiKey String? @db.VarChar(255)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
DifySetting DifySetting[]
}
model DifySetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback Dify? @relation(fields: [difyIdFallback], references: [id])
difyIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model EvolutionBot {
id String @id @default(cuid())
enabled Boolean @default(true)
description String? @db.VarChar(255)
apiUrl String? @db.VarChar(255)
apiKey String? @db.VarChar(255)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
EvolutionBotSetting EvolutionBotSetting[]
}
model EvolutionBotSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback EvolutionBot? @relation(fields: [botIdFallback], references: [id])
botIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Flowise {
id String @id @default(cuid())
enabled Boolean @default(true)
description String? @db.VarChar(255)
apiUrl String? @db.VarChar(255)
apiKey String? @db.VarChar(255)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
FlowiseSetting FlowiseSetting[]
}
model FlowiseSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback Flowise? @relation(fields: [flowiseIdFallback], references: [id])
flowiseIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model IsOnWhatsapp {
id String @id @default(cuid())
remoteJid String @unique @db.VarChar(100)
jidOptions String
createdAt DateTime @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
}
model N8n {
id String @id @default(cuid())
enabled Boolean @default(true) @db.TinyInt()
description String? @db.VarChar(255)
webhookUrl String? @db.VarChar(255)
basicAuthUser String? @db.VarChar(255)
basicAuthPass String? @db.VarChar(255)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
N8nSetting N8nSetting[]
}
model N8nSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback N8n? @relation(fields: [n8nIdFallback], references: [id])
n8nIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}
model Evoai {
id String @id @default(cuid())
enabled Boolean @default(true) @db.TinyInt()
description String? @db.VarChar(255)
agentUrl String? @db.VarChar(255)
apiKey String? @db.VarChar(255)
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
EvoaiSetting EvoaiSetting[]
}
model EvoaiSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Int
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Int
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false)
stopBotFromMe Boolean? @default(false)
keepOpen Boolean? @default(false)
debounceTime Int? @db.Int
ignoreJids Json?
splitMessages Boolean? @default(false)
timePerChar Int? @default(50) @db.Int
createdAt DateTime? @default(dbgenerated("CURRENT_TIMESTAMP")) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Fallback Evoai? @relation(fields: [evoaiIdFallback], references: [id])
evoaiIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}

View File

@@ -0,0 +1,375 @@
-- CreateEnum
CREATE TYPE "InstanceConnectionStatus" AS ENUM ('open', 'close', 'connecting');
-- CreateEnum
CREATE TYPE "DeviceMessage" AS ENUM ('ios', 'android', 'web', 'unknown', 'desktop');
-- CreateEnum
CREATE TYPE "TypebotSessionStatus" AS ENUM ('open', 'closed', 'paused');
-- CreateEnum
CREATE TYPE "TriggerType" AS ENUM ('all', 'keyword');
-- CreateEnum
CREATE TYPE "TriggerOperator" AS ENUM ('contains', 'equals', 'startsWith', 'endsWith');
-- CreateTable
CREATE TABLE "Instance" (
"id" TEXT NOT NULL,
"name" VARCHAR(255) NOT NULL,
"connectionStatus" "InstanceConnectionStatus" NOT NULL DEFAULT 'open',
"ownerJid" VARCHAR(100),
"profilePicUrl" VARCHAR(500),
"integration" VARCHAR(100),
"number" VARCHAR(100),
"token" VARCHAR(255),
"clientName" VARCHAR(100),
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP,
CONSTRAINT "Instance_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"sessionId" TEXT NOT NULL,
"creds" TEXT,
"createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Chat" (
"id" TEXT NOT NULL,
"remoteJid" VARCHAR(100) NOT NULL,
"labels" JSONB,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Chat_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Contact" (
"id" TEXT NOT NULL,
"remoteJid" VARCHAR(100) NOT NULL,
"pushName" VARCHAR(100),
"profilePicUrl" VARCHAR(500),
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Contact_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Message" (
"id" TEXT NOT NULL,
"key" JSONB NOT NULL,
"pushName" VARCHAR(100),
"participant" VARCHAR(100),
"messageType" VARCHAR(100) NOT NULL,
"message" JSONB NOT NULL,
"contextInfo" JSONB,
"source" "DeviceMessage" NOT NULL,
"messageTimestamp" INTEGER NOT NULL,
"chatwootMessageId" INTEGER,
"chatwootInboxId" INTEGER,
"chatwootConversationId" INTEGER,
"chatwootContactInboxSourceId" VARCHAR(100),
"chatwootIsRead" BOOLEAN,
"instanceId" TEXT NOT NULL,
"typebotSessionId" TEXT,
CONSTRAINT "Message_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MessageUpdate" (
"id" TEXT NOT NULL,
"keyId" VARCHAR(100) NOT NULL,
"remoteJid" VARCHAR(100) NOT NULL,
"fromMe" BOOLEAN NOT NULL,
"participant" VARCHAR(100),
"pollUpdates" JSONB,
"status" VARCHAR(30) NOT NULL,
"messageId" TEXT NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "MessageUpdate_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Webhook" (
"id" TEXT NOT NULL,
"url" VARCHAR(500) NOT NULL,
"enabled" BOOLEAN DEFAULT true,
"events" JSONB,
"webhookByEvents" BOOLEAN DEFAULT false,
"webhookBase64" BOOLEAN DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Webhook_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Chatwoot" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN DEFAULT true,
"accountId" VARCHAR(100),
"token" VARCHAR(100),
"url" VARCHAR(500),
"nameInbox" VARCHAR(100),
"signMsg" BOOLEAN DEFAULT false,
"signDelimiter" VARCHAR(100),
"number" VARCHAR(100),
"reopenConversation" BOOLEAN DEFAULT false,
"conversationPending" BOOLEAN DEFAULT false,
"mergeBrazilContacts" BOOLEAN DEFAULT false,
"importContacts" BOOLEAN DEFAULT false,
"importMessages" BOOLEAN DEFAULT false,
"daysLimitImportMessages" INTEGER,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Chatwoot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Label" (
"id" TEXT NOT NULL,
"labelId" VARCHAR(100),
"name" VARCHAR(100) NOT NULL,
"color" VARCHAR(100) NOT NULL,
"predefinedId" VARCHAR(100),
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Label_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Proxy" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"host" VARCHAR(100) NOT NULL,
"port" VARCHAR(100) NOT NULL,
"protocol" VARCHAR(100) NOT NULL,
"username" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Proxy_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Setting" (
"id" TEXT NOT NULL,
"rejectCall" BOOLEAN NOT NULL DEFAULT false,
"msgCall" VARCHAR(100),
"groupsIgnore" BOOLEAN NOT NULL DEFAULT false,
"alwaysOnline" BOOLEAN NOT NULL DEFAULT false,
"readMessages" BOOLEAN NOT NULL DEFAULT false,
"readStatus" BOOLEAN NOT NULL DEFAULT false,
"syncFullHistory" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Setting_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Rabbitmq" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"events" JSONB NOT NULL,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Rabbitmq_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Sqs" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"events" JSONB NOT NULL,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Sqs_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Websocket" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT false,
"events" JSONB NOT NULL,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Websocket_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Typebot" (
"id" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"url" VARCHAR(500) NOT NULL,
"typebot" VARCHAR(100) NOT NULL,
"expire" INTEGER DEFAULT 0,
"keywordFinish" VARCHAR(100),
"delayMessage" INTEGER,
"unknownMessage" VARCHAR(100),
"listeningFromMe" BOOLEAN DEFAULT false,
"stopBotFromMe" BOOLEAN DEFAULT false,
"keepOpen" BOOLEAN DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP,
"triggerType" "TriggerType",
"triggerOperator" "TriggerOperator",
"triggerValue" TEXT,
"instanceId" TEXT NOT NULL,
CONSTRAINT "Typebot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TypebotSession" (
"id" TEXT NOT NULL,
"remoteJid" VARCHAR(100) NOT NULL,
"pushName" VARCHAR(100),
"sessionId" VARCHAR(100) NOT NULL,
"status" VARCHAR(100) NOT NULL,
"prefilledVariables" JSONB,
"awaitUser" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"typebotId" TEXT NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "TypebotSession_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TypebotSetting" (
"id" TEXT NOT NULL,
"expire" INTEGER DEFAULT 0,
"keywordFinish" VARCHAR(100),
"delayMessage" INTEGER,
"unknownMessage" VARCHAR(100),
"listeningFromMe" BOOLEAN DEFAULT false,
"stopBotFromMe" BOOLEAN DEFAULT false,
"keepOpen" BOOLEAN DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "TypebotSetting_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Instance_name_key" ON "Instance"("name");
-- CreateIndex
CREATE UNIQUE INDEX "Instance_token_key" ON "Instance"("token");
-- CreateIndex
CREATE UNIQUE INDEX "Session_sessionId_key" ON "Session"("sessionId");
-- CreateIndex
CREATE UNIQUE INDEX "Webhook_instanceId_key" ON "Webhook"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Chatwoot_instanceId_key" ON "Chatwoot"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Label_labelId_key" ON "Label"("labelId");
-- CreateIndex
CREATE UNIQUE INDEX "Proxy_instanceId_key" ON "Proxy"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Setting_instanceId_key" ON "Setting"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Rabbitmq_instanceId_key" ON "Rabbitmq"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Sqs_instanceId_key" ON "Sqs"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "Websocket_instanceId_key" ON "Websocket"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "TypebotSetting_instanceId_key" ON "TypebotSetting"("instanceId");
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Chat" ADD CONSTRAINT "Chat_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Contact" ADD CONSTRAINT "Contact_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Message" ADD CONSTRAINT "Message_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Message" ADD CONSTRAINT "Message_typebotSessionId_fkey" FOREIGN KEY ("typebotSessionId") REFERENCES "TypebotSession"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MessageUpdate" ADD CONSTRAINT "MessageUpdate_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "Message"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MessageUpdate" ADD CONSTRAINT "MessageUpdate_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Webhook" ADD CONSTRAINT "Webhook_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Chatwoot" ADD CONSTRAINT "Chatwoot_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Label" ADD CONSTRAINT "Label_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Proxy" ADD CONSTRAINT "Proxy_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Setting" ADD CONSTRAINT "Setting_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Rabbitmq" ADD CONSTRAINT "Rabbitmq_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Sqs" ADD CONSTRAINT "Sqs_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Websocket" ADD CONSTRAINT "Websocket_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Typebot" ADD CONSTRAINT "Typebot_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TypebotSession" ADD CONSTRAINT "TypebotSession_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TypebotSession" ADD CONSTRAINT "TypebotSession_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TypebotSetting" ADD CONSTRAINT "TypebotSetting_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Instance" ADD COLUMN "profileName" VARCHAR(100);

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Chatwoot" ADD COLUMN "logo" VARCHAR(500),
ADD COLUMN "organization" VARCHAR(100);

Some files were not shown because too many files have changed in this diff Show More