mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-16 04:02:54 -06:00
feat: prisma
This commit is contained in:
parent
8eced6c575
commit
272bed1351
137
.env.example
Normal file
137
.env.example
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
SERVER_TYPE=http
|
||||||
|
SERVER_PORT=8080
|
||||||
|
SERVER_URL=http://localhost:8080
|
||||||
|
|
||||||
|
CORS_ORIGIN=*
|
||||||
|
CORS_METHODS=GET,POST,PUT,DELETE
|
||||||
|
CORS_CREDENTIALS=true
|
||||||
|
|
||||||
|
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS
|
||||||
|
LOG_COLOR=true
|
||||||
|
LOG_BAILEYS=error
|
||||||
|
|
||||||
|
DEL_INSTANCE=false
|
||||||
|
DEL_TEMP_INSTANCES=false
|
||||||
|
|
||||||
|
PROVIDER_ENABLED=true
|
||||||
|
PROVIDER_HOST=127.0.0.1
|
||||||
|
PROVIDER_PORT=5656
|
||||||
|
PROVIDER_PREFIX=evolution
|
||||||
|
|
||||||
|
STORE_MESSAGES=true
|
||||||
|
STORE_MESSAGE_UP=true
|
||||||
|
STORE_CONTACTS=true
|
||||||
|
STORE_CHATS=true
|
||||||
|
|
||||||
|
CLEAN_STORE_CLEANING_INTERVAL=7200
|
||||||
|
CLEAN_STORE_MESSAGES=true
|
||||||
|
CLEAN_STORE_MESSAGE_UP=true
|
||||||
|
CLEAN_STORE_CONTACTS=true
|
||||||
|
CLEAN_STORE_CHATS=true
|
||||||
|
|
||||||
|
DATABASE_ENABLED=false
|
||||||
|
DATABASE_PROVIDER=mongodb # postgresql, mysql, mongodb
|
||||||
|
DATABASE_CONNECTION_URI='mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true'
|
||||||
|
DATABASE_CONNECTION_DB_PREFIX_NAME=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
|
||||||
|
|
||||||
|
RABBITMQ_ENABLED=false
|
||||||
|
RABBITMQ_URI=amqp://localhost
|
||||||
|
RABBITMQ_EXCHANGE_NAME=evolution
|
||||||
|
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=false
|
||||||
|
RABBITMQ_EVENTS_MESSAGES_UPDATE=false
|
||||||
|
RABBITMQ_EVENTS_MESSAGES_DELETE=false
|
||||||
|
RABBITMQ_EVENTS_SEND_MESSAGE=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_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=v18.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_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
|
||||||
|
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
|
||||||
|
CONFIG_SESSION_PHONE_NAME=Chrome
|
||||||
|
CONFIG_SESSION_PHONE_VERSION='2,2413,1'
|
||||||
|
|
||||||
|
QRCODE_LIMIT=30
|
||||||
|
QRCODE_COLOR='#175197'
|
||||||
|
|
||||||
|
TYPEBOT_API_VERSION=latest
|
||||||
|
|
||||||
|
CHATWOOT_MESSAGE_DELETE=false
|
||||||
|
CHATWOOT_MESSAGE_READ=false
|
||||||
|
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://user:pass@host:5432/dbname
|
||||||
|
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=false
|
||||||
|
|
||||||
|
CACHE_REDIS_ENABLED=true
|
||||||
|
CACHE_REDIS_URI=redis://localhost:6379/6
|
||||||
|
CACHE_REDIS_PREFIX_KEY=evolution
|
||||||
|
CACHE_REDIS_SAVE_INSTANCES=false
|
||||||
|
CACHE_LOCAL_ENABLED=true
|
||||||
|
|
||||||
|
AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11
|
||||||
|
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
|
||||||
|
LANGUAGE=en
|
@ -116,13 +116,9 @@ WEBHOOK_EVENTS_CONNECTION_UPDATE=true
|
|||||||
WEBHOOK_EVENTS_LABELS_EDIT=true
|
WEBHOOK_EVENTS_LABELS_EDIT=true
|
||||||
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
|
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
|
||||||
WEBHOOK_EVENTS_CALL=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
|
# This events is used with Typebot
|
||||||
WEBHOOK_EVENTS_TYPEBOT_START=false
|
WEBHOOK_EVENTS_TYPEBOT_START=false
|
||||||
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=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
|
# This event is used to send errors
|
||||||
WEBHOOK_EVENTS_ERRORS=false
|
WEBHOOK_EVENTS_ERRORS=false
|
||||||
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
|
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
|
||||||
@ -157,18 +153,9 @@ CACHE_REDIS_SAVE_INSTANCES=false
|
|||||||
CACHE_LOCAL_ENABLED=false
|
CACHE_LOCAL_ENABLED=false
|
||||||
CACHE_LOCAL_TTL=604800
|
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.
|
## Define a global apikey to access all instances.
|
||||||
### OBS: This key must be inserted in the request header to create an instance.
|
### OBS: This key must be inserted in the request header to create an instance.
|
||||||
AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
|
AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
|
||||||
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
|
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
|
LANGUAGE=en # pt-BR, en
|
||||||
|
@ -75,8 +75,6 @@ WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
|
|||||||
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
|
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
|
||||||
WEBHOOK_EVENTS_LABELS_EDIT=true
|
WEBHOOK_EVENTS_LABELS_EDIT=true
|
||||||
WEBHOOK_EVENTS_LABELS_ASSOCIATION=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
|
# Name that will be displayed on smartphone connection
|
||||||
CONFIG_SESSION_PHONE_CLIENT='Evolution API'
|
CONFIG_SESSION_PHONE_CLIENT='Evolution API'
|
||||||
@ -94,26 +92,9 @@ CACHE_REDIS_SAVE_INSTANCES=false
|
|||||||
CACHE_LOCAL_ENABLED=false
|
CACHE_LOCAL_ENABLED=false
|
||||||
CACHE_LOCAL_TTL=604800
|
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.
|
## Define a global apikey to access all instances.
|
||||||
### OBS: This key must be inserted in the request header to create an instance.
|
### OBS: This key must be inserted in the request header to create an instance.
|
||||||
AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976'
|
AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976'
|
||||||
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
|
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
|
# 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
|
# 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=''
|
|
||||||
|
@ -133,13 +133,9 @@ ENV WEBHOOK_EVENTS_LABELS_EDIT=true
|
|||||||
ENV WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
|
ENV WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
|
||||||
ENV WEBHOOK_EVENTS_CALL=true
|
ENV WEBHOOK_EVENTS_CALL=true
|
||||||
|
|
||||||
ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
|
|
||||||
|
|
||||||
ENV WEBHOOK_EVENTS_TYPEBOT_START=false
|
ENV WEBHOOK_EVENTS_TYPEBOT_START=false
|
||||||
ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
|
ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
|
||||||
|
|
||||||
ENV WEBHOOK_EVENTS_CHAMA_AI_ACTION=false
|
|
||||||
|
|
||||||
ENV WEBHOOK_EVENTS_ERRORS=false
|
ENV WEBHOOK_EVENTS_ERRORS=false
|
||||||
ENV WEBHOOK_EVENTS_ERRORS_WEBHOOK=
|
ENV WEBHOOK_EVENTS_ERRORS_WEBHOOK=
|
||||||
|
|
||||||
@ -164,9 +160,6 @@ ENV AUTHENTICATION_TYPE=apikey
|
|||||||
ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
|
ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
|
||||||
ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
|
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_MODE=server
|
||||||
|
|
||||||
ENV AUTHENTICATION_INSTANCE_NAME=evolution
|
ENV AUTHENTICATION_INSTANCE_NAME=evolution
|
||||||
|
@ -42,19 +42,21 @@
|
|||||||
"homepage": "https://github.com/EvolutionAPI/evolution-api#readme",
|
"homepage": "https://github.com/EvolutionAPI/evolution-api#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adiwajshing/keyed-db": "^0.2.4",
|
"@adiwajshing/keyed-db": "^0.2.4",
|
||||||
|
"@aws-sdk/client-sqs": "^3.569.0",
|
||||||
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
||||||
"@figuro/chatwoot-sdk": "^1.1.16",
|
"@figuro/chatwoot-sdk": "^1.1.16",
|
||||||
"@hapi/boom": "^10.0.1",
|
"@hapi/boom": "^10.0.1",
|
||||||
|
"@prisma/client": "^5.15.0",
|
||||||
"@sentry/node": "^7.59.2",
|
"@sentry/node": "^7.59.2",
|
||||||
"amqplib": "^0.10.3",
|
|
||||||
"@aws-sdk/client-sqs": "^3.569.0",
|
|
||||||
"axios": "^1.6.5",
|
|
||||||
"@whiskeysockets/baileys": "6.7.4",
|
"@whiskeysockets/baileys": "6.7.4",
|
||||||
|
"amqplib": "^0.10.3",
|
||||||
|
"axios": "^1.6.5",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"eventemitter2": "^6.4.9",
|
"eventemitter2": "^6.4.9",
|
||||||
"evolution-manager": "^0.4.13",
|
"evolution-manager": "^0.4.13",
|
||||||
"exiftool-vendored": "^22.0.0",
|
"exiftool-vendored": "^22.0.0",
|
||||||
@ -85,7 +87,6 @@
|
|||||||
"sharp": "^0.32.2",
|
"sharp": "^0.32.2",
|
||||||
"socket.io": "^4.7.1",
|
"socket.io": "^4.7.1",
|
||||||
"socks-proxy-agent": "^8.0.1",
|
"socks-proxy-agent": "^8.0.1",
|
||||||
"swagger-ui-express": "^5.0.0",
|
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"xml2js": "^0.6.2",
|
"xml2js": "^0.6.2",
|
||||||
"yamljs": "^0.3.0"
|
"yamljs": "^0.3.0"
|
||||||
|
285
prisma/schema.prisma
Normal file
285
prisma/schema.prisma
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
// 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 = "postgresql"
|
||||||
|
url = env("DATABASE_CONNECTION_URI")
|
||||||
|
}
|
||||||
|
|
||||||
|
enum InstanceConnectionStatus {
|
||||||
|
open
|
||||||
|
close
|
||||||
|
connecting
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DeviceMessage {
|
||||||
|
ios
|
||||||
|
android
|
||||||
|
web
|
||||||
|
unknown
|
||||||
|
desktop
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TypebotSessionStatus {
|
||||||
|
open
|
||||||
|
closed
|
||||||
|
paused
|
||||||
|
}
|
||||||
|
|
||||||
|
model Instance {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String @unique @db.VarChar(255)
|
||||||
|
description String? @db.VarChar(255)
|
||||||
|
connectionStatus InstanceConnectionStatus @default(open)
|
||||||
|
ownerJid String? @db.VarChar(100)
|
||||||
|
profilePicUrl String? @db.VarChar(500)
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime? @updatedAt @db.Date
|
||||||
|
Auth Auth?
|
||||||
|
Chat Chat[]
|
||||||
|
Contact Contact[]
|
||||||
|
Message Message[]
|
||||||
|
Webhook Webhook?
|
||||||
|
Chatwoot Chatwoot?
|
||||||
|
Integration Integration?
|
||||||
|
Label Label[]
|
||||||
|
Proxy Proxy?
|
||||||
|
Setting Setting?
|
||||||
|
Rabbitmq Rabbitmq?
|
||||||
|
Sqs Sqs?
|
||||||
|
Websocket Websocket?
|
||||||
|
Typebot Typebot?
|
||||||
|
Session Session?
|
||||||
|
}
|
||||||
|
|
||||||
|
model Session {
|
||||||
|
id Int @id @unique @default(autoincrement())
|
||||||
|
sessionId String @unique @default(cuid())
|
||||||
|
creds String? @db.Text
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique @db.Integer
|
||||||
|
|
||||||
|
@@map("sessions")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Auth {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
apiKey String @unique
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime? @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique @db.Integer
|
||||||
|
}
|
||||||
|
|
||||||
|
model Chat {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
lastMsgTimestamp DateTime? @db.Timestamp
|
||||||
|
labels Json? @db.JsonB
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime? @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int
|
||||||
|
}
|
||||||
|
|
||||||
|
model Contact {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
remoteJid String @db.VarChar(100)
|
||||||
|
pushName String? @db.VarChar(100)
|
||||||
|
profilePicUrl String? @db.VarChar(500)
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime? @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int
|
||||||
|
}
|
||||||
|
|
||||||
|
model Message {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
keyId String @db.VarChar(100)
|
||||||
|
keyRemoteJid String @db.VarChar(100)
|
||||||
|
keyFromMe Boolean @db.Boolean
|
||||||
|
keyParticipant String? @db.VarChar(100)
|
||||||
|
pushName String? @db.VarChar(100)
|
||||||
|
participant String? @db.VarChar(100)
|
||||||
|
messageType String @db.VarChar(100)
|
||||||
|
message Json @db.JsonB
|
||||||
|
source DeviceMessage
|
||||||
|
messageTimestamp Int @db.Integer
|
||||||
|
chatwootMessageId Int? @db.Integer
|
||||||
|
chatwootInboxId Int? @db.Integer
|
||||||
|
chatwootConversationId Int? @db.Integer
|
||||||
|
chatwootContactInboxSourceId String? @db.VarChar(100)
|
||||||
|
chatwotIsRead Boolean? @db.Boolean
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int
|
||||||
|
typebotSessionId Int?
|
||||||
|
MessageUpdate MessageUpdate[]
|
||||||
|
TypebotSession TypebotSession? @relation(fields: [typebotSessionId], references: [id])
|
||||||
|
|
||||||
|
@@index([keyId], name: "keyId")
|
||||||
|
}
|
||||||
|
|
||||||
|
model MessageUpdate {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
remoteJid String @db.VarChar(100)
|
||||||
|
fromMe Boolean @db.Boolean
|
||||||
|
participant String? @db.VarChar(100)
|
||||||
|
dateTime DateTime @db.Date
|
||||||
|
status String @db.VarChar(30)
|
||||||
|
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
||||||
|
messageId Int
|
||||||
|
}
|
||||||
|
|
||||||
|
model Webhook {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
url String @db.VarChar(500)
|
||||||
|
enabled Boolean? @default(true) @db.Boolean
|
||||||
|
events Json? @db.JsonB
|
||||||
|
webhook_by_events Boolean? @default(false) @db.Boolean
|
||||||
|
webhook_base64 Boolean? @default(false) @db.Boolean
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Chatwoot {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(true) @db.Boolean
|
||||||
|
account_id String? @db.VarChar(100)
|
||||||
|
token String? @db.VarChar(100)
|
||||||
|
url String? @db.VarChar(500)
|
||||||
|
name_inbox String? @db.VarChar(100)
|
||||||
|
sign_msg Boolean? @default(false) @db.Boolean
|
||||||
|
sign_delimiter String? @db.VarChar(100)
|
||||||
|
number String? @db.VarChar(100)
|
||||||
|
reopen_conversation Boolean? @default(false) @db.Boolean
|
||||||
|
conversation_pending Boolean? @default(false) @db.Boolean
|
||||||
|
merge_brazil_contacts Boolean? @default(false) @db.Boolean
|
||||||
|
import_contacts Boolean? @default(false) @db.Boolean
|
||||||
|
import_messages Boolean? @default(false) @db.Boolean
|
||||||
|
days_limit_import_messages Int? @db.Integer
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Integration {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
integration String @db.VarChar(100)
|
||||||
|
number String? @db.VarChar(100)
|
||||||
|
token String? @db.VarChar(100)
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Label {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
labelId String? @unique @db.VarChar(100)
|
||||||
|
name String @db.VarChar(100)
|
||||||
|
color String @db.VarChar(100)
|
||||||
|
predefinedId String? @db.VarChar(100)
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int
|
||||||
|
}
|
||||||
|
|
||||||
|
model Proxy {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(true) @db.Boolean
|
||||||
|
proxyHost String? @db.VarChar(100)
|
||||||
|
proxyPort Int? @db.Integer
|
||||||
|
proxyUsername String? @db.VarChar(100)
|
||||||
|
proxyPassword String? @db.VarChar(100)
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Setting {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
rejectCall Boolean? @default(false) @db.Boolean
|
||||||
|
msgCall String? @db.VarChar(100)
|
||||||
|
groupsIgnore Boolean? @default(false) @db.Boolean
|
||||||
|
alwaysOnline Boolean? @default(false) @db.Boolean
|
||||||
|
readMessages Boolean? @default(false) @db.Boolean
|
||||||
|
readStatus Boolean? @default(false) @db.Boolean
|
||||||
|
syncFullHistory Boolean? @default(false) @db.Boolean
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Rabbitmq {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(false) @db.Boolean
|
||||||
|
events Json? @db.JsonB
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Sqs {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(false) @db.Boolean
|
||||||
|
events Json? @db.JsonB
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Websocket {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(false) @db.Boolean
|
||||||
|
events Json? @db.JsonB
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
}
|
||||||
|
|
||||||
|
model Typebot {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
enabled Boolean? @default(true) @db.Boolean
|
||||||
|
url String @db.VarChar(500)
|
||||||
|
typebot String @db.VarChar(100)
|
||||||
|
expire Int? @db.Integer
|
||||||
|
keywordFinish String? @db.VarChar(100)
|
||||||
|
delayMessage Int? @db.Integer
|
||||||
|
unknownMessage String? @db.VarChar(100)
|
||||||
|
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime? @updatedAt @db.Date
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId Int @unique
|
||||||
|
sessions TypebotSession[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model TypebotSession {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
remoteJid String @db.VarChar(100)
|
||||||
|
pushName String? @db.VarChar(100)
|
||||||
|
sessionId String @db.VarChar(100)
|
||||||
|
status String @db.VarChar(100)
|
||||||
|
prefilledVariables Json? @db.JsonB
|
||||||
|
createdAt DateTime? @default(now()) @db.Date
|
||||||
|
updatedAt DateTime @updatedAt @db.Date
|
||||||
|
Typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
|
||||||
|
typebotId Int
|
||||||
|
Message Message[]
|
||||||
|
}
|
@ -16,9 +16,9 @@ import {
|
|||||||
WhatsAppNumberDto,
|
WhatsAppNumberDto,
|
||||||
} from '../dto/chat.dto';
|
} from '../dto/chat.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { ContactQuery } from '../repository/contact.repository';
|
import { ContactQuery } from '../repository/mongodb/contact.repository';
|
||||||
import { MessageQuery } from '../repository/message.repository';
|
import { MessageQuery } from '../repository/mongodb/message.repository';
|
||||||
import { MessageUpQuery } from '../repository/messageUp.repository';
|
import { MessageUpQuery } from '../repository/mongodb/messageUp.repository';
|
||||||
import { WAMonitoringService } from '../services/monitor.service';
|
import { WAMonitoringService } from '../services/monitor.service';
|
||||||
|
|
||||||
const logger = new Logger('ChatController');
|
const logger = new Logger('ChatController');
|
||||||
|
@ -13,8 +13,9 @@ import { SqsService } from '../integrations/sqs/services/sqs.service';
|
|||||||
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
||||||
import { WebsocketService } from '../integrations/websocket/services/websocket.service';
|
import { WebsocketService } from '../integrations/websocket/services/websocket.service';
|
||||||
import { ProviderFiles } from '../provider/sessions';
|
import { ProviderFiles } from '../provider/sessions';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||||
import { AuthService, OldToken } from '../services/auth.service';
|
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||||
|
import { AuthService } from '../services/auth.service';
|
||||||
import { CacheService } from '../services/cache.service';
|
import { CacheService } from '../services/cache.service';
|
||||||
import { BaileysStartupService } from '../services/channels/whatsapp.baileys.service';
|
import { BaileysStartupService } from '../services/channels/whatsapp.baileys.service';
|
||||||
import { BusinessStartupService } from '../services/channels/whatsapp.business.service';
|
import { BusinessStartupService } from '../services/channels/whatsapp.business.service';
|
||||||
@ -29,7 +30,8 @@ export class InstanceController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly mongodbRepository: MongodbRepository,
|
||||||
|
private readonly prismaRepository: PrismaRepository,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
private readonly webhookService: WebhookService,
|
private readonly webhookService: WebhookService,
|
||||||
@ -109,7 +111,8 @@ export class InstanceController {
|
|||||||
instance = new BusinessStartupService(
|
instance = new BusinessStartupService(
|
||||||
this.configService,
|
this.configService,
|
||||||
this.eventEmitter,
|
this.eventEmitter,
|
||||||
this.repository,
|
this.mongodbRepository,
|
||||||
|
this.prismaRepository,
|
||||||
this.cache,
|
this.cache,
|
||||||
this.chatwootCache,
|
this.chatwootCache,
|
||||||
this.baileysCache,
|
this.baileysCache,
|
||||||
@ -119,7 +122,8 @@ export class InstanceController {
|
|||||||
instance = new BaileysStartupService(
|
instance = new BaileysStartupService(
|
||||||
this.configService,
|
this.configService,
|
||||||
this.eventEmitter,
|
this.eventEmitter,
|
||||||
this.repository,
|
this.mongodbRepository,
|
||||||
|
this.prismaRepository,
|
||||||
this.cache,
|
this.cache,
|
||||||
this.chatwootCache,
|
this.chatwootCache,
|
||||||
this.baileysCache,
|
this.baileysCache,
|
||||||
@ -188,10 +192,8 @@ export class InstanceController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
newEvents = events;
|
newEvents = events;
|
||||||
@ -240,10 +242,8 @@ export class InstanceController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
newEvents = websocket_events;
|
newEvents = websocket_events;
|
||||||
@ -289,10 +289,8 @@ export class InstanceController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
newEvents = rabbitmq_events;
|
newEvents = rabbitmq_events;
|
||||||
@ -338,10 +336,8 @@ export class InstanceController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
newEvents = sqs_events;
|
newEvents = sqs_events;
|
||||||
@ -690,7 +686,7 @@ export class InstanceController {
|
|||||||
let arrayReturn = false;
|
let arrayReturn = false;
|
||||||
|
|
||||||
if (env.KEY !== key) {
|
if (env.KEY !== key) {
|
||||||
const instanceByKey = await this.repository.auth.findByKey(key);
|
const instanceByKey = await this.mongodbRepository.auth.findByKey(key);
|
||||||
if (instanceByKey) {
|
if (instanceByKey) {
|
||||||
name = instanceByKey._id;
|
name = instanceByKey._id;
|
||||||
arrayReturn = true;
|
arrayReturn = true;
|
||||||
@ -755,7 +751,7 @@ export class InstanceController {
|
|||||||
try {
|
try {
|
||||||
this.waMonitor.waInstances[instanceName]?.sendDataWebhook(Events.INSTANCE_DELETE, {
|
this.waMonitor.waInstances[instanceName]?.sendDataWebhook(Events.INSTANCE_DELETE, {
|
||||||
instanceName,
|
instanceName,
|
||||||
instanceId: (await this.repository.auth.find(instanceName))?.instanceId,
|
instanceId: (await this.mongodbRepository.auth.find(instanceName))?.instanceId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
@ -768,9 +764,4 @@ export class InstanceController {
|
|||||||
throw new BadRequestException(error.toString());
|
throw new BadRequestException(error.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async refreshToken(_: InstanceDto, oldToken: OldToken) {
|
|
||||||
this.logger.verbose('requested refreshToken');
|
|
||||||
return await this.authService.refreshToken(oldToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,8 @@ export class WebhookController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,60 +1,13 @@
|
|||||||
import { isJWT } from 'class-validator';
|
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
|
|
||||||
import { name } from '../../../package.json';
|
|
||||||
import { Auth, configService, Database } from '../../config/env.config';
|
import { Auth, configService, Database } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { ForbiddenException, UnauthorizedException } from '../../exceptions';
|
import { ForbiddenException, UnauthorizedException } from '../../exceptions';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { repository } from '../server.module';
|
import { mongodbRepository } from '../server.module';
|
||||||
import { JwtPayload } from '../services/auth.service';
|
|
||||||
|
|
||||||
const logger = new Logger('GUARD');
|
const logger = new Logger('GUARD');
|
||||||
|
|
||||||
async function jwtGuard(req: Request, res: Response, next: NextFunction) {
|
|
||||||
const key = req.get('apikey');
|
|
||||||
|
|
||||||
if (key && configService.get<Auth>('AUTHENTICATION').API_KEY.KEY !== key) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configService.get<Auth>('AUTHENTICATION').API_KEY.KEY === key) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 jwtOpts = configService.get<Auth>('AUTHENTICATION').JWT;
|
|
||||||
try {
|
|
||||||
const [bearer, token] = req.get('authorization').split(' ');
|
|
||||||
|
|
||||||
if (bearer.toLowerCase() !== 'bearer') {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isJWT(token)) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
const param = req.params as unknown as InstanceDto;
|
|
||||||
const decode = jwt.verify(token, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: jwtOpts.EXPIRIN_IN === 0,
|
|
||||||
}) as JwtPayload;
|
|
||||||
|
|
||||||
if (param.instanceName !== decode.instanceName || name !== decode.apiName) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(error);
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function apikey(req: Request, _: Response, next: NextFunction) {
|
async function apikey(req: Request, _: Response, next: NextFunction) {
|
||||||
const env = configService.get<Auth>('AUTHENTICATION').API_KEY;
|
const env = configService.get<Auth>('AUTHENTICATION').API_KEY;
|
||||||
const key = req.get('apikey');
|
const key = req.get('apikey');
|
||||||
@ -75,13 +28,13 @@ async function apikey(req: Request, _: Response, next: NextFunction) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (param?.instanceName) {
|
if (param?.instanceName) {
|
||||||
const instanceKey = await repository.auth.find(param.instanceName);
|
const instanceKey = await mongodbRepository.auth.find(param.instanceName);
|
||||||
if (instanceKey?.apikey === key) {
|
if (instanceKey?.apikey === key) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (req.originalUrl.includes('/instance/fetchInstances') && db.ENABLED) {
|
if (req.originalUrl.includes('/instance/fetchInstances') && db.ENABLED) {
|
||||||
const instanceByKey = await repository.auth.findByKey(key);
|
const instanceByKey = await mongodbRepository.auth.findByKey(key);
|
||||||
if (instanceByKey) {
|
if (instanceByKey) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
@ -94,4 +47,4 @@ async function apikey(req: Request, _: Response, next: NextFunction) {
|
|||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const authGuard = { jwt: jwtGuard, apikey };
|
export const authGuard = { apikey };
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
InternalServerErrorException,
|
InternalServerErrorException,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '../../exceptions';
|
} from '../../exceptions';
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { cache, waMonitor } from '../server.module';
|
import { cache, waMonitor } from '../server.module';
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ async function getInstance(instanceName: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED) {
|
||||||
const collection = dbserver
|
const collection = mongodbServer
|
||||||
.getClient()
|
.getClient()
|
||||||
.db(db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
.db(db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
.collection(instanceName);
|
.collection(instanceName);
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { Logger } from '../../../../config/logger.config';
|
|
||||||
import { InstanceDto } from '../../../dto/instance.dto';
|
|
||||||
import { ChamaaiDto } from '../dto/chamaai.dto';
|
|
||||||
import { ChamaaiService } from '../services/chamaai.service';
|
|
||||||
|
|
||||||
const logger = new Logger('ChamaaiController');
|
|
||||||
|
|
||||||
export class ChamaaiController {
|
|
||||||
constructor(private readonly chamaaiService: ChamaaiService) {}
|
|
||||||
|
|
||||||
public async createChamaai(instance: InstanceDto, data: ChamaaiDto) {
|
|
||||||
logger.verbose('requested createChamaai from ' + instance.instanceName + ' instance');
|
|
||||||
|
|
||||||
if (!data.enabled) {
|
|
||||||
logger.verbose('chamaai disabled');
|
|
||||||
data.url = '';
|
|
||||||
data.token = '';
|
|
||||||
data.waNumber = '';
|
|
||||||
data.answerByAudio = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.chamaaiService.create(instance, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async findChamaai(instance: InstanceDto) {
|
|
||||||
logger.verbose('requested findChamaai from ' + instance.instanceName + ' instance');
|
|
||||||
return this.chamaaiService.find(instance);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
export class ChamaaiDto {
|
|
||||||
enabled: boolean;
|
|
||||||
url: string;
|
|
||||||
token: string;
|
|
||||||
waNumber: string;
|
|
||||||
answerByAudio: boolean;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import { Schema } from 'mongoose';
|
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
|
||||||
|
|
||||||
export class ChamaaiRaw {
|
|
||||||
_id?: string;
|
|
||||||
enabled?: boolean;
|
|
||||||
url?: string;
|
|
||||||
token?: string;
|
|
||||||
waNumber?: string;
|
|
||||||
answerByAudio?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const chamaaiSchema = new Schema<ChamaaiRaw>({
|
|
||||||
_id: { type: String, _id: true },
|
|
||||||
enabled: { type: Boolean, required: true },
|
|
||||||
url: { type: String, required: true },
|
|
||||||
token: { type: String, required: true },
|
|
||||||
waNumber: { type: String, required: true },
|
|
||||||
answerByAudio: { type: Boolean, required: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ChamaaiModel = dbserver?.model(ChamaaiRaw.name, chamaaiSchema, 'chamaai');
|
|
||||||
export type IChamaaiModel = typeof ChamaaiModel;
|
|
@ -1,62 +0,0 @@
|
|||||||
import { readFileSync } from 'fs';
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
import { ConfigService } from '../../../../config/env.config';
|
|
||||||
import { Logger } from '../../../../config/logger.config';
|
|
||||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
|
||||||
import { ChamaaiRaw, IChamaaiModel } from '../../../models';
|
|
||||||
|
|
||||||
export class ChamaaiRepository extends Repository {
|
|
||||||
constructor(private readonly chamaaiModel: IChamaaiModel, private readonly configService: ConfigService) {
|
|
||||||
super(configService);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly logger = new Logger('ChamaaiRepository');
|
|
||||||
|
|
||||||
public async create(data: ChamaaiRaw, instance: string): Promise<IInsert> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('creating chamaai');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('saving chamaai to db');
|
|
||||||
const insert = await this.chamaaiModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
|
||||||
|
|
||||||
this.logger.verbose('chamaai saved to db: ' + insert.modifiedCount + ' chamaai');
|
|
||||||
return { insertCount: insert.modifiedCount };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('saving chamaai to store');
|
|
||||||
|
|
||||||
this.writeStore<ChamaaiRaw>({
|
|
||||||
path: join(this.storePath, 'chamaai'),
|
|
||||||
fileName: instance,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('chamaai saved to store in path: ' + join(this.storePath, 'chamaai') + '/' + instance);
|
|
||||||
|
|
||||||
this.logger.verbose('chamaai created');
|
|
||||||
return { insertCount: 1 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: string): Promise<ChamaaiRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('finding chamaai');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('finding chamaai in db');
|
|
||||||
return await this.chamaaiModel.findOne({ _id: instance });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding chamaai in store');
|
|
||||||
return JSON.parse(
|
|
||||||
readFileSync(join(this.storePath, 'chamaai', instance + '.json'), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
) as ChamaaiRaw;
|
|
||||||
} catch (error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
import { RequestHandler, Router } from 'express';
|
|
||||||
|
|
||||||
import { Logger } from '../../../../config/logger.config';
|
|
||||||
import { chamaaiSchema, instanceNameSchema } from '../../../../validate/validate.schema';
|
|
||||||
import { RouterBroker } from '../../../abstract/abstract.router';
|
|
||||||
import { InstanceDto } from '../../../dto/instance.dto';
|
|
||||||
import { HttpStatus } from '../../../routes/index.router';
|
|
||||||
import { chamaaiController } from '../../../server.module';
|
|
||||||
import { ChamaaiDto } from '../dto/chamaai.dto';
|
|
||||||
|
|
||||||
const logger = new Logger('ChamaaiRouter');
|
|
||||||
|
|
||||||
export class ChamaaiRouter extends RouterBroker {
|
|
||||||
constructor(...guards: RequestHandler[]) {
|
|
||||||
super();
|
|
||||||
this.router
|
|
||||||
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in setChamaai');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<ChamaaiDto>({
|
|
||||||
request: req,
|
|
||||||
schema: chamaaiSchema,
|
|
||||||
ClassRef: ChamaaiDto,
|
|
||||||
execute: (instance, data) => chamaaiController.createChamaai(instance, data),
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
|
||||||
})
|
|
||||||
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in findChamaai');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => chamaaiController.findChamaai(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly router = Router();
|
|
||||||
}
|
|
@ -1,230 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { writeFileSync } from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
import { ConfigService, HttpServer } from '../../../../config/env.config';
|
|
||||||
import { Logger } from '../../../../config/logger.config';
|
|
||||||
import { InstanceDto } from '../../../dto/instance.dto';
|
|
||||||
import { ChamaaiRaw } from '../../../models';
|
|
||||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
|
||||||
import { Events } from '../../../types/wa.types';
|
|
||||||
import { ChamaaiDto } from '../dto/chamaai.dto';
|
|
||||||
|
|
||||||
export class ChamaaiService {
|
|
||||||
constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {}
|
|
||||||
|
|
||||||
private readonly logger = new Logger(ChamaaiService.name);
|
|
||||||
|
|
||||||
public create(instance: InstanceDto, data: ChamaaiDto) {
|
|
||||||
this.logger.verbose('create chamaai: ' + instance.instanceName);
|
|
||||||
this.waMonitor.waInstances[instance.instanceName].setChamaai(data);
|
|
||||||
|
|
||||||
return { chamaai: { ...instance, chamaai: data } };
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: InstanceDto): Promise<ChamaaiRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('find chamaai: ' + instance.instanceName);
|
|
||||||
const result = await this.waMonitor.waInstances[instance.instanceName].findChamaai();
|
|
||||||
|
|
||||||
if (Object.keys(result).length === 0) {
|
|
||||||
throw new Error('Chamaai not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
return { enabled: false, url: '', token: '', waNumber: '', answerByAudio: false };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getTypeMessage(msg: any) {
|
|
||||||
this.logger.verbose('get type message');
|
|
||||||
|
|
||||||
const types = {
|
|
||||||
conversation: msg.conversation,
|
|
||||||
extendedTextMessage: msg.extendedTextMessage?.text,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.logger.verbose('type message: ' + types);
|
|
||||||
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getMessageContent(types: any) {
|
|
||||||
this.logger.verbose('get message content');
|
|
||||||
const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
|
|
||||||
|
|
||||||
const result = typeKey ? types[typeKey] : undefined;
|
|
||||||
|
|
||||||
this.logger.verbose('message content: ' + result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getConversationMessage(msg: any) {
|
|
||||||
this.logger.verbose('get conversation message');
|
|
||||||
|
|
||||||
const types = this.getTypeMessage(msg);
|
|
||||||
|
|
||||||
const messageContent = this.getMessageContent(types);
|
|
||||||
|
|
||||||
this.logger.verbose('conversation message: ' + messageContent);
|
|
||||||
|
|
||||||
return messageContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private calculateTypingTime(text: string) {
|
|
||||||
const wordsPerMinute = 100;
|
|
||||||
|
|
||||||
const wordCount = text.split(' ').length;
|
|
||||||
const typingTimeInMinutes = wordCount / wordsPerMinute;
|
|
||||||
const typingTimeInMilliseconds = typingTimeInMinutes * 60;
|
|
||||||
return typingTimeInMilliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private convertToMilliseconds(count: number) {
|
|
||||||
const averageCharactersPerSecond = 15;
|
|
||||||
const characterCount = count;
|
|
||||||
const speakingTimeInSeconds = characterCount / averageCharactersPerSecond;
|
|
||||||
return speakingTimeInSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getRegexPatterns() {
|
|
||||||
const patternsToCheck = [
|
|
||||||
'.*atend.*humano.*',
|
|
||||||
'.*falar.*com.*um.*humano.*',
|
|
||||||
'.*fala.*humano.*',
|
|
||||||
'.*atend.*humano.*',
|
|
||||||
'.*fala.*atend.*',
|
|
||||||
'.*preciso.*ajuda.*',
|
|
||||||
'.*quero.*suporte.*',
|
|
||||||
'.*preciso.*assiste.*',
|
|
||||||
'.*ajuda.*atend.*',
|
|
||||||
'.*chama.*atendente.*',
|
|
||||||
'.*suporte.*urgente.*',
|
|
||||||
'.*atend.*por.*favor.*',
|
|
||||||
'.*quero.*falar.*com.*alguém.*',
|
|
||||||
'.*falar.*com.*um.*humano.*',
|
|
||||||
'.*transfer.*humano.*',
|
|
||||||
'.*transfer.*atend.*',
|
|
||||||
'.*equipe.*humano.*',
|
|
||||||
'.*suporte.*humano.*',
|
|
||||||
];
|
|
||||||
|
|
||||||
const regexPatterns = patternsToCheck.map((pattern) => new RegExp(pattern, 'iu'));
|
|
||||||
return regexPatterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async sendChamaai(instance: InstanceDto, remoteJid: string, msg: any) {
|
|
||||||
const content = this.getConversationMessage(msg.message);
|
|
||||||
const msgType = msg.messageType;
|
|
||||||
const find = await this.find(instance);
|
|
||||||
const url = find.url;
|
|
||||||
const token = find.token;
|
|
||||||
const waNumber = find.waNumber;
|
|
||||||
const answerByAudio = find.answerByAudio;
|
|
||||||
|
|
||||||
if (!content && msgType !== 'audioMessage') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let data;
|
|
||||||
let endpoint;
|
|
||||||
|
|
||||||
if (msgType === 'audioMessage') {
|
|
||||||
const downloadBase64 = await this.waMonitor.waInstances[instance.instanceName].getBase64FromMediaMessage({
|
|
||||||
message: {
|
|
||||||
...msg,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const random = Math.random().toString(36).substring(7);
|
|
||||||
const nameFile = `${random}.ogg`;
|
|
||||||
|
|
||||||
const fileData = Buffer.from(downloadBase64.base64, 'base64');
|
|
||||||
|
|
||||||
const fileName = `${path.join(
|
|
||||||
this.waMonitor.waInstances[instance.instanceName].storePath,
|
|
||||||
'temp',
|
|
||||||
`${nameFile}`,
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
writeFileSync(fileName, fileData, 'utf8');
|
|
||||||
|
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
|
||||||
|
|
||||||
const url = `${urlServer}/store/temp/${nameFile}`;
|
|
||||||
|
|
||||||
data = {
|
|
||||||
waNumber: waNumber,
|
|
||||||
audioUrl: url,
|
|
||||||
queryNumber: remoteJid.split('@')[0],
|
|
||||||
answerByAudio: answerByAudio,
|
|
||||||
};
|
|
||||||
endpoint = 'processMessageAudio';
|
|
||||||
} else {
|
|
||||||
data = {
|
|
||||||
waNumber: waNumber,
|
|
||||||
question: content,
|
|
||||||
queryNumber: remoteJid.split('@')[0],
|
|
||||||
answerByAudio: answerByAudio,
|
|
||||||
};
|
|
||||||
endpoint = 'processMessageText';
|
|
||||||
}
|
|
||||||
|
|
||||||
const request = await axios.post(`${url}/${endpoint}`, data, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const answer = request.data?.answer;
|
|
||||||
|
|
||||||
const type = request.data?.type;
|
|
||||||
|
|
||||||
const characterCount = request.data?.characterCount;
|
|
||||||
|
|
||||||
if (answer) {
|
|
||||||
if (type === 'text') {
|
|
||||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
|
||||||
number: remoteJid.split('@')[0],
|
|
||||||
options: {
|
|
||||||
delay: this.calculateTypingTime(answer) * 1000 || 1000,
|
|
||||||
presence: 'composing',
|
|
||||||
linkPreview: false,
|
|
||||||
quoted: {
|
|
||||||
key: msg.key,
|
|
||||||
message: msg.message,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
textMessage: {
|
|
||||||
text: answer,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'audio') {
|
|
||||||
this.waMonitor.waInstances[instance.instanceName].audioWhatsapp({
|
|
||||||
number: remoteJid.split('@')[0],
|
|
||||||
options: {
|
|
||||||
delay: characterCount ? this.convertToMilliseconds(characterCount) * 1000 || 1000 : 1000,
|
|
||||||
presence: 'recording',
|
|
||||||
encoding: true,
|
|
||||||
},
|
|
||||||
audioMessage: {
|
|
||||||
audio: answer,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getRegexPatterns().some((pattern) => pattern.test(answer))) {
|
|
||||||
this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.CHAMA_AI_ACTION, {
|
|
||||||
remoteJid: remoteJid,
|
|
||||||
message: msg,
|
|
||||||
answer: answer,
|
|
||||||
action: 'transfer',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
import { JSONSchema7 } from 'json-schema';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
|
|
||||||
const properties = {};
|
|
||||||
propertyNames.forEach(
|
|
||||||
(property) =>
|
|
||||||
(properties[property] = {
|
|
||||||
minLength: 1,
|
|
||||||
description: `The "${property}" cannot be empty`,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
if: {
|
|
||||||
propertyNames: {
|
|
||||||
enum: [...propertyNames],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
then: { properties },
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const chamaaiSchema: JSONSchema7 = {
|
|
||||||
$id: v4(),
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
enabled: { type: 'boolean', enum: [true, false] },
|
|
||||||
url: { type: 'string' },
|
|
||||||
token: { type: 'string' },
|
|
||||||
waNumber: { type: 'string' },
|
|
||||||
answerByAudio: { type: 'boolean', enum: [true, false] },
|
|
||||||
},
|
|
||||||
required: ['enabled', 'url', 'token', 'waNumber', 'answerByAudio'],
|
|
||||||
...isNotEmpty('enabled', 'url', 'token', 'waNumber', 'answerByAudio'),
|
|
||||||
};
|
|
@ -5,7 +5,8 @@ import { ConfigService, HttpServer } from '../../../../config/env.config';
|
|||||||
import { Logger } from '../../../../config/logger.config';
|
import { Logger } from '../../../../config/logger.config';
|
||||||
import { BadRequestException } from '../../../../exceptions';
|
import { BadRequestException } from '../../../../exceptions';
|
||||||
import { InstanceDto } from '../../../dto/instance.dto';
|
import { InstanceDto } from '../../../dto/instance.dto';
|
||||||
import { RepositoryBroker } from '../../../repository/repository.manager';
|
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||||
import { waMonitor } from '../../../server.module';
|
import { waMonitor } from '../../../server.module';
|
||||||
import { CacheService } from '../../../services/cache.service';
|
import { CacheService } from '../../../services/cache.service';
|
||||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||||
@ -17,7 +18,8 @@ export class ChatwootController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly chatwootService: ChatwootService,
|
private readonly chatwootService: ChatwootService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly mongodbRepository: MongodbRepository,
|
||||||
|
private readonly prismaRepository: PrismaRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async createChatwoot(instance: InstanceDto, data: ChatwootDto) {
|
public async createChatwoot(instance: InstanceDto, data: ChatwootDto) {
|
||||||
@ -105,7 +107,13 @@ export class ChatwootController {
|
|||||||
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
||||||
|
|
||||||
const chatwootCache = new CacheService(new CacheEngine(this.configService, ChatwootService.name).getEngine());
|
const chatwootCache = new CacheService(new CacheEngine(this.configService, ChatwootService.name).getEngine());
|
||||||
const chatwootService = new ChatwootService(waMonitor, this.configService, this.repository, chatwootCache);
|
const chatwootService = new ChatwootService(
|
||||||
|
waMonitor,
|
||||||
|
this.configService,
|
||||||
|
this.mongodbRepository,
|
||||||
|
this.prismaRepository,
|
||||||
|
chatwootCache,
|
||||||
|
);
|
||||||
|
|
||||||
return chatwootService.receiveWebhook(instance, data);
|
return chatwootService.receiveWebhook(instance, data);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class ChatwootRaw {
|
export class ChatwootRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -38,5 +38,5 @@ const chatwootSchema = new Schema<ChatwootRaw>({
|
|||||||
days_limit_import_messages: { type: Number, required: true },
|
days_limit_import_messages: { type: Number, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
export const ChatwootModel = mongodbServer?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
||||||
export type IChatwootModel = typeof ChatwootModel;
|
export type IChatwootModel = typeof ChatwootModel;
|
||||||
|
@ -23,7 +23,8 @@ import { ICache } from '../../../abstract/abstract.cache';
|
|||||||
import { InstanceDto } from '../../../dto/instance.dto';
|
import { InstanceDto } from '../../../dto/instance.dto';
|
||||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../../../dto/sendMessage.dto';
|
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../../../dto/sendMessage.dto';
|
||||||
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../models';
|
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../models';
|
||||||
import { RepositoryBroker } from '../../../repository/repository.manager';
|
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||||
import { Events } from '../../../types/wa.types';
|
import { Events } from '../../../types/wa.types';
|
||||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||||
@ -37,7 +38,8 @@ export class ChatwootService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly mongodbRepository: MongodbRepository,
|
||||||
|
private readonly prismaRepository: PrismaRepository,
|
||||||
private readonly cache: ICache,
|
private readonly cache: ICache,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -444,8 +446,7 @@ export class ChatwootService {
|
|||||||
const searchableFields = this.getSearchableFields();
|
const searchableFields = this.getSearchableFields();
|
||||||
|
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
if(contacts.length === 2 && this.getClientCwConfig().merge_brazil_contacts && query.startsWith('+55')){
|
if (contacts.length === 2 && this.getClientCwConfig().merge_brazil_contacts && query.startsWith('+55')) {
|
||||||
|
|
||||||
const contact = this.mergeBrazilianContacts(contacts);
|
const contact = this.mergeBrazilianContacts(contacts);
|
||||||
if (contact) {
|
if (contact) {
|
||||||
return contact;
|
return contact;
|
||||||
@ -1194,7 +1195,7 @@ export class ChatwootService {
|
|||||||
|
|
||||||
this.logger.verbose('check if is a message deletion');
|
this.logger.verbose('check if is a message deletion');
|
||||||
if (body.event === 'message_updated' && body.content_attributes?.deleted) {
|
if (body.event === 'message_updated' && body.content_attributes?.deleted) {
|
||||||
const message = await this.repository.message.find({
|
const message = await this.mongodbRepository.message.find({
|
||||||
where: {
|
where: {
|
||||||
owner: instance.instanceName,
|
owner: instance.instanceName,
|
||||||
chatwoot: {
|
chatwoot: {
|
||||||
@ -1208,7 +1209,7 @@ export class ChatwootService {
|
|||||||
await waInstance?.client.sendMessage(message[0].key.remoteJid, { delete: message[0].key });
|
await waInstance?.client.sendMessage(message[0].key.remoteJid, { delete: message[0].key });
|
||||||
|
|
||||||
this.logger.verbose('deleting message in repository. Message id: ' + message[0].key.id);
|
this.logger.verbose('deleting message in repository. Message id: ' + message[0].key.id);
|
||||||
this.repository.message.delete({
|
this.mongodbRepository.message.delete({
|
||||||
where: {
|
where: {
|
||||||
owner: instance.instanceName,
|
owner: instance.instanceName,
|
||||||
chatwoot: {
|
chatwoot: {
|
||||||
@ -1423,7 +1424,7 @@ export class ChatwootService {
|
|||||||
|
|
||||||
const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;
|
const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;
|
||||||
if (chatwootRead) {
|
if (chatwootRead) {
|
||||||
const lastMessage = await this.repository.message.find({
|
const lastMessage = await this.mongodbRepository.message.find({
|
||||||
where: {
|
where: {
|
||||||
key: {
|
key: {
|
||||||
fromMe: false,
|
fromMe: false,
|
||||||
@ -1448,7 +1449,7 @@ export class ChatwootService {
|
|||||||
isRead: true,
|
isRead: true,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
this.repository.message.update(updateMessage, instance.instanceName, true);
|
this.mongodbRepository.message.update(updateMessage, instance.instanceName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1490,11 +1491,11 @@ export class ChatwootService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message.chatwoot = chatwootMessageIds;
|
message.chatwoot = chatwootMessageIds;
|
||||||
this.repository.message.update([message], instance.instanceName, true);
|
this.mongodbRepository.message.update([message], instance.instanceName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageRaw> {
|
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageRaw> {
|
||||||
const messages = await this.repository.message.find({
|
const messages = await this.mongodbRepository.message.find({
|
||||||
where: {
|
where: {
|
||||||
key: {
|
key: {
|
||||||
id: keyId,
|
id: keyId,
|
||||||
@ -1532,7 +1533,7 @@ export class ChatwootService {
|
|||||||
|
|
||||||
private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {
|
private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {
|
||||||
if (msg?.content_attributes?.in_reply_to) {
|
if (msg?.content_attributes?.in_reply_to) {
|
||||||
const message = await this.repository.message.find({
|
const message = await this.mongodbRepository.message.find({
|
||||||
where: {
|
where: {
|
||||||
chatwoot: {
|
chatwoot: {
|
||||||
messageId: msg?.content_attributes?.in_reply_to,
|
messageId: msg?.content_attributes?.in_reply_to,
|
||||||
@ -2132,7 +2133,7 @@ export class ChatwootService {
|
|||||||
const message = await this.getMessageByKeyId(instance, body.key.id);
|
const message = await this.getMessageByKeyId(instance, body.key.id);
|
||||||
if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) {
|
if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) {
|
||||||
this.logger.verbose('deleting message in repository. Message id: ' + body.key.id);
|
this.logger.verbose('deleting message in repository. Message id: ' + body.key.id);
|
||||||
this.repository.message.delete({
|
this.mongodbRepository.message.delete({
|
||||||
where: {
|
where: {
|
||||||
key: {
|
key: {
|
||||||
id: body.key.id,
|
id: body.key.id,
|
||||||
@ -2381,7 +2382,7 @@ export class ChatwootService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const contactsWithProfilePicture = (
|
const contactsWithProfilePicture = (
|
||||||
await this.repository.contact.find({
|
await this.mongodbRepository.contact.find({
|
||||||
where: {
|
where: {
|
||||||
owner: instance.instanceName,
|
owner: instance.instanceName,
|
||||||
id: {
|
id: {
|
||||||
|
@ -41,10 +41,8 @@ export class RabbitmqController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class RabbitmqRaw {
|
export class RabbitmqRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -14,5 +14,5 @@ const rabbitmqSchema = new Schema<RabbitmqRaw>({
|
|||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const RabbitmqModel = dbserver?.model(RabbitmqRaw.name, rabbitmqSchema, 'rabbitmq');
|
export const RabbitmqModel = mongodbServer?.model(RabbitmqRaw.name, rabbitmqSchema, 'rabbitmq');
|
||||||
export type IRabbitmqModel = typeof RabbitmqModel;
|
export type IRabbitmqModel = typeof RabbitmqModel;
|
||||||
|
@ -53,10 +53,8 @@ export const rabbitmqSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -41,10 +41,8 @@ export class SqsController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class SqsRaw {
|
export class SqsRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -14,5 +14,5 @@ const sqsSchema = new Schema<SqsRaw>({
|
|||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SqsModel = dbserver?.model(SqsRaw.name, sqsSchema, 'sqs');
|
export const SqsModel = mongodbServer?.model(SqsRaw.name, sqsSchema, 'sqs');
|
||||||
export type ISqsModel = typeof SqsModel;
|
export type ISqsModel = typeof SqsModel;
|
||||||
|
@ -53,10 +53,8 @@ export const sqsSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||||
|
|
||||||
class Session {
|
class Session {
|
||||||
remoteJid?: string;
|
remoteJid?: string;
|
||||||
@ -54,5 +54,5 @@ const typebotSchema = new Schema<TypebotRaw>({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TypebotModel = dbserver?.model(TypebotRaw.name, typebotSchema, 'typebot');
|
export const TypebotModel = mongodbServer?.model(TypebotRaw.name, typebotSchema, 'typebot');
|
||||||
export type ITypebotModel = typeof TypebotModel;
|
export type ITypebotModel = typeof TypebotModel;
|
||||||
|
@ -41,10 +41,8 @@ export class WebsocketController {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../../../libs/db.connect';
|
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class WebsocketRaw {
|
export class WebsocketRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -14,5 +14,5 @@ const websocketSchema = new Schema<WebsocketRaw>({
|
|||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const WebsocketModel = dbserver?.model(WebsocketRaw.name, websocketSchema, 'websocket');
|
export const WebsocketModel = mongodbServer?.model(WebsocketRaw.name, websocketSchema, 'websocket');
|
||||||
export type IWebsocketModel = typeof WebsocketModel;
|
export type IWebsocketModel = typeof WebsocketModel;
|
||||||
|
@ -53,10 +53,8 @@ export const websocketSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class AuthRaw {
|
export class AuthRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
jwt?: string;
|
|
||||||
apikey?: string;
|
apikey?: string;
|
||||||
instanceId?: string;
|
instanceId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authSchema = new Schema<AuthRaw>({
|
const authSchema = new Schema<AuthRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
jwt: { type: String, minlength: 1 },
|
|
||||||
apikey: { type: String, minlength: 1 },
|
apikey: { type: String, minlength: 1 },
|
||||||
instanceId: { type: String, minlength: 1 },
|
instanceId: { type: String, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication');
|
export const AuthModel = mongodbServer?.model(AuthRaw.name, authSchema, 'authentication');
|
||||||
export type IAuthModel = typeof AuthModel;
|
export type IAuthModel = typeof AuthModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class ChatRaw {
|
export class ChatRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -22,5 +22,5 @@ const chatSchema = new Schema<ChatRaw>({
|
|||||||
labels: { type: [String], default: [] },
|
labels: { type: [String], default: [] },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ChatModel = dbserver?.model(ChatRaw.name, chatSchema, 'chats');
|
export const ChatModel = mongodbServer?.model(ChatRaw.name, chatSchema, 'chats');
|
||||||
export type IChatModel = typeof ChatModel;
|
export type IChatModel = typeof ChatModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class ContactRaw {
|
export class ContactRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -23,5 +23,5 @@ const contactSchema = new Schema<ContactRaw>({
|
|||||||
owner: { type: String, required: true, minlength: 1 },
|
owner: { type: String, required: true, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ContactModel = dbserver?.model(ContactRaw.name, contactSchema, 'contacts');
|
export const ContactModel = mongodbServer?.model(ContactRaw.name, contactSchema, 'contacts');
|
||||||
export type IContactModel = typeof ContactModel;
|
export type IContactModel = typeof ContactModel;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
export * from '../integrations/chamaai/models/chamaai.model';
|
|
||||||
export * from '../integrations/chatwoot/models/chatwoot.model';
|
export * from '../integrations/chatwoot/models/chatwoot.model';
|
||||||
export * from '../integrations/rabbitmq/models/rabbitmq.model';
|
export * from '../integrations/rabbitmq/models/rabbitmq.model';
|
||||||
export * from '../integrations/sqs/models/sqs.model';
|
export * from '../integrations/sqs/models/sqs.model';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class IntegrationRaw {
|
export class IntegrationRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -16,5 +16,5 @@ const integrationSchema = new Schema<IntegrationRaw>({
|
|||||||
token: { type: String, required: true },
|
token: { type: String, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const IntegrationModel = dbserver?.model(IntegrationRaw.name, integrationSchema, 'integration');
|
export const IntegrationModel = mongodbServer?.model(IntegrationRaw.name, integrationSchema, 'integration');
|
||||||
export type IntegrationModel = typeof IntegrationModel;
|
export type IntegrationModel = typeof IntegrationModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class LabelRaw {
|
export class LabelRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -25,5 +25,5 @@ const labelSchema = new Schema<LabelRaw>({
|
|||||||
predefinedId: { type: String },
|
predefinedId: { type: String },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const LabelModel = dbserver?.model(LabelRaw.name, labelSchema, 'labels');
|
export const LabelModel = mongodbServer?.model(LabelRaw.name, labelSchema, 'labels');
|
||||||
export type ILabelModel = typeof LabelModel;
|
export type ILabelModel = typeof LabelModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
import { wa } from '../types/wa.types';
|
import { wa } from '../types/wa.types';
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
@ -72,7 +72,7 @@ messageSchema.index({ 'key.id': 1 });
|
|||||||
messageSchema.index({ 'key.id': 1, owner: 1 });
|
messageSchema.index({ 'key.id': 1, owner: 1 });
|
||||||
messageSchema.index({ owner: 1 });
|
messageSchema.index({ owner: 1 });
|
||||||
|
|
||||||
export const MessageModel = dbserver?.model(MessageRaw.name, messageSchema, 'messages');
|
export const MessageModel = mongodbServer?.model(MessageRaw.name, messageSchema, 'messages');
|
||||||
export type IMessageModel = typeof MessageModel;
|
export type IMessageModel = typeof MessageModel;
|
||||||
|
|
||||||
export class MessageUpdateRaw {
|
export class MessageUpdateRaw {
|
||||||
@ -98,5 +98,5 @@ const messageUpdateSchema = new Schema<MessageUpdateRaw>({
|
|||||||
owner: { type: String, required: true, min: 1 },
|
owner: { type: String, required: true, min: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const MessageUpModel = dbserver?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate');
|
export const MessageUpModel = mongodbServer?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate');
|
||||||
export type IMessageUpModel = typeof MessageUpModel;
|
export type IMessageUpModel = typeof MessageUpModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
class Proxy {
|
class Proxy {
|
||||||
host?: string;
|
host?: string;
|
||||||
@ -28,5 +28,5 @@ const proxySchema = new Schema<ProxyRaw>({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ProxyModel = dbserver?.model(ProxyRaw.name, proxySchema, 'proxy');
|
export const ProxyModel = mongodbServer?.model(ProxyRaw.name, proxySchema, 'proxy');
|
||||||
export type IProxyModel = typeof ProxyModel;
|
export type IProxyModel = typeof ProxyModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class SettingsRaw {
|
export class SettingsRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -24,5 +24,5 @@ const settingsSchema = new Schema<SettingsRaw>({
|
|||||||
sync_full_history: { type: Boolean, required: true },
|
sync_full_history: { type: Boolean, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings');
|
export const SettingsModel = mongodbServer?.model(SettingsRaw.name, settingsSchema, 'settings');
|
||||||
export type ISettingsModel = typeof SettingsModel;
|
export type ISettingsModel = typeof SettingsModel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
|
|
||||||
export class WebhookRaw {
|
export class WebhookRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
@ -20,5 +20,5 @@ const webhookSchema = new Schema<WebhookRaw>({
|
|||||||
webhook_base64: { type: Boolean, required: true },
|
webhook_base64: { type: Boolean, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
export const WebhookModel = mongodbServer?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
||||||
export type IWebhookModel = typeof WebhookModel;
|
export type IWebhookModel = typeof WebhookModel;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { opendirSync, readFileSync } from 'fs';
|
import { opendirSync, readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Auth, ConfigService } from '../../config/env.config';
|
import { Auth, ConfigService } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { AUTH_DIR } from '../../config/path.config';
|
import { AUTH_DIR } from '../../../config/path.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { AuthRaw, IAuthModel, IntegrationModel } from '../models';
|
import { AuthRaw, IAuthModel, IntegrationModel } from '../../models';
|
||||||
|
|
||||||
export class AuthRepository extends Repository {
|
export class AuthRepository extends Repository {
|
||||||
constructor(
|
constructor(
|
||||||
@ -35,11 +35,11 @@ export class AuthRepository extends Repository {
|
|||||||
this.logger.verbose('saving auth to store');
|
this.logger.verbose('saving auth to store');
|
||||||
|
|
||||||
this.writeStore<AuthRaw>({
|
this.writeStore<AuthRaw>({
|
||||||
path: join(AUTH_DIR, this.auth.TYPE),
|
path: join(AUTH_DIR, 'apikey'),
|
||||||
fileName: instance,
|
fileName: instance,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance);
|
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, 'apikey') + '/' + instance);
|
||||||
|
|
||||||
this.logger.verbose('auth created');
|
this.logger.verbose('auth created');
|
||||||
return { insertCount: 1 };
|
return { insertCount: 1 };
|
||||||
@ -59,7 +59,7 @@ export class AuthRepository extends Repository {
|
|||||||
this.logger.verbose('finding auth in store');
|
this.logger.verbose('finding auth in store');
|
||||||
|
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), {
|
readFileSync(join(AUTH_DIR, 'apikey', instance + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
) as AuthRaw;
|
) as AuthRaw;
|
||||||
@ -92,14 +92,14 @@ export class AuthRepository extends Repository {
|
|||||||
this.logger.verbose('listing auth in store');
|
this.logger.verbose('listing auth in store');
|
||||||
|
|
||||||
const auths: AuthRaw[] = [];
|
const auths: AuthRaw[] = [];
|
||||||
const openDir = opendirSync(join(AUTH_DIR, this.auth.TYPE), {
|
const openDir = opendirSync(join(AUTH_DIR, 'apikey'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
for await (const dirent of openDir) {
|
for await (const dirent of openDir) {
|
||||||
if (dirent.isFile()) {
|
if (dirent.isFile()) {
|
||||||
auths.push(
|
auths.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(AUTH_DIR, this.auth.TYPE, dirent.name), {
|
readFileSync(join(AUTH_DIR, 'apikey', dirent.name), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
@ -1,10 +1,10 @@
|
|||||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService, StoreConf } from '../../config/env.config';
|
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { ChatRaw, ChatRawSelect, IChatModel } from '../models';
|
import { ChatRaw, ChatRawSelect, IChatModel } from '../../models';
|
||||||
|
|
||||||
export class ChatQuery {
|
export class ChatQuery {
|
||||||
select?: ChatRawSelect;
|
select?: ChatRawSelect;
|
@ -1,10 +1,10 @@
|
|||||||
import { opendirSync, readFileSync } from 'fs';
|
import { opendirSync, readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService, StoreConf } from '../../config/env.config';
|
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { ContactRaw, ContactRawSelect, IContactModel } from '../models';
|
import { ContactRaw, ContactRawSelect, IContactModel } from '../../models';
|
||||||
|
|
||||||
export class ContactQuery {
|
export class ContactQuery {
|
||||||
select?: ContactRawSelect;
|
select?: ContactRawSelect;
|
149
src/api/repository/mongodb/instance.repository.ts
Normal file
149
src/api/repository/mongodb/instance.repository.ts
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import { opendirSync, readFileSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
import { Auth, ConfigService } from '../../../config/env.config';
|
||||||
|
import { Logger } from '../../../config/logger.config';
|
||||||
|
import { AUTH_DIR } from '../../../config/path.config';
|
||||||
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
|
import { AuthRaw, IAuthModel, IntegrationModel } from '../../models';
|
||||||
|
|
||||||
|
export class AuthRepository extends Repository {
|
||||||
|
constructor(
|
||||||
|
private readonly authModel: IAuthModel,
|
||||||
|
private readonly integrationModel: IntegrationModel,
|
||||||
|
readonly configService: ConfigService,
|
||||||
|
) {
|
||||||
|
super(configService);
|
||||||
|
this.auth = configService.get<Auth>('AUTHENTICATION');
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly auth: Auth;
|
||||||
|
private readonly logger = new Logger('AuthRepository');
|
||||||
|
|
||||||
|
public async create(data: AuthRaw, instance: string): Promise<IInsert> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('creating auth');
|
||||||
|
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('saving auth to db');
|
||||||
|
const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
|
this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth');
|
||||||
|
return { insertCount: insert.modifiedCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('saving auth to store');
|
||||||
|
|
||||||
|
this.writeStore<AuthRaw>({
|
||||||
|
path: join(AUTH_DIR, 'apikey'),
|
||||||
|
fileName: instance,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, 'apikey') + '/' + instance);
|
||||||
|
|
||||||
|
this.logger.verbose('auth created');
|
||||||
|
return { insertCount: 1 };
|
||||||
|
} catch (error) {
|
||||||
|
return { error } as any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async find(instance: string): Promise<AuthRaw> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding auth');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding auth in db');
|
||||||
|
return await this.authModel.findOne({ _id: instance });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('finding auth in store');
|
||||||
|
|
||||||
|
return JSON.parse(
|
||||||
|
readFileSync(join(AUTH_DIR, 'apikey', instance + '.json'), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
}),
|
||||||
|
) as AuthRaw;
|
||||||
|
} catch (error) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findByKey(key: string): Promise<AuthRaw> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding auth');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding auth in db');
|
||||||
|
return await this.authModel.findOne({ apikey: key });
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
} catch (error) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async list(): Promise<AuthRaw[]> {
|
||||||
|
try {
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('listing auth in db');
|
||||||
|
return await this.authModel.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('listing auth in store');
|
||||||
|
|
||||||
|
const auths: AuthRaw[] = [];
|
||||||
|
const openDir = opendirSync(join(AUTH_DIR, 'apikey'), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
for await (const dirent of openDir) {
|
||||||
|
if (dirent.isFile()) {
|
||||||
|
auths.push(
|
||||||
|
JSON.parse(
|
||||||
|
readFileSync(join(AUTH_DIR, 'apikey', dirent.name), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return auths;
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findInstanceNameById(instanceId: string): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding auth by instanceId');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding auth in db');
|
||||||
|
const response = await this.authModel.findOne({ instanceId });
|
||||||
|
|
||||||
|
return response._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('finding auth in store is not supported');
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findInstanceNameByNumber(number: string): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding auth by number');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding auth in db');
|
||||||
|
const instance = await this.integrationModel.findOne({ number });
|
||||||
|
|
||||||
|
const response = await this.authModel.findOne({ _id: instance._id });
|
||||||
|
|
||||||
|
return response._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('finding auth in store is not supported');
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { IntegrationModel, IntegrationRaw } from '../models';
|
import { IntegrationModel, IntegrationRaw } from '../../models';
|
||||||
|
|
||||||
export class IntegrationRepository extends Repository {
|
export class IntegrationRepository extends Repository {
|
||||||
constructor(private readonly integrationModel: IntegrationModel, private readonly configService: ConfigService) {
|
constructor(private readonly integrationModel: IntegrationModel, private readonly configService: ConfigService) {
|
@ -1,10 +1,10 @@
|
|||||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService, StoreConf } from '../../config/env.config';
|
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { ILabelModel, LabelRaw, LabelRawSelect } from '../models';
|
import { ILabelModel, LabelRaw, LabelRawSelect } from '../../models';
|
||||||
|
|
||||||
export class LabelQuery {
|
export class LabelQuery {
|
||||||
select?: LabelRawSelect;
|
select?: LabelRawSelect;
|
@ -1,10 +1,10 @@
|
|||||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService, StoreConf } from '../../config/env.config';
|
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { IMessageModel, MessageRaw, MessageRawSelect } from '../models';
|
import { IMessageModel, MessageRaw, MessageRawSelect } from '../../models';
|
||||||
|
|
||||||
export class MessageQuery {
|
export class MessageQuery {
|
||||||
select?: MessageRawSelect;
|
select?: MessageRawSelect;
|
@ -1,10 +1,10 @@
|
|||||||
import { opendirSync, readFileSync } from 'fs';
|
import { opendirSync, readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService, StoreConf } from '../../config/env.config';
|
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { IMessageUpModel, MessageUpdateRaw } from '../models';
|
import { IMessageUpModel, MessageUpdateRaw } from '../../models';
|
||||||
|
|
||||||
export class MessageUpQuery {
|
export class MessageUpQuery {
|
||||||
where: MessageUpdateRaw;
|
where: MessageUpdateRaw;
|
@ -1,10 +1,10 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { IProxyModel, ProxyRaw } from '../models';
|
import { IProxyModel, ProxyRaw } from '../../models';
|
||||||
|
|
||||||
export class ProxyRepository extends Repository {
|
export class ProxyRepository extends Repository {
|
||||||
constructor(private readonly proxyModel: IProxyModel, private readonly configService: ConfigService) {
|
constructor(private readonly proxyModel: IProxyModel, private readonly configService: ConfigService) {
|
@ -1,15 +1,15 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { MongoClient } from 'mongodb';
|
import { MongoClient } from 'mongodb';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Auth, ConfigService, Database } from '../../config/env.config';
|
import { ConfigService, Database } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { ChamaaiRepository } from '../integrations/chamaai/repository/chamaai.repository';
|
import { ChatwootRepository } from '../../integrations/chatwoot/repository/chatwoot.repository';
|
||||||
import { ChatwootRepository } from '../integrations/chatwoot/repository/chatwoot.repository';
|
import { RabbitmqRepository } from '../../integrations/rabbitmq/repository/rabbitmq.repository';
|
||||||
import { RabbitmqRepository } from '../integrations/rabbitmq/repository/rabbitmq.repository';
|
import { SqsRepository } from '../../integrations/sqs/repository/sqs.repository';
|
||||||
import { SqsRepository } from '../integrations/sqs/repository/sqs.repository';
|
import { TypebotRepository } from '../../integrations/typebot/repository/typebot.repository';
|
||||||
import { TypebotRepository } from '../integrations/typebot/repository/typebot.repository';
|
import { WebsocketRepository } from '../../integrations/websocket/repository/websocket.repository';
|
||||||
import { WebsocketRepository } from '../integrations/websocket/repository/websocket.repository';
|
|
||||||
import { AuthRepository } from './auth.repository';
|
import { AuthRepository } from './auth.repository';
|
||||||
import { ChatRepository } from './chat.repository';
|
import { ChatRepository } from './chat.repository';
|
||||||
import { ContactRepository } from './contact.repository';
|
import { ContactRepository } from './contact.repository';
|
||||||
@ -20,7 +20,7 @@ import { MessageUpRepository } from './messageUp.repository';
|
|||||||
import { ProxyRepository } from './proxy.repository';
|
import { ProxyRepository } from './proxy.repository';
|
||||||
import { SettingsRepository } from './settings.repository';
|
import { SettingsRepository } from './settings.repository';
|
||||||
import { WebhookRepository } from './webhook.repository';
|
import { WebhookRepository } from './webhook.repository';
|
||||||
export class RepositoryBroker {
|
export class MongodbRepository {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly message: MessageRepository,
|
public readonly message: MessageRepository,
|
||||||
public readonly chat: ChatRepository,
|
public readonly chat: ChatRepository,
|
||||||
@ -34,22 +34,28 @@ export class RepositoryBroker {
|
|||||||
public readonly sqs: SqsRepository,
|
public readonly sqs: SqsRepository,
|
||||||
public readonly typebot: TypebotRepository,
|
public readonly typebot: TypebotRepository,
|
||||||
public readonly proxy: ProxyRepository,
|
public readonly proxy: ProxyRepository,
|
||||||
public readonly chamaai: ChamaaiRepository,
|
|
||||||
public readonly integration: IntegrationRepository,
|
public readonly integration: IntegrationRepository,
|
||||||
public readonly auth: AuthRepository,
|
public readonly auth: AuthRepository,
|
||||||
public readonly labels: LabelRepository,
|
public readonly labels: LabelRepository,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
dbServer?: MongoClient,
|
mongodbServer?: MongoClient,
|
||||||
|
prismaServer?: PrismaClient,
|
||||||
) {
|
) {
|
||||||
this.dbClient = dbServer;
|
this.mongodbClient = mongodbServer;
|
||||||
|
this.prismaClient = prismaServer;
|
||||||
this.__init_repo_without_db__();
|
this.__init_repo_without_db__();
|
||||||
}
|
}
|
||||||
|
|
||||||
private dbClient?: MongoClient;
|
private mongodbClient?: MongoClient;
|
||||||
|
private prismaClient?: PrismaClient;
|
||||||
private readonly logger = new Logger('RepositoryBroker');
|
private readonly logger = new Logger('RepositoryBroker');
|
||||||
|
|
||||||
public get dbServer() {
|
public get mongodbServer() {
|
||||||
return this.dbClient;
|
return this.mongodbClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get prismaServer() {
|
||||||
|
return this.prismaClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private __init_repo_without_db__() {
|
private __init_repo_without_db__() {
|
||||||
@ -59,7 +65,7 @@ export class RepositoryBroker {
|
|||||||
|
|
||||||
this.logger.verbose('creating store path: ' + storePath);
|
this.logger.verbose('creating store path: ' + storePath);
|
||||||
try {
|
try {
|
||||||
const authDir = join(storePath, 'auth', this.configService.get<Auth>('AUTHENTICATION').TYPE);
|
const authDir = join(storePath, 'auth', 'apikey');
|
||||||
const chatsDir = join(storePath, 'chats');
|
const chatsDir = join(storePath, 'chats');
|
||||||
const contactsDir = join(storePath, 'contacts');
|
const contactsDir = join(storePath, 'contacts');
|
||||||
const messagesDir = join(storePath, 'messages');
|
const messagesDir = join(storePath, 'messages');
|
||||||
@ -72,7 +78,6 @@ export class RepositoryBroker {
|
|||||||
const sqsDir = join(storePath, 'sqs');
|
const sqsDir = join(storePath, 'sqs');
|
||||||
const typebotDir = join(storePath, 'typebot');
|
const typebotDir = join(storePath, 'typebot');
|
||||||
const proxyDir = join(storePath, 'proxy');
|
const proxyDir = join(storePath, 'proxy');
|
||||||
const chamaaiDir = join(storePath, 'chamaai');
|
|
||||||
const integrationDir = join(storePath, 'integration');
|
const integrationDir = join(storePath, 'integration');
|
||||||
const tempDir = join(storePath, 'temp');
|
const tempDir = join(storePath, 'temp');
|
||||||
|
|
||||||
@ -128,10 +133,6 @@ export class RepositoryBroker {
|
|||||||
this.logger.verbose('creating proxy dir: ' + proxyDir);
|
this.logger.verbose('creating proxy dir: ' + proxyDir);
|
||||||
fs.mkdirSync(proxyDir, { recursive: true });
|
fs.mkdirSync(proxyDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(chamaaiDir)) {
|
|
||||||
this.logger.verbose('creating chamaai dir: ' + chamaaiDir);
|
|
||||||
fs.mkdirSync(chamaaiDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(integrationDir)) {
|
if (!fs.existsSync(integrationDir)) {
|
||||||
this.logger.verbose('creating integration dir: ' + integrationDir);
|
this.logger.verbose('creating integration dir: ' + integrationDir);
|
||||||
fs.mkdirSync(integrationDir, { recursive: true });
|
fs.mkdirSync(integrationDir, { recursive: true });
|
@ -1,10 +1,10 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { ISettingsModel, SettingsRaw } from '../models';
|
import { ISettingsModel, SettingsRaw } from '../../models';
|
||||||
|
|
||||||
export class SettingsRepository extends Repository {
|
export class SettingsRepository extends Repository {
|
||||||
constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) {
|
constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) {
|
@ -1,10 +1,10 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||||
import { IWebhookModel, WebhookRaw } from '../models';
|
import { IWebhookModel, WebhookRaw } from '../../models';
|
||||||
|
|
||||||
export class WebhookRepository extends Repository {
|
export class WebhookRepository extends Repository {
|
||||||
constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) {
|
constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) {
|
29
src/api/repository/prisma/repository.service.ts
Normal file
29
src/api/repository/prisma/repository.service.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
|
import { ConfigService } from '../../../config/env.config';
|
||||||
|
import { Logger } from '../../../config/logger.config';
|
||||||
|
|
||||||
|
export class Query<T> {
|
||||||
|
where?: T;
|
||||||
|
sort?: 'asc' | 'desc';
|
||||||
|
page?: number;
|
||||||
|
offset?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PrismaRepository extends PrismaClient {
|
||||||
|
constructor(private readonly configService: ConfigService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger(PrismaRepository.name);
|
||||||
|
|
||||||
|
public async onModuleInit() {
|
||||||
|
await this.$connect();
|
||||||
|
this.logger.info('Repository:Prisma - ON');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onModuleDestroy() {
|
||||||
|
await this.$disconnect();
|
||||||
|
this.logger.warn('Repository:Prisma - OFF');
|
||||||
|
}
|
||||||
|
}
|
@ -37,9 +37,9 @@ import {
|
|||||||
WhatsAppNumberDto,
|
WhatsAppNumberDto,
|
||||||
} from '../dto/chat.dto';
|
} from '../dto/chat.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { ContactQuery } from '../repository/contact.repository';
|
import { ContactQuery } from '../repository/mongodb/contact.repository';
|
||||||
import { MessageQuery } from '../repository/message.repository';
|
import { MessageQuery } from '../repository/mongodb/message.repository';
|
||||||
import { MessageUpQuery } from '../repository/messageUp.repository';
|
import { MessageUpQuery } from '../repository/mongodb/messageUp.repository';
|
||||||
import { chatController } from '../server.module';
|
import { chatController } from '../server.module';
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
import { Auth, configService } from '../../config/env.config';
|
import { configService } from '../../config/env.config';
|
||||||
import { authGuard } from '../guards/auth.guard';
|
import { authGuard } from '../guards/auth.guard';
|
||||||
import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard';
|
import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard';
|
||||||
import { ChamaaiRouter } from '../integrations/chamaai/routes/chamaai.router';
|
|
||||||
import { ChatwootRouter } from '../integrations/chatwoot/routes/chatwoot.router';
|
import { ChatwootRouter } from '../integrations/chatwoot/routes/chatwoot.router';
|
||||||
import { RabbitmqRouter } from '../integrations/rabbitmq/routes/rabbitmq.router';
|
import { RabbitmqRouter } from '../integrations/rabbitmq/routes/rabbitmq.router';
|
||||||
import { SqsRouter } from '../integrations/sqs/routes/sqs.router';
|
import { SqsRouter } from '../integrations/sqs/routes/sqs.router';
|
||||||
@ -31,9 +30,8 @@ enum HttpStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
const authType = configService.get<Auth>('AUTHENTICATION').TYPE;
|
|
||||||
const serverConfig = configService.get('SERVER');
|
const serverConfig = configService.get('SERVER');
|
||||||
const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]];
|
const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];
|
||||||
|
|
||||||
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
||||||
|
|
||||||
@ -45,7 +43,6 @@ router
|
|||||||
status: HttpStatus.OK,
|
status: HttpStatus.OK,
|
||||||
message: 'Welcome to the Evolution API, it is working!',
|
message: 'Welcome to the Evolution API, it is working!',
|
||||||
version: packageJson.version,
|
version: packageJson.version,
|
||||||
swagger: !serverConfig.DISABLE_DOCS ? `${req.protocol}://${req.get('host')}/docs` : undefined,
|
|
||||||
manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined,
|
manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined,
|
||||||
documentation: `https://doc.evolution-api.com`,
|
documentation: `https://doc.evolution-api.com`,
|
||||||
});
|
});
|
||||||
@ -62,7 +59,6 @@ router
|
|||||||
.use('/sqs', new SqsRouter(...guards).router)
|
.use('/sqs', new SqsRouter(...guards).router)
|
||||||
.use('/typebot', new TypebotRouter(...guards).router)
|
.use('/typebot', new TypebotRouter(...guards).router)
|
||||||
.use('/proxy', new ProxyRouter(...guards).router)
|
.use('/proxy', new ProxyRouter(...guards).router)
|
||||||
.use('/chamaai', new ChamaaiRouter(...guards).router)
|
|
||||||
.use('/label', new LabelRouter(...guards).router);
|
.use('/label', new LabelRouter(...guards).router);
|
||||||
|
|
||||||
export { HttpStatus, router };
|
export { HttpStatus, router };
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { RequestHandler, Router } from 'express';
|
import { RequestHandler, Router } from 'express';
|
||||||
|
|
||||||
import { Auth, ConfigService, Database } from '../../config/env.config';
|
import { ConfigService, Database } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||||
import { instanceNameSchema, oldTokenSchema, presenceOnlySchema } from '../../validate/validate.schema';
|
import { instanceNameSchema, presenceOnlySchema } from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
|
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
|
||||||
import { instanceController } from '../server.module';
|
import { instanceController } from '../server.module';
|
||||||
import { OldToken } from '../services/auth.service';
|
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
|
|
||||||
const logger = new Logger('InstanceRouter');
|
const logger = new Logger('InstanceRouter');
|
||||||
@ -15,7 +14,6 @@ const logger = new Logger('InstanceRouter');
|
|||||||
export class InstanceRouter extends RouterBroker {
|
export class InstanceRouter extends RouterBroker {
|
||||||
constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) {
|
constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
const auth = configService.get<Auth>('AUTHENTICATION');
|
|
||||||
this.router
|
this.router
|
||||||
.post('/create', ...guards, async (req, res) => {
|
.post('/create', ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in createInstance');
|
logger.verbose('request received in createInstance');
|
||||||
@ -165,25 +163,6 @@ export class InstanceRouter extends RouterBroker {
|
|||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (auth.TYPE === 'jwt') {
|
|
||||||
this.router.put('/refreshToken', async (req, res) => {
|
|
||||||
logger.verbose('request received in refreshToken');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<OldToken>({
|
|
||||||
request: req,
|
|
||||||
schema: oldTokenSchema,
|
|
||||||
ClassRef: OldToken,
|
|
||||||
execute: (_, data) => instanceController.refreshToken(_, data),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.router.delete('/deleteDatabase', async (req, res) => {
|
this.router.delete('/deleteDatabase', async (req, res) => {
|
||||||
logger.verbose('request received in deleteDatabase');
|
logger.verbose('request received in deleteDatabase');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
@ -194,7 +173,7 @@ export class InstanceRouter extends RouterBroker {
|
|||||||
const db = this.configService.get<Database>('DATABASE');
|
const db = this.configService.get<Database>('DATABASE');
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED) {
|
||||||
try {
|
try {
|
||||||
await dbserver.dropDatabase();
|
await mongodbServer.dropDatabase();
|
||||||
return res
|
return res
|
||||||
.status(HttpStatus.CREATED)
|
.status(HttpStatus.CREATED)
|
||||||
.json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } });
|
.json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } });
|
||||||
|
@ -2,7 +2,8 @@ import { CacheEngine } from '../cache/cacheengine';
|
|||||||
import { configService } from '../config/env.config';
|
import { configService } from '../config/env.config';
|
||||||
import { eventEmitter } from '../config/event.config';
|
import { eventEmitter } from '../config/event.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
import { dbserver } from '../libs/db.connect';
|
import { mongodbServer } from '../libs/mongodb.connect';
|
||||||
|
import { prismaServer } from '../libs/prisma.connect';
|
||||||
import { ChatController } from './controllers/chat.controller';
|
import { ChatController } from './controllers/chat.controller';
|
||||||
import { GroupController } from './controllers/group.controller';
|
import { GroupController } from './controllers/group.controller';
|
||||||
import { InstanceController } from './controllers/instance.controller';
|
import { InstanceController } from './controllers/instance.controller';
|
||||||
@ -11,9 +12,6 @@ import { ProxyController } from './controllers/proxy.controller';
|
|||||||
import { SendMessageController } from './controllers/sendMessage.controller';
|
import { SendMessageController } from './controllers/sendMessage.controller';
|
||||||
import { SettingsController } from './controllers/settings.controller';
|
import { SettingsController } from './controllers/settings.controller';
|
||||||
import { WebhookController } from './controllers/webhook.controller';
|
import { WebhookController } from './controllers/webhook.controller';
|
||||||
import { ChamaaiController } from './integrations/chamaai/controllers/chamaai.controller';
|
|
||||||
import { ChamaaiRepository } from './integrations/chamaai/repository/chamaai.repository';
|
|
||||||
import { ChamaaiService } from './integrations/chamaai/services/chamaai.service';
|
|
||||||
import { ChatwootController } from './integrations/chatwoot/controllers/chatwoot.controller';
|
import { ChatwootController } from './integrations/chatwoot/controllers/chatwoot.controller';
|
||||||
import { ChatwootRepository } from './integrations/chatwoot/repository/chatwoot.repository';
|
import { ChatwootRepository } from './integrations/chatwoot/repository/chatwoot.repository';
|
||||||
import { ChatwootService } from './integrations/chatwoot/services/chatwoot.service';
|
import { ChatwootService } from './integrations/chatwoot/services/chatwoot.service';
|
||||||
@ -31,7 +29,6 @@ import { WebsocketRepository } from './integrations/websocket/repository/websock
|
|||||||
import { WebsocketService } from './integrations/websocket/services/websocket.service';
|
import { WebsocketService } from './integrations/websocket/services/websocket.service';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChamaaiModel,
|
|
||||||
ChatModel,
|
ChatModel,
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
@ -48,17 +45,18 @@ import {
|
|||||||
} from './models';
|
} from './models';
|
||||||
import { LabelModel } from './models/label.model';
|
import { LabelModel } from './models/label.model';
|
||||||
import { ProviderFiles } from './provider/sessions';
|
import { ProviderFiles } from './provider/sessions';
|
||||||
import { AuthRepository } from './repository/auth.repository';
|
import { AuthRepository } from './repository/mongodb/auth.repository';
|
||||||
import { ChatRepository } from './repository/chat.repository';
|
import { ChatRepository } from './repository/mongodb/chat.repository';
|
||||||
import { ContactRepository } from './repository/contact.repository';
|
import { ContactRepository } from './repository/mongodb/contact.repository';
|
||||||
import { IntegrationRepository } from './repository/integration.repository';
|
import { IntegrationRepository } from './repository/mongodb/integration.repository';
|
||||||
import { LabelRepository } from './repository/label.repository';
|
import { LabelRepository } from './repository/mongodb/label.repository';
|
||||||
import { MessageRepository } from './repository/message.repository';
|
import { MessageRepository } from './repository/mongodb/message.repository';
|
||||||
import { MessageUpRepository } from './repository/messageUp.repository';
|
import { MessageUpRepository } from './repository/mongodb/messageUp.repository';
|
||||||
import { ProxyRepository } from './repository/proxy.repository';
|
import { ProxyRepository } from './repository/mongodb/proxy.repository';
|
||||||
import { RepositoryBroker } from './repository/repository.manager';
|
import { MongodbRepository } from './repository/mongodb/repository.manager';
|
||||||
import { SettingsRepository } from './repository/settings.repository';
|
import { SettingsRepository } from './repository/mongodb/settings.repository';
|
||||||
import { WebhookRepository } from './repository/webhook.repository';
|
import { WebhookRepository } from './repository/mongodb/webhook.repository';
|
||||||
|
import { PrismaRepository } from './repository/prisma/repository.service';
|
||||||
import { AuthService } from './services/auth.service';
|
import { AuthService } from './services/auth.service';
|
||||||
import { CacheService } from './services/cache.service';
|
import { CacheService } from './services/cache.service';
|
||||||
import { IntegrationService } from './services/integration.service';
|
import { IntegrationService } from './services/integration.service';
|
||||||
@ -77,7 +75,6 @@ const typebotRepository = new TypebotRepository(TypebotModel, configService);
|
|||||||
const webhookRepository = new WebhookRepository(WebhookModel, configService);
|
const webhookRepository = new WebhookRepository(WebhookModel, configService);
|
||||||
const websocketRepository = new WebsocketRepository(WebsocketModel, configService);
|
const websocketRepository = new WebsocketRepository(WebsocketModel, configService);
|
||||||
const proxyRepository = new ProxyRepository(ProxyModel, configService);
|
const proxyRepository = new ProxyRepository(ProxyModel, configService);
|
||||||
const chamaaiRepository = new ChamaaiRepository(ChamaaiModel, configService);
|
|
||||||
const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService);
|
const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService);
|
||||||
const sqsRepository = new SqsRepository(SqsModel, configService);
|
const sqsRepository = new SqsRepository(SqsModel, configService);
|
||||||
const integrationRepository = new IntegrationRepository(IntegrationModel, configService);
|
const integrationRepository = new IntegrationRepository(IntegrationModel, configService);
|
||||||
@ -86,7 +83,7 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService);
|
|||||||
const authRepository = new AuthRepository(AuthModel, IntegrationModel, configService);
|
const authRepository = new AuthRepository(AuthModel, IntegrationModel, configService);
|
||||||
const labelRepository = new LabelRepository(LabelModel, configService);
|
const labelRepository = new LabelRepository(LabelModel, configService);
|
||||||
|
|
||||||
export const repository = new RepositoryBroker(
|
export const mongodbRepository = new MongodbRepository(
|
||||||
messageRepository,
|
messageRepository,
|
||||||
chatRepository,
|
chatRepository,
|
||||||
contactRepository,
|
contactRepository,
|
||||||
@ -99,14 +96,16 @@ export const repository = new RepositoryBroker(
|
|||||||
sqsRepository,
|
sqsRepository,
|
||||||
typebotRepository,
|
typebotRepository,
|
||||||
proxyRepository,
|
proxyRepository,
|
||||||
chamaaiRepository,
|
|
||||||
integrationRepository,
|
integrationRepository,
|
||||||
authRepository,
|
authRepository,
|
||||||
labelRepository,
|
labelRepository,
|
||||||
configService,
|
configService,
|
||||||
dbserver?.getClient(),
|
mongodbServer.getClient(),
|
||||||
|
prismaServer,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const prismaRepository = new PrismaRepository(configService);
|
||||||
|
|
||||||
export const cache = new CacheService(new CacheEngine(configService, 'instance').getEngine());
|
export const cache = new CacheService(new CacheEngine(configService, 'instance').getEngine());
|
||||||
const chatwootCache = new CacheService(new CacheEngine(configService, ChatwootService.name).getEngine());
|
const chatwootCache = new CacheService(new CacheEngine(configService, ChatwootService.name).getEngine());
|
||||||
const baileysCache = new CacheService(new CacheEngine(configService, 'baileys').getEngine());
|
const baileysCache = new CacheService(new CacheEngine(configService, 'baileys').getEngine());
|
||||||
@ -115,14 +114,15 @@ const providerFiles = new ProviderFiles(configService);
|
|||||||
export const waMonitor = new WAMonitoringService(
|
export const waMonitor = new WAMonitoringService(
|
||||||
eventEmitter,
|
eventEmitter,
|
||||||
configService,
|
configService,
|
||||||
repository,
|
mongodbRepository,
|
||||||
|
prismaRepository,
|
||||||
cache,
|
cache,
|
||||||
chatwootCache,
|
chatwootCache,
|
||||||
baileysCache,
|
baileysCache,
|
||||||
providerFiles,
|
providerFiles,
|
||||||
);
|
);
|
||||||
|
|
||||||
const authService = new AuthService(configService, waMonitor, repository);
|
const authService = new AuthService(waMonitor, mongodbRepository, prismaRepository);
|
||||||
|
|
||||||
const typebotService = new TypebotService(waMonitor, configService, eventEmitter);
|
const typebotService = new TypebotService(waMonitor, configService, eventEmitter);
|
||||||
export const typebotController = new TypebotController(typebotService);
|
export const typebotController = new TypebotController(typebotService);
|
||||||
@ -136,9 +136,6 @@ export const websocketController = new WebsocketController(websocketService);
|
|||||||
const proxyService = new ProxyService(waMonitor);
|
const proxyService = new ProxyService(waMonitor);
|
||||||
export const proxyController = new ProxyController(proxyService, waMonitor);
|
export const proxyController = new ProxyController(proxyService, waMonitor);
|
||||||
|
|
||||||
const chamaaiService = new ChamaaiService(waMonitor, configService);
|
|
||||||
export const chamaaiController = new ChamaaiController(chamaaiService);
|
|
||||||
|
|
||||||
const rabbitmqService = new RabbitmqService(waMonitor);
|
const rabbitmqService = new RabbitmqService(waMonitor);
|
||||||
export const rabbitmqController = new RabbitmqController(rabbitmqService);
|
export const rabbitmqController = new RabbitmqController(rabbitmqService);
|
||||||
|
|
||||||
@ -147,8 +144,19 @@ export const sqsController = new SqsController(sqsService);
|
|||||||
|
|
||||||
const integrationService = new IntegrationService(waMonitor);
|
const integrationService = new IntegrationService(waMonitor);
|
||||||
|
|
||||||
const chatwootService = new ChatwootService(waMonitor, configService, repository, chatwootCache);
|
const chatwootService = new ChatwootService(
|
||||||
export const chatwootController = new ChatwootController(chatwootService, configService, repository);
|
waMonitor,
|
||||||
|
configService,
|
||||||
|
mongodbRepository,
|
||||||
|
prismaRepository,
|
||||||
|
chatwootCache,
|
||||||
|
);
|
||||||
|
export const chatwootController = new ChatwootController(
|
||||||
|
chatwootService,
|
||||||
|
configService,
|
||||||
|
mongodbRepository,
|
||||||
|
prismaRepository,
|
||||||
|
);
|
||||||
|
|
||||||
const settingsService = new SettingsService(waMonitor);
|
const settingsService = new SettingsService(waMonitor);
|
||||||
export const settingsController = new SettingsController(settingsService);
|
export const settingsController = new SettingsController(settingsService);
|
||||||
@ -156,7 +164,8 @@ export const settingsController = new SettingsController(settingsService);
|
|||||||
export const instanceController = new InstanceController(
|
export const instanceController = new InstanceController(
|
||||||
waMonitor,
|
waMonitor,
|
||||||
configService,
|
configService,
|
||||||
repository,
|
mongodbRepository,
|
||||||
|
prismaRepository,
|
||||||
eventEmitter,
|
eventEmitter,
|
||||||
authService,
|
authService,
|
||||||
webhookService,
|
webhookService,
|
||||||
|
@ -1,75 +1,30 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { isJWT } from 'class-validator';
|
|
||||||
import { sign, verify } from 'jsonwebtoken';
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { name as apiName } from '../../../package.json';
|
|
||||||
import { Auth, ConfigService, Webhook } from '../../config/env.config';
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { BadRequestException } from '../../exceptions';
|
import { BadRequestException } from '../../exceptions';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export type JwtPayload = {
|
|
||||||
instanceName: string;
|
|
||||||
apiName: string;
|
|
||||||
jwt?: string;
|
|
||||||
apikey?: string;
|
|
||||||
tokenId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class OldToken {
|
|
||||||
oldToken: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly configService: ConfigService,
|
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly mongodbRepository: MongodbRepository,
|
||||||
|
private readonly prismaRepository: PrismaRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(AuthService.name);
|
private readonly logger = new Logger(AuthService.name);
|
||||||
|
|
||||||
private async jwt(instance: InstanceDto) {
|
|
||||||
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
|
||||||
const token = sign(
|
|
||||||
{
|
|
||||||
instanceName: instance.instanceName,
|
|
||||||
apiName,
|
|
||||||
tokenId: v4(),
|
|
||||||
},
|
|
||||||
jwtOpts.SECRET,
|
|
||||||
{ expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' },
|
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('JWT token created: ' + token);
|
|
||||||
|
|
||||||
const auth = await this.repository.auth.create(
|
|
||||||
{ jwt: token, instanceId: instance.instanceId },
|
|
||||||
instance.instanceName,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('JWT token saved in database');
|
|
||||||
|
|
||||||
if (auth['error']) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: AuthService.name + '.jwt',
|
|
||||||
error: auth['error'],
|
|
||||||
});
|
|
||||||
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return { jwt: token };
|
|
||||||
}
|
|
||||||
|
|
||||||
private async apikey(instance: InstanceDto, token?: string) {
|
private async apikey(instance: InstanceDto, token?: string) {
|
||||||
const apikey = token ? token : v4().toUpperCase();
|
const apikey = token ? token : v4().toUpperCase();
|
||||||
|
|
||||||
this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey);
|
this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey);
|
||||||
|
|
||||||
const auth = await this.repository.auth.create({ apikey, instanceId: instance.instanceId }, instance.instanceName);
|
const auth = await this.mongodbRepository.auth.create(
|
||||||
|
{ apikey, instanceId: instance.instanceId },
|
||||||
|
instance.instanceName,
|
||||||
|
);
|
||||||
|
|
||||||
this.logger.verbose('APIKEY saved in database');
|
this.logger.verbose('APIKEY saved in database');
|
||||||
|
|
||||||
@ -101,80 +56,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async generateHash(instance: InstanceDto, token?: string) {
|
public async generateHash(instance: InstanceDto, token?: string) {
|
||||||
const options = this.configService.get<Auth>('AUTHENTICATION');
|
this.logger.verbose('generating hash apiKey to instance: ' + instance.instanceName);
|
||||||
|
|
||||||
this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName);
|
return (await this.apikey(instance, token)) as { apikey: string };
|
||||||
|
|
||||||
return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
public async refreshToken({ oldToken }: OldToken) {
|
|
||||||
this.logger.verbose('refreshing token');
|
|
||||||
|
|
||||||
if (!isJWT(oldToken)) {
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
|
||||||
|
|
||||||
this.logger.verbose('checking oldToken');
|
|
||||||
|
|
||||||
const decode = verify(oldToken, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: true,
|
|
||||||
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
|
||||||
|
|
||||||
this.logger.verbose('checking token in database');
|
|
||||||
|
|
||||||
const tokenStore = await this.repository.auth.find(decode.instanceName);
|
|
||||||
|
|
||||||
const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: true,
|
|
||||||
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
|
||||||
|
|
||||||
this.logger.verbose('checking tokenId');
|
|
||||||
|
|
||||||
if (decode.tokenId !== decodeTokenStore.tokenId) {
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('generating new token');
|
|
||||||
|
|
||||||
const token = {
|
|
||||||
jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt,
|
|
||||||
instanceName: decode.instanceName,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.logger.verbose('checking webhook');
|
|
||||||
const webhook = await this.repository.webhook.find(decode.instanceName);
|
|
||||||
if (webhook?.enabled && this.configService.get<Webhook>('WEBHOOK').EVENTS.NEW_JWT_TOKEN) {
|
|
||||||
this.logger.verbose('sending webhook');
|
|
||||||
|
|
||||||
const httpService = axios.create({ baseURL: webhook.url });
|
|
||||||
await httpService.post(
|
|
||||||
'',
|
|
||||||
{
|
|
||||||
event: 'new.jwt',
|
|
||||||
instance: decode.instanceName,
|
|
||||||
data: token,
|
|
||||||
},
|
|
||||||
{ params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('token refreshed');
|
|
||||||
|
|
||||||
return token;
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: AuthService.name + '.refreshToken',
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { ROOT_DIR } from '../../config/path.config';
|
import { ROOT_DIR } from '../../config/path.config';
|
||||||
import { NotFoundException } from '../../exceptions';
|
import { NotFoundException } from '../../exceptions';
|
||||||
import { ChamaaiService } from '../integrations/chamaai/services/chamaai.service';
|
|
||||||
import { ChatwootRaw } from '../integrations/chatwoot/models/chatwoot.model';
|
import { ChatwootRaw } from '../integrations/chatwoot/models/chatwoot.model';
|
||||||
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
|
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
|
||||||
import { getAMQP, removeQueues } from '../integrations/rabbitmq/libs/amqp.server';
|
import { getAMQP, removeQueues } from '../integrations/rabbitmq/libs/amqp.server';
|
||||||
@ -29,12 +28,13 @@ import { getSQS, removeQueues as removeQueuesSQS } from '../integrations/sqs/lib
|
|||||||
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
||||||
import { getIO } from '../integrations/websocket/libs/socket.server';
|
import { getIO } from '../integrations/websocket/libs/socket.server';
|
||||||
import { WebsocketRaw } from '../integrations/websocket/models/websocket.model';
|
import { WebsocketRaw } from '../integrations/websocket/models/websocket.model';
|
||||||
import { ChamaaiRaw, IntegrationRaw, ProxyRaw, RabbitmqRaw, SettingsRaw, SqsRaw, TypebotRaw } from '../models';
|
import { IntegrationRaw, ProxyRaw, RabbitmqRaw, SettingsRaw, SqsRaw, TypebotRaw } from '../models';
|
||||||
import { WebhookRaw } from '../models/webhook.model';
|
import { WebhookRaw } from '../models/webhook.model';
|
||||||
import { ContactQuery } from '../repository/contact.repository';
|
import { ContactQuery } from '../repository/mongodb/contact.repository';
|
||||||
import { MessageQuery } from '../repository/message.repository';
|
import { MessageQuery } from '../repository/mongodb/message.repository';
|
||||||
import { MessageUpQuery } from '../repository/messageUp.repository';
|
import { MessageUpQuery } from '../repository/mongodb/messageUp.repository';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||||
import { waMonitor } from '../server.module';
|
import { waMonitor } from '../server.module';
|
||||||
import { Events, wa } from '../types/wa.types';
|
import { Events, wa } from '../types/wa.types';
|
||||||
import { CacheService } from './cache.service';
|
import { CacheService } from './cache.service';
|
||||||
@ -43,7 +43,8 @@ export class ChannelStartupService {
|
|||||||
constructor(
|
constructor(
|
||||||
public readonly configService: ConfigService,
|
public readonly configService: ConfigService,
|
||||||
public readonly eventEmitter: EventEmitter2,
|
public readonly eventEmitter: EventEmitter2,
|
||||||
public readonly repository: RepositoryBroker,
|
public readonly mongodbRepository: MongodbRepository,
|
||||||
|
public readonly prismaRepository: PrismaRepository,
|
||||||
public readonly chatwootCache: CacheService,
|
public readonly chatwootCache: CacheService,
|
||||||
) {
|
) {
|
||||||
this.logger.verbose('ChannelStartupService initialized');
|
this.logger.verbose('ChannelStartupService initialized');
|
||||||
@ -60,17 +61,20 @@ export class ChannelStartupService {
|
|||||||
public readonly localSqs: wa.LocalSqs = {};
|
public readonly localSqs: wa.LocalSqs = {};
|
||||||
public readonly localTypebot: wa.LocalTypebot = {};
|
public readonly localTypebot: wa.LocalTypebot = {};
|
||||||
public readonly localProxy: wa.LocalProxy = {};
|
public readonly localProxy: wa.LocalProxy = {};
|
||||||
public readonly localChamaai: wa.LocalChamaai = {};
|
|
||||||
public readonly localIntegration: wa.LocalIntegration = {};
|
public readonly localIntegration: wa.LocalIntegration = {};
|
||||||
public readonly localSettings: wa.LocalSettings = {};
|
public readonly localSettings: wa.LocalSettings = {};
|
||||||
public readonly storePath = join(ROOT_DIR, 'store');
|
public readonly storePath = join(ROOT_DIR, 'store');
|
||||||
|
|
||||||
public chatwootService = new ChatwootService(waMonitor, this.configService, this.repository, this.chatwootCache);
|
public chatwootService = new ChatwootService(
|
||||||
|
waMonitor,
|
||||||
|
this.configService,
|
||||||
|
this.mongodbRepository,
|
||||||
|
this.prismaRepository,
|
||||||
|
this.chatwootCache,
|
||||||
|
);
|
||||||
|
|
||||||
public typebotService = new TypebotService(waMonitor, this.configService, this.eventEmitter);
|
public typebotService = new TypebotService(waMonitor, this.configService, this.eventEmitter);
|
||||||
|
|
||||||
public chamaaiService = new ChamaaiService(waMonitor, this.configService);
|
|
||||||
|
|
||||||
public set instanceName(name: string) {
|
public set instanceName(name: string) {
|
||||||
this.logger.setInstance(name);
|
this.logger.setInstance(name);
|
||||||
|
|
||||||
@ -112,7 +116,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadIntegration() {
|
public async loadIntegration() {
|
||||||
this.logger.verbose('Loading webhook');
|
this.logger.verbose('Loading webhook');
|
||||||
const data = await this.repository.integration.find(this.instanceName);
|
const data = await this.mongodbRepository.integration.find(this.instanceName);
|
||||||
this.localIntegration.integration = data?.integration;
|
this.localIntegration.integration = data?.integration;
|
||||||
this.logger.verbose(`Integration: ${this.localIntegration.integration}`);
|
this.logger.verbose(`Integration: ${this.localIntegration.integration}`);
|
||||||
|
|
||||||
@ -127,7 +131,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setIntegration(data: IntegrationRaw) {
|
public async setIntegration(data: IntegrationRaw) {
|
||||||
this.logger.verbose('Setting integration');
|
this.logger.verbose('Setting integration');
|
||||||
await this.repository.integration.create(data, this.instanceName);
|
await this.mongodbRepository.integration.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Integration: ${data.integration}`);
|
this.logger.verbose(`Integration: ${data.integration}`);
|
||||||
this.logger.verbose(`Integration number: ${data.number}`);
|
this.logger.verbose(`Integration number: ${data.number}`);
|
||||||
this.logger.verbose(`Integration token: ${data.token}`);
|
this.logger.verbose(`Integration token: ${data.token}`);
|
||||||
@ -139,10 +143,13 @@ export class ChannelStartupService {
|
|||||||
this.logger.verbose('Finding integration');
|
this.logger.verbose('Finding integration');
|
||||||
let data: any;
|
let data: any;
|
||||||
|
|
||||||
data = await this.repository.integration.find(this.instanceName);
|
data = await this.mongodbRepository.integration.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.repository.integration.create({ integration: 'WHATSAPP-BAILEYS', number: '', token: '' }, this.instanceName);
|
this.mongodbRepository.integration.create(
|
||||||
|
{ integration: 'WHATSAPP-BAILEYS', number: '', token: '' },
|
||||||
|
this.instanceName,
|
||||||
|
);
|
||||||
data = { integration: 'WHATSAPP-BAILEYS', number: '', token: '' };
|
data = { integration: 'WHATSAPP-BAILEYS', number: '', token: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +166,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadSettings() {
|
public async loadSettings() {
|
||||||
this.logger.verbose('Loading settings');
|
this.logger.verbose('Loading settings');
|
||||||
const data = await this.repository.settings.find(this.instanceName);
|
const data = await this.mongodbRepository.settings.find(this.instanceName);
|
||||||
this.localSettings.reject_call = data?.reject_call;
|
this.localSettings.reject_call = data?.reject_call;
|
||||||
this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`);
|
this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`);
|
||||||
|
|
||||||
@ -186,7 +193,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setSettings(data: SettingsRaw) {
|
public async setSettings(data: SettingsRaw) {
|
||||||
this.logger.verbose('Setting settings');
|
this.logger.verbose('Setting settings');
|
||||||
await this.repository.settings.create(data, this.instanceName);
|
await this.mongodbRepository.settings.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Settings reject_call: ${data.reject_call}`);
|
this.logger.verbose(`Settings reject_call: ${data.reject_call}`);
|
||||||
this.logger.verbose(`Settings msg_call: ${data.msg_call}`);
|
this.logger.verbose(`Settings msg_call: ${data.msg_call}`);
|
||||||
this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`);
|
this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`);
|
||||||
@ -200,7 +207,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findSettings() {
|
public async findSettings() {
|
||||||
this.logger.verbose('Finding settings');
|
this.logger.verbose('Finding settings');
|
||||||
const data = await this.repository.settings.find(this.instanceName);
|
const data = await this.mongodbRepository.settings.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Settings not found');
|
this.logger.verbose('Settings not found');
|
||||||
@ -227,7 +234,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadWebhook() {
|
public async loadWebhook() {
|
||||||
this.logger.verbose('Loading webhook');
|
this.logger.verbose('Loading webhook');
|
||||||
const data = await this.repository.webhook.find(this.instanceName);
|
const data = await this.mongodbRepository.webhook.find(this.instanceName);
|
||||||
this.localWebhook.url = data?.url;
|
this.localWebhook.url = data?.url;
|
||||||
this.logger.verbose(`Webhook url: ${this.localWebhook.url}`);
|
this.logger.verbose(`Webhook url: ${this.localWebhook.url}`);
|
||||||
|
|
||||||
@ -248,7 +255,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setWebhook(data: WebhookRaw) {
|
public async setWebhook(data: WebhookRaw) {
|
||||||
this.logger.verbose('Setting webhook');
|
this.logger.verbose('Setting webhook');
|
||||||
await this.repository.webhook.create(data, this.instanceName);
|
await this.mongodbRepository.webhook.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Webhook url: ${data.url}`);
|
this.logger.verbose(`Webhook url: ${data.url}`);
|
||||||
this.logger.verbose(`Webhook events: ${data.events}`);
|
this.logger.verbose(`Webhook events: ${data.events}`);
|
||||||
Object.assign(this.localWebhook, data);
|
Object.assign(this.localWebhook, data);
|
||||||
@ -257,7 +264,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findWebhook() {
|
public async findWebhook() {
|
||||||
this.logger.verbose('Finding webhook');
|
this.logger.verbose('Finding webhook');
|
||||||
const data = await this.repository.webhook.find(this.instanceName);
|
const data = await this.mongodbRepository.webhook.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Webhook not found');
|
this.logger.verbose('Webhook not found');
|
||||||
@ -278,7 +285,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadChatwoot() {
|
public async loadChatwoot() {
|
||||||
this.logger.verbose('Loading chatwoot');
|
this.logger.verbose('Loading chatwoot');
|
||||||
const data = await this.repository.chatwoot.find(this.instanceName);
|
const data = await this.mongodbRepository.chatwoot.find(this.instanceName);
|
||||||
this.localChatwoot.enabled = data?.enabled;
|
this.localChatwoot.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`);
|
this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`);
|
||||||
|
|
||||||
@ -323,7 +330,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setChatwoot(data: ChatwootRaw) {
|
public async setChatwoot(data: ChatwootRaw) {
|
||||||
this.logger.verbose('Setting chatwoot');
|
this.logger.verbose('Setting chatwoot');
|
||||||
await this.repository.chatwoot.create(data, this.instanceName);
|
await this.mongodbRepository.chatwoot.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Chatwoot account id: ${data.account_id}`);
|
this.logger.verbose(`Chatwoot account id: ${data.account_id}`);
|
||||||
this.logger.verbose(`Chatwoot token: ${data.token}`);
|
this.logger.verbose(`Chatwoot token: ${data.token}`);
|
||||||
this.logger.verbose(`Chatwoot url: ${data.url}`);
|
this.logger.verbose(`Chatwoot url: ${data.url}`);
|
||||||
@ -346,7 +353,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findChatwoot() {
|
public async findChatwoot() {
|
||||||
this.logger.verbose('Finding chatwoot');
|
this.logger.verbose('Finding chatwoot');
|
||||||
const data = await this.repository.chatwoot.find(this.instanceName);
|
const data = await this.mongodbRepository.chatwoot.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Chatwoot not found');
|
this.logger.verbose('Chatwoot not found');
|
||||||
@ -393,7 +400,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadWebsocket() {
|
public async loadWebsocket() {
|
||||||
this.logger.verbose('Loading websocket');
|
this.logger.verbose('Loading websocket');
|
||||||
const data = await this.repository.websocket.find(this.instanceName);
|
const data = await this.mongodbRepository.websocket.find(this.instanceName);
|
||||||
|
|
||||||
this.localWebsocket.enabled = data?.enabled;
|
this.localWebsocket.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Websocket enabled: ${this.localWebsocket.enabled}`);
|
this.logger.verbose(`Websocket enabled: ${this.localWebsocket.enabled}`);
|
||||||
@ -406,7 +413,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setWebsocket(data: WebsocketRaw) {
|
public async setWebsocket(data: WebsocketRaw) {
|
||||||
this.logger.verbose('Setting websocket');
|
this.logger.verbose('Setting websocket');
|
||||||
await this.repository.websocket.create(data, this.instanceName);
|
await this.mongodbRepository.websocket.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Websocket events: ${data.events}`);
|
this.logger.verbose(`Websocket events: ${data.events}`);
|
||||||
Object.assign(this.localWebsocket, data);
|
Object.assign(this.localWebsocket, data);
|
||||||
this.logger.verbose('Websocket set');
|
this.logger.verbose('Websocket set');
|
||||||
@ -414,7 +421,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findWebsocket() {
|
public async findWebsocket() {
|
||||||
this.logger.verbose('Finding websocket');
|
this.logger.verbose('Finding websocket');
|
||||||
const data = await this.repository.websocket.find(this.instanceName);
|
const data = await this.mongodbRepository.websocket.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Websocket not found');
|
this.logger.verbose('Websocket not found');
|
||||||
@ -430,7 +437,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadRabbitmq() {
|
public async loadRabbitmq() {
|
||||||
this.logger.verbose('Loading rabbitmq');
|
this.logger.verbose('Loading rabbitmq');
|
||||||
const data = await this.repository.rabbitmq.find(this.instanceName);
|
const data = await this.mongodbRepository.rabbitmq.find(this.instanceName);
|
||||||
|
|
||||||
this.localRabbitmq.enabled = data?.enabled;
|
this.localRabbitmq.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Rabbitmq enabled: ${this.localRabbitmq.enabled}`);
|
this.logger.verbose(`Rabbitmq enabled: ${this.localRabbitmq.enabled}`);
|
||||||
@ -443,7 +450,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setRabbitmq(data: RabbitmqRaw) {
|
public async setRabbitmq(data: RabbitmqRaw) {
|
||||||
this.logger.verbose('Setting rabbitmq');
|
this.logger.verbose('Setting rabbitmq');
|
||||||
await this.repository.rabbitmq.create(data, this.instanceName);
|
await this.mongodbRepository.rabbitmq.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Rabbitmq events: ${data.events}`);
|
this.logger.verbose(`Rabbitmq events: ${data.events}`);
|
||||||
Object.assign(this.localRabbitmq, data);
|
Object.assign(this.localRabbitmq, data);
|
||||||
this.logger.verbose('Rabbitmq set');
|
this.logger.verbose('Rabbitmq set');
|
||||||
@ -451,7 +458,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findRabbitmq() {
|
public async findRabbitmq() {
|
||||||
this.logger.verbose('Finding rabbitmq');
|
this.logger.verbose('Finding rabbitmq');
|
||||||
const data = await this.repository.rabbitmq.find(this.instanceName);
|
const data = await this.mongodbRepository.rabbitmq.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Rabbitmq not found');
|
this.logger.verbose('Rabbitmq not found');
|
||||||
@ -475,7 +482,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadSqs() {
|
public async loadSqs() {
|
||||||
this.logger.verbose('Loading sqs');
|
this.logger.verbose('Loading sqs');
|
||||||
const data = await this.repository.sqs.find(this.instanceName);
|
const data = await this.mongodbRepository.sqs.find(this.instanceName);
|
||||||
|
|
||||||
this.localSqs.enabled = data?.enabled;
|
this.localSqs.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Sqs enabled: ${this.localSqs.enabled}`);
|
this.logger.verbose(`Sqs enabled: ${this.localSqs.enabled}`);
|
||||||
@ -488,7 +495,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setSqs(data: SqsRaw) {
|
public async setSqs(data: SqsRaw) {
|
||||||
this.logger.verbose('Setting sqs');
|
this.logger.verbose('Setting sqs');
|
||||||
await this.repository.sqs.create(data, this.instanceName);
|
await this.mongodbRepository.sqs.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Sqs events: ${data.events}`);
|
this.logger.verbose(`Sqs events: ${data.events}`);
|
||||||
Object.assign(this.localSqs, data);
|
Object.assign(this.localSqs, data);
|
||||||
this.logger.verbose('Sqs set');
|
this.logger.verbose('Sqs set');
|
||||||
@ -496,7 +503,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findSqs() {
|
public async findSqs() {
|
||||||
this.logger.verbose('Finding sqs');
|
this.logger.verbose('Finding sqs');
|
||||||
const data = await this.repository.sqs.find(this.instanceName);
|
const data = await this.mongodbRepository.sqs.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Sqs not found');
|
this.logger.verbose('Sqs not found');
|
||||||
@ -520,7 +527,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadTypebot() {
|
public async loadTypebot() {
|
||||||
this.logger.verbose('Loading typebot');
|
this.logger.verbose('Loading typebot');
|
||||||
const data = await this.repository.typebot.find(this.instanceName);
|
const data = await this.mongodbRepository.typebot.find(this.instanceName);
|
||||||
|
|
||||||
this.localTypebot.enabled = data?.enabled;
|
this.localTypebot.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Typebot enabled: ${this.localTypebot.enabled}`);
|
this.logger.verbose(`Typebot enabled: ${this.localTypebot.enabled}`);
|
||||||
@ -553,7 +560,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setTypebot(data: TypebotRaw) {
|
public async setTypebot(data: TypebotRaw) {
|
||||||
this.logger.verbose('Setting typebot');
|
this.logger.verbose('Setting typebot');
|
||||||
await this.repository.typebot.create(data, this.instanceName);
|
await this.mongodbRepository.typebot.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Typebot typebot: ${data.typebot}`);
|
this.logger.verbose(`Typebot typebot: ${data.typebot}`);
|
||||||
this.logger.verbose(`Typebot expire: ${data.expire}`);
|
this.logger.verbose(`Typebot expire: ${data.expire}`);
|
||||||
this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`);
|
this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`);
|
||||||
@ -566,7 +573,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findTypebot() {
|
public async findTypebot() {
|
||||||
this.logger.verbose('Finding typebot');
|
this.logger.verbose('Finding typebot');
|
||||||
const data = await this.repository.typebot.find(this.instanceName);
|
const data = await this.mongodbRepository.typebot.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Typebot not found');
|
this.logger.verbose('Typebot not found');
|
||||||
@ -588,7 +595,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async loadProxy() {
|
public async loadProxy() {
|
||||||
this.logger.verbose('Loading proxy');
|
this.logger.verbose('Loading proxy');
|
||||||
const data = await this.repository.proxy.find(this.instanceName);
|
const data = await this.mongodbRepository.proxy.find(this.instanceName);
|
||||||
|
|
||||||
this.localProxy.enabled = data?.enabled;
|
this.localProxy.enabled = data?.enabled;
|
||||||
this.logger.verbose(`Proxy enabled: ${this.localProxy.enabled}`);
|
this.logger.verbose(`Proxy enabled: ${this.localProxy.enabled}`);
|
||||||
@ -601,7 +608,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async setProxy(data: ProxyRaw) {
|
public async setProxy(data: ProxyRaw) {
|
||||||
this.logger.verbose('Setting proxy');
|
this.logger.verbose('Setting proxy');
|
||||||
await this.repository.proxy.create(data, this.instanceName);
|
await this.mongodbRepository.proxy.create(data, this.instanceName);
|
||||||
this.logger.verbose(`Proxy proxy: ${data.proxy}`);
|
this.logger.verbose(`Proxy proxy: ${data.proxy}`);
|
||||||
Object.assign(this.localProxy, data);
|
Object.assign(this.localProxy, data);
|
||||||
this.logger.verbose('Proxy set');
|
this.logger.verbose('Proxy set');
|
||||||
@ -609,7 +616,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public async findProxy() {
|
public async findProxy() {
|
||||||
this.logger.verbose('Finding proxy');
|
this.logger.verbose('Finding proxy');
|
||||||
const data = await this.repository.proxy.find(this.instanceName);
|
const data = await this.mongodbRepository.proxy.find(this.instanceName);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.logger.verbose('Proxy not found');
|
this.logger.verbose('Proxy not found');
|
||||||
@ -622,70 +629,6 @@ export class ChannelStartupService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadChamaai() {
|
|
||||||
this.logger.verbose('Loading chamaai');
|
|
||||||
const data = await this.repository.chamaai.find(this.instanceName);
|
|
||||||
|
|
||||||
this.localChamaai.enabled = data?.enabled;
|
|
||||||
this.logger.verbose(`Chamaai enabled: ${this.localChamaai.enabled}`);
|
|
||||||
|
|
||||||
this.localChamaai.url = data?.url;
|
|
||||||
this.logger.verbose(`Chamaai url: ${this.localChamaai.url}`);
|
|
||||||
|
|
||||||
this.localChamaai.token = data?.token;
|
|
||||||
this.logger.verbose(`Chamaai token: ${this.localChamaai.token}`);
|
|
||||||
|
|
||||||
this.localChamaai.waNumber = data?.waNumber;
|
|
||||||
this.logger.verbose(`Chamaai waNumber: ${this.localChamaai.waNumber}`);
|
|
||||||
|
|
||||||
this.localChamaai.answerByAudio = data?.answerByAudio;
|
|
||||||
this.logger.verbose(`Chamaai answerByAudio: ${this.localChamaai.answerByAudio}`);
|
|
||||||
|
|
||||||
this.logger.verbose('Chamaai loaded');
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setChamaai(data: ChamaaiRaw) {
|
|
||||||
this.logger.verbose('Setting chamaai');
|
|
||||||
await this.repository.chamaai.create(data, this.instanceName);
|
|
||||||
this.logger.verbose(`Chamaai url: ${data.url}`);
|
|
||||||
this.logger.verbose(`Chamaai token: ${data.token}`);
|
|
||||||
this.logger.verbose(`Chamaai waNumber: ${data.waNumber}`);
|
|
||||||
this.logger.verbose(`Chamaai answerByAudio: ${data.answerByAudio}`);
|
|
||||||
|
|
||||||
Object.assign(this.localChamaai, data);
|
|
||||||
this.logger.verbose('Chamaai set');
|
|
||||||
}
|
|
||||||
|
|
||||||
public async findChamaai() {
|
|
||||||
this.logger.verbose('Finding chamaai');
|
|
||||||
const data = await this.repository.chamaai.find(this.instanceName);
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
this.logger.verbose('Chamaai not found');
|
|
||||||
throw new NotFoundException('Chamaai not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
enabled: data.enabled,
|
|
||||||
url: data.url,
|
|
||||||
token: data.token,
|
|
||||||
waNumber: data.waNumber,
|
|
||||||
answerByAudio: data.answerByAudio,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private assertExchangeAsync = (channel, exchangeName, exchangeType, options) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
channel.assertExchange(exchangeName, exchangeType, options, (error, ok) => {
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
} else {
|
|
||||||
resolve(ok);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
public async sendDataWebhook<T = any>(event: Events, data: T, local = true) {
|
public async sendDataWebhook<T = any>(event: Events, data: T, local = true) {
|
||||||
const webhookGlobal = this.configService.get<Webhook>('WEBHOOK');
|
const webhookGlobal = this.configService.get<Webhook>('WEBHOOK');
|
||||||
const webhookLocal = this.localWebhook.events;
|
const webhookLocal = this.localWebhook.events;
|
||||||
@ -703,7 +646,7 @@ export class ChannelStartupService {
|
|||||||
const now = localISOTime;
|
const now = localISOTime;
|
||||||
|
|
||||||
const expose = this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES;
|
const expose = this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES;
|
||||||
const tokenStore = await this.repository.auth.find(this.instanceName);
|
const tokenStore = await this.mongodbRepository.auth.find(this.instanceName);
|
||||||
const instanceApikey = tokenStore?.apikey || 'Apikey not found';
|
const instanceApikey = tokenStore?.apikey || 'Apikey not found';
|
||||||
|
|
||||||
if (rabbitmqEnabled) {
|
if (rabbitmqEnabled) {
|
||||||
@ -1238,7 +1181,7 @@ export class ChannelStartupService {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await this.repository.contact.find(query);
|
return await this.mongodbRepository.contact.find(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchMessages(query: MessageQuery) {
|
public async fetchMessages(query: MessageQuery) {
|
||||||
@ -1256,7 +1199,7 @@ export class ChannelStartupService {
|
|||||||
limit: query?.limit,
|
limit: query?.limit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await this.repository.message.find(query);
|
return await this.mongodbRepository.message.find(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchStatusMessage(query: MessageUpQuery) {
|
public async fetchStatusMessage(query: MessageUpQuery) {
|
||||||
@ -1274,11 +1217,11 @@ export class ChannelStartupService {
|
|||||||
limit: query?.limit,
|
limit: query?.limit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await this.repository.messageUpdate.find(query);
|
return await this.mongodbRepository.messageUpdate.find(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchChats() {
|
public async fetchChats() {
|
||||||
this.logger.verbose('Fetching chats');
|
this.logger.verbose('Fetching chats');
|
||||||
return await this.repository.chat.find({ where: { owner: this.instance.name } });
|
return await this.mongodbRepository.chat.find({ where: { owner: this.instance.name } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,10 @@ import {
|
|||||||
} from '../../../config/env.config';
|
} from '../../../config/env.config';
|
||||||
import { INSTANCE_DIR } from '../../../config/path.config';
|
import { INSTANCE_DIR } from '../../../config/path.config';
|
||||||
import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../../exceptions';
|
import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../../exceptions';
|
||||||
import { dbserver } from '../../../libs/db.connect';
|
import { mongodbServer } from '../../../libs/mongodb.connect';
|
||||||
import { makeProxyAgent } from '../../../utils/makeProxyAgent';
|
import { makeProxyAgent } from '../../../utils/makeProxyAgent';
|
||||||
import { useMultiFileAuthStateDb } from '../../../utils/use-multi-file-auth-state-db';
|
import { useMultiFileAuthStateMongoDb } from '../../../utils/use-multi-file-auth-state-mongodb';
|
||||||
|
import useMultiFileAuthStatePrisma from '../../../utils/use-multi-file-auth-state-prisma';
|
||||||
import { AuthStateProvider } from '../../../utils/use-multi-file-auth-state-provider-files';
|
import { AuthStateProvider } from '../../../utils/use-multi-file-auth-state-provider-files';
|
||||||
import { useMultiFileAuthStateRedisDb } from '../../../utils/use-multi-file-auth-state-redis-db';
|
import { useMultiFileAuthStateRedisDb } from '../../../utils/use-multi-file-auth-state-redis-db';
|
||||||
import {
|
import {
|
||||||
@ -126,7 +127,8 @@ import { ChatRaw } from '../../models/chat.model';
|
|||||||
import { ContactRaw } from '../../models/contact.model';
|
import { ContactRaw } from '../../models/contact.model';
|
||||||
import { MessageRaw, MessageUpdateRaw } from '../../models/message.model';
|
import { MessageRaw, MessageUpdateRaw } from '../../models/message.model';
|
||||||
import { ProviderFiles } from '../../provider/sessions';
|
import { ProviderFiles } from '../../provider/sessions';
|
||||||
import { RepositoryBroker } from '../../repository/repository.manager';
|
import { MongodbRepository } from '../../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../../repository/prisma/repository.service';
|
||||||
import { waMonitor } from '../../server.module';
|
import { waMonitor } from '../../server.module';
|
||||||
import { Events, MessageSubtype, TypeMediaMessage, wa } from '../../types/wa.types';
|
import { Events, MessageSubtype, TypeMediaMessage, wa } from '../../types/wa.types';
|
||||||
import { CacheService } from './../cache.service';
|
import { CacheService } from './../cache.service';
|
||||||
@ -138,13 +140,14 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
constructor(
|
constructor(
|
||||||
public readonly configService: ConfigService,
|
public readonly configService: ConfigService,
|
||||||
public readonly eventEmitter: EventEmitter2,
|
public readonly eventEmitter: EventEmitter2,
|
||||||
public readonly repository: RepositoryBroker,
|
public readonly mongoRepository: MongodbRepository,
|
||||||
|
public readonly prismaRepository: PrismaRepository,
|
||||||
public readonly cache: CacheService,
|
public readonly cache: CacheService,
|
||||||
public readonly chatwootCache: CacheService,
|
public readonly chatwootCache: CacheService,
|
||||||
public readonly baileysCache: CacheService,
|
public readonly baileysCache: CacheService,
|
||||||
private readonly providerFiles: ProviderFiles,
|
private readonly providerFiles: ProviderFiles,
|
||||||
) {
|
) {
|
||||||
super(configService, eventEmitter, repository, chatwootCache);
|
super(configService, eventEmitter, mongoRepository, prismaRepository, chatwootCache);
|
||||||
this.logger.verbose('BaileysStartupService initialized');
|
this.logger.verbose('BaileysStartupService initialized');
|
||||||
this.cleanStore();
|
this.cleanStore();
|
||||||
this.instance.qrcode = { count: 0 };
|
this.instance.qrcode = { count: 0 };
|
||||||
@ -224,7 +227,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('Profile name not found, trying to get from database');
|
this.logger.verbose('Profile name not found, trying to get from database');
|
||||||
if (this.configService.get<Database>('DATABASE').ENABLED) {
|
if (this.configService.get<Database>('DATABASE').ENABLED) {
|
||||||
this.logger.verbose('Database enabled, trying to get from database');
|
this.logger.verbose('Database enabled, trying to get from database');
|
||||||
const collection = dbserver
|
const collection = mongodbServer
|
||||||
.getClient()
|
.getClient()
|
||||||
.db(this.configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
.db(this.configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
.collection(this.instanceName);
|
.collection(this.instanceName);
|
||||||
@ -460,7 +463,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
private async getMessage(key: proto.IMessageKey, full = false) {
|
private async getMessage(key: proto.IMessageKey, full = false) {
|
||||||
this.logger.verbose('Getting message with key: ' + JSON.stringify(key));
|
this.logger.verbose('Getting message with key: ' + JSON.stringify(key));
|
||||||
try {
|
try {
|
||||||
const webMessageInfo = (await this.repository.message.find({
|
const webMessageInfo = (await this.mongodbRepository.message.find({
|
||||||
where: { owner: this.instance.name, key: { id: key.id } },
|
where: { owner: this.instance.name, key: { id: key.id } },
|
||||||
})) as unknown as proto.IWebMessageInfo[];
|
})) as unknown as proto.IWebMessageInfo[];
|
||||||
if (full) {
|
if (full) {
|
||||||
@ -510,7 +513,8 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
|
|
||||||
if (db.SAVE_DATA.INSTANCE && db.ENABLED) {
|
if (db.SAVE_DATA.INSTANCE && db.ENABLED) {
|
||||||
this.logger.verbose('Database enabled');
|
this.logger.verbose('Database enabled');
|
||||||
return await useMultiFileAuthStateDb(this.instance.name);
|
if (db.PROVIDER === 'mongodb') return await useMultiFileAuthStateMongoDb(this.instance.name);
|
||||||
|
else return await useMultiFileAuthStatePrisma(this.instance.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Store file enabled');
|
this.logger.verbose('Store file enabled');
|
||||||
@ -528,7 +532,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.loadSqs();
|
this.loadSqs();
|
||||||
this.loadTypebot();
|
this.loadTypebot();
|
||||||
this.loadProxy();
|
this.loadProxy();
|
||||||
this.loadChamaai();
|
|
||||||
|
|
||||||
this.instance.authState = await this.defineAuthState();
|
this.instance.authState = await this.defineAuthState();
|
||||||
|
|
||||||
@ -827,7 +830,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('Event received: chats.upsert');
|
this.logger.verbose('Event received: chats.upsert');
|
||||||
|
|
||||||
this.logger.verbose('Finding chats in database');
|
this.logger.verbose('Finding chats in database');
|
||||||
const chatsRepository = await this.repository.chat.find({
|
const chatsRepository = await this.mongodbRepository.chat.find({
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -845,7 +848,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw);
|
this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw);
|
||||||
|
|
||||||
this.logger.verbose('Inserting chats in database');
|
this.logger.verbose('Inserting chats in database');
|
||||||
this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS);
|
this.mongodbRepository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS);
|
||||||
},
|
},
|
||||||
|
|
||||||
'chats.update': async (
|
'chats.update': async (
|
||||||
@ -872,7 +875,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('Deleting chats in database');
|
this.logger.verbose('Deleting chats in database');
|
||||||
chats.forEach(
|
chats.forEach(
|
||||||
async (chat) =>
|
async (chat) =>
|
||||||
await this.repository.chat.delete({
|
await this.mongodbRepository.chat.delete({
|
||||||
where: { owner: this.instance.name, id: chat },
|
where: { owner: this.instance.name, id: chat },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -890,7 +893,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('Finding contacts in database');
|
this.logger.verbose('Finding contacts in database');
|
||||||
const contactsRepository = new Set(
|
const contactsRepository = new Set(
|
||||||
(
|
(
|
||||||
await this.repository.contact.find({
|
await this.mongodbRepository.contact.find({
|
||||||
select: { id: 1, _id: 0 },
|
select: { id: 1, _id: 0 },
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
})
|
})
|
||||||
@ -917,7 +920,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
if (contactsRaw.length > 0) this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw);
|
if (contactsRaw.length > 0) this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw);
|
||||||
|
|
||||||
this.logger.verbose('Inserting contacts in database');
|
this.logger.verbose('Inserting contacts in database');
|
||||||
this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
this.mongodbRepository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
|
|
||||||
if (this.localChatwoot.enabled && this.localChatwoot.import_contacts && contactsRaw.length) {
|
if (this.localChatwoot.enabled && this.localChatwoot.import_contacts && contactsRaw.length) {
|
||||||
this.chatwootService.addHistoryContacts({ instanceName: this.instance.name }, contactsRaw);
|
this.chatwootService.addHistoryContacts({ instanceName: this.instance.name }, contactsRaw);
|
||||||
@ -939,7 +942,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
if (contactsRaw.length > 0) this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw);
|
if (contactsRaw.length > 0) this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw);
|
||||||
|
|
||||||
this.logger.verbose('Updating contacts in database');
|
this.logger.verbose('Updating contacts in database');
|
||||||
this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
this.mongodbRepository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
@ -963,7 +966,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw);
|
this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw);
|
||||||
|
|
||||||
this.logger.verbose('Updating contacts in database');
|
this.logger.verbose('Updating contacts in database');
|
||||||
this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
this.mongodbRepository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1004,7 +1007,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
const chatsRaw: ChatRaw[] = [];
|
const chatsRaw: ChatRaw[] = [];
|
||||||
const chatsRepository = new Set(
|
const chatsRepository = new Set(
|
||||||
(
|
(
|
||||||
await this.repository.chat.find({
|
await this.mongodbRepository.chat.find({
|
||||||
select: { id: 1, _id: 0 },
|
select: { id: 1, _id: 0 },
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
})
|
})
|
||||||
@ -1027,13 +1030,13 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.CHATS_SET, chatsRaw);
|
this.sendDataWebhook(Events.CHATS_SET, chatsRaw);
|
||||||
|
|
||||||
this.logger.verbose('Inserting chats in database');
|
this.logger.verbose('Inserting chats in database');
|
||||||
this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS);
|
this.mongodbRepository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS);
|
||||||
|
|
||||||
const messagesRaw: MessageRaw[] = [];
|
const messagesRaw: MessageRaw[] = [];
|
||||||
const messagesRepository = new Set(
|
const messagesRepository = new Set(
|
||||||
chatwootImport.getRepositoryMessagesCache(instance) ??
|
chatwootImport.getRepositoryMessagesCache(instance) ??
|
||||||
(
|
(
|
||||||
await this.repository.message.find({
|
await this.mongodbRepository.message.find({
|
||||||
select: { key: { id: 1 }, _id: 0 },
|
select: { key: { id: 1 }, _id: 0 },
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
})
|
})
|
||||||
@ -1086,7 +1089,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]);
|
this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]);
|
||||||
|
|
||||||
this.logger.verbose('Inserting messages in database');
|
this.logger.verbose('Inserting messages in database');
|
||||||
await this.repository.message.insert(messagesRaw, this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
await this.mongodbRepository.message.insert(messagesRaw, this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
||||||
|
|
||||||
if (this.localChatwoot.enabled && this.localChatwoot.import_messages && messagesRaw.length > 0) {
|
if (this.localChatwoot.enabled && this.localChatwoot.import_messages && messagesRaw.length > 0) {
|
||||||
this.chatwootService.addHistoryMessages(
|
this.chatwootService.addHistoryMessages(
|
||||||
@ -1262,19 +1265,11 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.localChamaai.enabled && messageRaw.key.fromMe === false && type === 'notify') {
|
|
||||||
await this.chamaaiService.sendChamaai(
|
|
||||||
{ instanceName: this.instance.name },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
await this.mongodbRepository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
||||||
|
|
||||||
this.logger.verbose('Verifying contact from message');
|
this.logger.verbose('Verifying contact from message');
|
||||||
const contact = await this.repository.contact.find({
|
const contact = await this.mongodbRepository.contact.find({
|
||||||
where: { owner: this.instance.name, id: received.key.remoteJid },
|
where: { owner: this.instance.name, id: received.key.remoteJid },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1311,7 +1306,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Updating contact in database');
|
this.logger.verbose('Updating contact in database');
|
||||||
await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
await this.mongodbRepository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1321,7 +1316,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);
|
this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);
|
||||||
|
|
||||||
this.logger.verbose('Inserting contact in database');
|
this.logger.verbose('Inserting contact in database');
|
||||||
this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
this.mongodbRepository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
@ -1388,7 +1383,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose(message);
|
this.logger.verbose(message);
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.messageUpdate.insert(
|
await this.mongodbRepository.messageUpdate.insert(
|
||||||
[message],
|
[message],
|
||||||
this.instance.name,
|
this.instance.name,
|
||||||
database.SAVE_DATA.MESSAGE_UPDATE,
|
database.SAVE_DATA.MESSAGE_UPDATE,
|
||||||
@ -1419,7 +1414,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
|
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
this.repository.messageUpdate.insert([message], this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE);
|
this.mongodbRepository.messageUpdate.insert([message], this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1462,14 +1457,14 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
[Events.LABELS_EDIT]: async (label: Label, database: Database) => {
|
[Events.LABELS_EDIT]: async (label: Label, database: Database) => {
|
||||||
this.logger.verbose('Event received: labels.edit');
|
this.logger.verbose('Event received: labels.edit');
|
||||||
this.logger.verbose('Finding labels in database');
|
this.logger.verbose('Finding labels in database');
|
||||||
const labelsRepository = await this.repository.labels.find({
|
const labelsRepository = await this.mongodbRepository.labels.find({
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
});
|
});
|
||||||
|
|
||||||
const savedLabel = labelsRepository.find((l) => l.id === label.id);
|
const savedLabel = labelsRepository.find((l) => l.id === label.id);
|
||||||
if (label.deleted && savedLabel) {
|
if (label.deleted && savedLabel) {
|
||||||
this.logger.verbose('Sending data to webhook in event LABELS_EDIT');
|
this.logger.verbose('Sending data to webhook in event LABELS_EDIT');
|
||||||
await this.repository.labels.delete({
|
await this.mongodbRepository.labels.delete({
|
||||||
where: { owner: this.instance.name, id: label.id },
|
where: { owner: this.instance.name, id: label.id },
|
||||||
});
|
});
|
||||||
this.sendDataWebhook(Events.LABELS_EDIT, { ...label, instance: this.instance.name });
|
this.sendDataWebhook(Events.LABELS_EDIT, { ...label, instance: this.instance.name });
|
||||||
@ -1479,7 +1474,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
const labelName = label.name.replace(/[^\x20-\x7E]/g, '');
|
const labelName = label.name.replace(/[^\x20-\x7E]/g, '');
|
||||||
if (!savedLabel || savedLabel.color !== label.color || savedLabel.name !== labelName) {
|
if (!savedLabel || savedLabel.color !== label.color || savedLabel.name !== labelName) {
|
||||||
this.logger.verbose('Sending data to webhook in event LABELS_EDIT');
|
this.logger.verbose('Sending data to webhook in event LABELS_EDIT');
|
||||||
await this.repository.labels.insert(
|
await this.mongodbRepository.labels.insert(
|
||||||
{
|
{
|
||||||
color: label.color,
|
color: label.color,
|
||||||
name: labelName,
|
name: labelName,
|
||||||
@ -1502,7 +1497,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
|
|
||||||
// Atualiza labels nos chats
|
// Atualiza labels nos chats
|
||||||
if (database.ENABLED && database.SAVE_DATA.CHATS) {
|
if (database.ENABLED && database.SAVE_DATA.CHATS) {
|
||||||
const chats = await this.repository.chat.find({
|
const chats = await this.mongodbRepository.chat.find({
|
||||||
where: {
|
where: {
|
||||||
owner: this.instance.name,
|
owner: this.instance.name,
|
||||||
},
|
},
|
||||||
@ -1515,7 +1510,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
} else if (data.type === 'add') {
|
} else if (data.type === 'add') {
|
||||||
labels = [...labels, data.association.labelId];
|
labels = [...labels, data.association.labelId];
|
||||||
}
|
}
|
||||||
await this.repository.chat.update(
|
await this.mongodbRepository.chat.update(
|
||||||
[{ id: chat.id, owner: this.instance.name, labels }],
|
[{ id: chat.id, owner: this.instance.name, labels }],
|
||||||
this.instance.name,
|
this.instance.name,
|
||||||
database.SAVE_DATA.CHATS,
|
database.SAVE_DATA.CHATS,
|
||||||
@ -2041,7 +2036,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.message.insert(
|
await this.mongodbRepository.message.insert(
|
||||||
[messageRaw],
|
[messageRaw],
|
||||||
this.instance.name,
|
this.instance.name,
|
||||||
this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE,
|
this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE,
|
||||||
@ -2160,7 +2155,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('All contacts defined as true');
|
this.logger.verbose('All contacts defined as true');
|
||||||
|
|
||||||
this.logger.verbose('Getting contacts from database');
|
this.logger.verbose('Getting contacts from database');
|
||||||
const contacts = await this.repository.contact.find({
|
const contacts = await this.mongodbRepository.contact.find({
|
||||||
where: { owner: this.instance.name },
|
where: { owner: this.instance.name },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2686,7 +2681,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
onWhatsapp.push(...groups);
|
onWhatsapp.push(...groups);
|
||||||
|
|
||||||
// USERS
|
// USERS
|
||||||
const contacts: ContactRaw[] = await this.repository.contact.findManyById({
|
const contacts: ContactRaw[] = await this.mongodbRepository.contact.findManyById({
|
||||||
owner: this.instance.name,
|
owner: this.instance.name,
|
||||||
ids: jids.users.map(({ jid }) => (jid.startsWith('+') ? jid.substring(1) : jid)),
|
ids: jids.users.map(({ jid }) => (jid.startsWith('+') ? jid.substring(1) : jid)),
|
||||||
});
|
});
|
||||||
@ -3177,7 +3172,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
|
|
||||||
public async fetchLabels(): Promise<LabelDto[]> {
|
public async fetchLabels(): Promise<LabelDto[]> {
|
||||||
this.logger.verbose('Fetching labels');
|
this.logger.verbose('Fetching labels');
|
||||||
const labels = await this.repository.labels.find({
|
const labels = await this.mongodbRepository.labels.find({
|
||||||
where: {
|
where: {
|
||||||
owner: this.instance.name,
|
owner: this.instance.name,
|
||||||
},
|
},
|
||||||
@ -3485,7 +3480,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose('Fetching participants for group: ' + id.groupJid);
|
this.logger.verbose('Fetching participants for group: ' + id.groupJid);
|
||||||
try {
|
try {
|
||||||
const participants = (await this.client.groupMetadata(id.groupJid)).participants;
|
const participants = (await this.client.groupMetadata(id.groupJid)).participants;
|
||||||
const contacts = await this.repository.contact.findManyById({
|
const contacts = await this.mongodbRepository.contact.findManyById({
|
||||||
owner: this.instance.name,
|
owner: this.instance.name,
|
||||||
ids: participants.map((p) => p.id),
|
ids: participants.map((p) => p.id),
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,8 @@ import {
|
|||||||
} from '../../dto/sendMessage.dto';
|
} from '../../dto/sendMessage.dto';
|
||||||
import { ContactRaw, MessageRaw, MessageUpdateRaw, SettingsRaw } from '../../models';
|
import { ContactRaw, MessageRaw, MessageUpdateRaw, SettingsRaw } from '../../models';
|
||||||
import { ProviderFiles } from '../../provider/sessions';
|
import { ProviderFiles } from '../../provider/sessions';
|
||||||
import { RepositoryBroker } from '../../repository/repository.manager';
|
import { MongodbRepository } from '../../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../../repository/prisma/repository.service';
|
||||||
import { Events, wa } from '../../types/wa.types';
|
import { Events, wa } from '../../types/wa.types';
|
||||||
import { CacheService } from './../cache.service';
|
import { CacheService } from './../cache.service';
|
||||||
import { ChannelStartupService } from './../channel.service';
|
import { ChannelStartupService } from './../channel.service';
|
||||||
@ -33,13 +34,14 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
constructor(
|
constructor(
|
||||||
public readonly configService: ConfigService,
|
public readonly configService: ConfigService,
|
||||||
public readonly eventEmitter: EventEmitter2,
|
public readonly eventEmitter: EventEmitter2,
|
||||||
public readonly repository: RepositoryBroker,
|
public readonly mongodbRepository: MongodbRepository,
|
||||||
|
public readonly prismaRepository: PrismaRepository,
|
||||||
public readonly cache: CacheService,
|
public readonly cache: CacheService,
|
||||||
public readonly chatwootCache: CacheService,
|
public readonly chatwootCache: CacheService,
|
||||||
public readonly baileysCache: CacheService,
|
public readonly baileysCache: CacheService,
|
||||||
private readonly providerFiles: ProviderFiles,
|
private readonly providerFiles: ProviderFiles,
|
||||||
) {
|
) {
|
||||||
super(configService, eventEmitter, repository, chatwootCache);
|
super(configService, eventEmitter, mongodbRepository, prismaRepository, chatwootCache);
|
||||||
this.logger.verbose('BusinessStartupService initialized');
|
this.logger.verbose('BusinessStartupService initialized');
|
||||||
this.cleanStore();
|
this.cleanStore();
|
||||||
}
|
}
|
||||||
@ -146,7 +148,6 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
this.loadRabbitmq();
|
this.loadRabbitmq();
|
||||||
this.loadSqs();
|
this.loadSqs();
|
||||||
this.loadTypebot();
|
this.loadTypebot();
|
||||||
this.loadChamaai();
|
|
||||||
|
|
||||||
this.logger.verbose('Creating socket');
|
this.logger.verbose('Creating socket');
|
||||||
|
|
||||||
@ -442,19 +443,11 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.localChamaai.enabled && messageRaw.key.fromMe === false && received?.message.type === 'notify') {
|
|
||||||
await this.chamaaiService.sendChamaai(
|
|
||||||
{ instanceName: this.instance.name },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
await this.mongodbRepository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
||||||
|
|
||||||
this.logger.verbose('Verifying contact from message');
|
this.logger.verbose('Verifying contact from message');
|
||||||
const contact = await this.repository.contact.find({
|
const contact = await this.mongodbRepository.contact.find({
|
||||||
where: { owner: this.instance.name, id: key.remoteJid },
|
where: { owner: this.instance.name, id: key.remoteJid },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -491,7 +484,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Updating contact in database');
|
this.logger.verbose('Updating contact in database');
|
||||||
await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
await this.mongodbRepository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +494,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);
|
this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);
|
||||||
|
|
||||||
this.logger.verbose('Inserting contact in database');
|
this.logger.verbose('Inserting contact in database');
|
||||||
this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
this.mongodbRepository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||||
}
|
}
|
||||||
this.logger.verbose('Event received: messages.update');
|
this.logger.verbose('Event received: messages.update');
|
||||||
if (received.statuses) {
|
if (received.statuses) {
|
||||||
@ -536,7 +529,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
this.logger.verbose(message);
|
this.logger.verbose(message);
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.messageUpdate.insert(
|
await this.mongodbRepository.messageUpdate.insert(
|
||||||
[message],
|
[message],
|
||||||
this.instance.name,
|
this.instance.name,
|
||||||
database.SAVE_DATA.MESSAGE_UPDATE,
|
database.SAVE_DATA.MESSAGE_UPDATE,
|
||||||
@ -566,7 +559,11 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
|
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
this.repository.messageUpdate.insert([message], this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE);
|
this.mongodbRepository.messageUpdate.insert(
|
||||||
|
[message],
|
||||||
|
this.instance.name,
|
||||||
|
database.SAVE_DATA.MESSAGE_UPDATE,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -871,7 +868,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Inserting message in database');
|
this.logger.verbose('Inserting message in database');
|
||||||
await this.repository.message.insert(
|
await this.mongodbRepository.message.insert(
|
||||||
[messageRaw],
|
[messageRaw],
|
||||||
this.instance.name,
|
this.instance.name,
|
||||||
this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE,
|
this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE,
|
||||||
|
@ -19,7 +19,6 @@ import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config';
|
|||||||
import { NotFoundException } from '../../exceptions';
|
import { NotFoundException } from '../../exceptions';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChamaaiModel,
|
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
LabelModel,
|
LabelModel,
|
||||||
@ -31,7 +30,8 @@ import {
|
|||||||
WebsocketModel,
|
WebsocketModel,
|
||||||
} from '../models';
|
} from '../models';
|
||||||
import { ProviderFiles } from '../provider/sessions';
|
import { ProviderFiles } from '../provider/sessions';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||||
|
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||||
import { Integration } from '../types/wa.types';
|
import { Integration } from '../types/wa.types';
|
||||||
import { CacheService } from './cache.service';
|
import { CacheService } from './cache.service';
|
||||||
import { BaileysStartupService } from './channels/whatsapp.baileys.service';
|
import { BaileysStartupService } from './channels/whatsapp.baileys.service';
|
||||||
@ -41,7 +41,8 @@ export class WAMonitoringService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly monogodbRepository: MongodbRepository,
|
||||||
|
private readonly primaRepository: PrismaRepository,
|
||||||
private readonly cache: CacheService,
|
private readonly cache: CacheService,
|
||||||
private readonly chatwootCache: CacheService,
|
private readonly chatwootCache: CacheService,
|
||||||
private readonly baileysCache: CacheService,
|
private readonly baileysCache: CacheService,
|
||||||
@ -56,7 +57,7 @@ export class WAMonitoringService {
|
|||||||
Object.assign(this.redis, configService.get<CacheConf>('CACHE'));
|
Object.assign(this.redis, configService.get<CacheConf>('CACHE'));
|
||||||
|
|
||||||
this.dbInstance = this.db.ENABLED
|
this.dbInstance = this.db.ENABLED
|
||||||
? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
? this.monogodbRepository.mongodbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ export class WAMonitoringService {
|
|||||||
const instanceData = {
|
const instanceData = {
|
||||||
instance: {
|
instance: {
|
||||||
instanceName: key,
|
instanceName: key,
|
||||||
instanceId: (await this.repository.auth.find(key))?.instanceId,
|
instanceId: (await this.monogodbRepository.auth.find(key))?.instanceId,
|
||||||
owner: value.wuid,
|
owner: value.wuid,
|
||||||
profileName: (await value.getProfileName()) || 'not loaded',
|
profileName: (await value.getProfileName()) || 'not loaded',
|
||||||
profilePictureUrl: value.profilePictureUrl,
|
profilePictureUrl: value.profilePictureUrl,
|
||||||
@ -147,7 +148,7 @@ export class WAMonitoringService {
|
|||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
instanceData.instance['apikey'] = (await this.monogodbRepository.auth.find(key))?.apikey;
|
||||||
|
|
||||||
instanceData.instance['chatwoot'] = chatwoot;
|
instanceData.instance['chatwoot'] = chatwoot;
|
||||||
|
|
||||||
@ -161,7 +162,7 @@ export class WAMonitoringService {
|
|||||||
const instanceData = {
|
const instanceData = {
|
||||||
instance: {
|
instance: {
|
||||||
instanceName: key,
|
instanceName: key,
|
||||||
instanceId: (await this.repository.auth.find(key))?.instanceId,
|
instanceId: (await this.monogodbRepository.auth.find(key))?.instanceId,
|
||||||
status: value.connectionStatus.state,
|
status: value.connectionStatus.state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -169,7 +170,7 @@ export class WAMonitoringService {
|
|||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
instanceData.instance['apikey'] = (await this.monogodbRepository.auth.find(key))?.apikey;
|
||||||
|
|
||||||
instanceData.instance['chatwoot'] = chatwoot;
|
instanceData.instance['chatwoot'] = chatwoot;
|
||||||
|
|
||||||
@ -193,12 +194,12 @@ export class WAMonitoringService {
|
|||||||
this.logger.verbose('get instance info');
|
this.logger.verbose('get instance info');
|
||||||
let instanceName: string;
|
let instanceName: string;
|
||||||
if (instanceId) {
|
if (instanceId) {
|
||||||
instanceName = await this.repository.auth.findInstanceNameById(instanceId);
|
instanceName = await this.monogodbRepository.auth.findInstanceNameById(instanceId);
|
||||||
if (!instanceName) {
|
if (!instanceName) {
|
||||||
throw new NotFoundException(`Instance "${instanceId}" not found`);
|
throw new NotFoundException(`Instance "${instanceId}" not found`);
|
||||||
}
|
}
|
||||||
} else if (number) {
|
} else if (number) {
|
||||||
instanceName = await this.repository.auth.findInstanceNameByNumber(number);
|
instanceName = await this.monogodbRepository.auth.findInstanceNameByNumber(number);
|
||||||
if (!instanceName) {
|
if (!instanceName) {
|
||||||
throw new NotFoundException(`Instance "${number}" not found`);
|
throw new NotFoundException(`Instance "${number}" not found`);
|
||||||
}
|
}
|
||||||
@ -254,7 +255,7 @@ export class WAMonitoringService {
|
|||||||
|
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
||||||
await this.repository.dbServer.connect();
|
await this.monogodbRepository.mongodbServer.connect();
|
||||||
const collections: any[] = await this.dbInstance.collections();
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
if (collections.length > 0) {
|
if (collections.length > 0) {
|
||||||
await this.dbInstance.dropCollection(instanceName);
|
await this.dbInstance.dropCollection(instanceName);
|
||||||
@ -291,7 +292,6 @@ export class WAMonitoringService {
|
|||||||
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chamaai', instanceName + '*')}`);
|
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`);
|
||||||
@ -307,7 +307,6 @@ export class WAMonitoringService {
|
|||||||
await AuthModel.deleteMany({ _id: instanceName });
|
await AuthModel.deleteMany({ _id: instanceName });
|
||||||
await WebhookModel.deleteMany({ _id: instanceName });
|
await WebhookModel.deleteMany({ _id: instanceName });
|
||||||
await ChatwootModel.deleteMany({ _id: instanceName });
|
await ChatwootModel.deleteMany({ _id: instanceName });
|
||||||
await ChamaaiModel.deleteMany({ _id: instanceName });
|
|
||||||
await ProxyModel.deleteMany({ _id: instanceName });
|
await ProxyModel.deleteMany({ _id: instanceName });
|
||||||
await RabbitmqModel.deleteMany({ _id: instanceName });
|
await RabbitmqModel.deleteMany({ _id: instanceName });
|
||||||
await TypebotModel.deleteMany({ _id: instanceName });
|
await TypebotModel.deleteMany({ _id: instanceName });
|
||||||
@ -328,7 +327,8 @@ export class WAMonitoringService {
|
|||||||
} else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) {
|
} else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) {
|
||||||
await this.loadInstancesFromRedis();
|
await this.loadInstancesFromRedis();
|
||||||
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
await this.loadInstancesFromDatabase();
|
if (this.db.PROVIDER === 'mongodb') await this.loadInstancesFromDatabaseMongoDB();
|
||||||
|
else if (this.db.PROVIDER === 'postgresql') await this.loadInstancesFromDatabasePostgres();
|
||||||
} else {
|
} else {
|
||||||
await this.loadInstancesFromFiles();
|
await this.loadInstancesFromFiles();
|
||||||
}
|
}
|
||||||
@ -343,7 +343,7 @@ export class WAMonitoringService {
|
|||||||
try {
|
try {
|
||||||
const msgParsed = JSON.parse(JSON.stringify(data));
|
const msgParsed = JSON.parse(JSON.stringify(data));
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
await this.repository.dbServer.connect();
|
await this.monogodbRepository.mongodbServer.connect();
|
||||||
await this.dbInstance.collection(data.instanceName).replaceOne({ _id: 'integration' }, msgParsed, {
|
await this.dbInstance.collection(data.instanceName).replaceOne({ _id: 'integration' }, msgParsed, {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
});
|
});
|
||||||
@ -358,14 +358,15 @@ export class WAMonitoringService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async setInstance(name: string) {
|
private async setInstance(name: string) {
|
||||||
const integration = await this.repository.integration.find(name);
|
const integration = await this.monogodbRepository.integration.find(name);
|
||||||
|
|
||||||
let instance: BaileysStartupService | BusinessStartupService;
|
let instance: BaileysStartupService | BusinessStartupService;
|
||||||
if (integration && integration.integration === Integration.WHATSAPP_BUSINESS) {
|
if (integration && integration.integration === Integration.WHATSAPP_BUSINESS) {
|
||||||
instance = new BusinessStartupService(
|
instance = new BusinessStartupService(
|
||||||
this.configService,
|
this.configService,
|
||||||
this.eventEmitter,
|
this.eventEmitter,
|
||||||
this.repository,
|
this.monogodbRepository,
|
||||||
|
this.primaRepository,
|
||||||
this.cache,
|
this.cache,
|
||||||
this.chatwootCache,
|
this.chatwootCache,
|
||||||
this.baileysCache,
|
this.baileysCache,
|
||||||
@ -377,7 +378,8 @@ export class WAMonitoringService {
|
|||||||
instance = new BaileysStartupService(
|
instance = new BaileysStartupService(
|
||||||
this.configService,
|
this.configService,
|
||||||
this.eventEmitter,
|
this.eventEmitter,
|
||||||
this.repository,
|
this.monogodbRepository,
|
||||||
|
this.primaRepository,
|
||||||
this.cache,
|
this.cache,
|
||||||
this.chatwootCache,
|
this.chatwootCache,
|
||||||
this.baileysCache,
|
this.baileysCache,
|
||||||
@ -410,9 +412,9 @@ export class WAMonitoringService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadInstancesFromDatabase() {
|
private async loadInstancesFromDatabaseMongoDB() {
|
||||||
this.logger.verbose('Database enabled');
|
this.logger.verbose('Database enabled');
|
||||||
await this.repository.dbServer.connect();
|
await this.monogodbRepository.mongodbServer.connect();
|
||||||
const collections: any[] = await this.dbInstance.collections();
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
await this.deleteTempInstances(collections);
|
await this.deleteTempInstances(collections);
|
||||||
if (collections.length > 0) {
|
if (collections.length > 0) {
|
||||||
@ -423,6 +425,20 @@ export class WAMonitoringService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async loadInstancesFromDatabasePostgres() {
|
||||||
|
this.logger.verbose('Database enabled');
|
||||||
|
await this.primaRepository.onModuleInit();
|
||||||
|
|
||||||
|
const instances = await this.primaRepository.instance.findMany();
|
||||||
|
|
||||||
|
if (instances.length === 0) {
|
||||||
|
this.logger.verbose('No instances found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(instances.map(async (instance) => this.setInstance(instance.name)));
|
||||||
|
}
|
||||||
|
|
||||||
private async loadInstancesFromProvider() {
|
private async loadInstancesFromProvider() {
|
||||||
this.logger.verbose('Provider in files enabled');
|
this.logger.verbose('Provider in files enabled');
|
||||||
const [instances] = await this.providerFiles.allInstances();
|
const [instances] = await this.providerFiles.allInstances();
|
||||||
@ -523,7 +539,7 @@ export class WAMonitoringService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.verbose('Cleaning up temp instances');
|
this.logger.verbose('Cleaning up temp instances');
|
||||||
const auths = await this.repository.auth.list();
|
const auths = await this.monogodbRepository.auth.list();
|
||||||
if (auths.length === 0) {
|
if (auths.length === 0) {
|
||||||
this.logger.verbose('No temp instances found');
|
this.logger.verbose('No temp instances found');
|
||||||
return;
|
return;
|
||||||
|
@ -27,7 +27,6 @@ export enum Events {
|
|||||||
CALL = 'call',
|
CALL = 'call',
|
||||||
TYPEBOT_START = 'typebot.start',
|
TYPEBOT_START = 'typebot.start',
|
||||||
TYPEBOT_CHANGE_STATUS = 'typebot.change-status',
|
TYPEBOT_CHANGE_STATUS = 'typebot.change-status',
|
||||||
CHAMA_AI_ACTION = 'chama-ai.action',
|
|
||||||
LABELS_EDIT = 'labels.edit',
|
LABELS_EDIT = 'labels.edit',
|
||||||
LABELS_ASSOCIATION = 'labels.association',
|
LABELS_ASSOCIATION = 'labels.association',
|
||||||
CREDS_UPDATE = 'creds.update',
|
CREDS_UPDATE = 'creds.update',
|
||||||
@ -131,14 +130,6 @@ export declare namespace wa {
|
|||||||
proxy?: Proxy;
|
proxy?: Proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalChamaai = {
|
|
||||||
enabled?: boolean;
|
|
||||||
url?: string;
|
|
||||||
token?: string;
|
|
||||||
waNumber?: string;
|
|
||||||
answerByAudio?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LocalIntegration = {
|
export type LocalIntegration = {
|
||||||
integration?: string;
|
integration?: string;
|
||||||
number?: string;
|
number?: string;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { isBooleanString } from 'class-validator';
|
import { isBooleanString } from 'class-validator';
|
||||||
import { readFileSync } from 'fs';
|
import dotenv from 'dotenv';
|
||||||
import { load } from 'js-yaml';
|
|
||||||
import { join } from 'path';
|
dotenv.config();
|
||||||
|
|
||||||
export type HttpServer = {
|
export type HttpServer = {
|
||||||
TYPE: 'http' | 'https';
|
TYPE: 'http' | 'https';
|
||||||
@ -67,6 +67,7 @@ export type DBConnection = {
|
|||||||
export type Database = {
|
export type Database = {
|
||||||
CONNECTION: DBConnection;
|
CONNECTION: DBConnection;
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
|
PROVIDER: string;
|
||||||
SAVE_DATA: SaveData;
|
SAVE_DATA: SaveData;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,7 +96,6 @@ export type EventsRabbitmq = {
|
|||||||
GROUP_UPDATE: boolean;
|
GROUP_UPDATE: boolean;
|
||||||
GROUP_PARTICIPANTS_UPDATE: boolean;
|
GROUP_PARTICIPANTS_UPDATE: boolean;
|
||||||
CALL: boolean;
|
CALL: boolean;
|
||||||
NEW_JWT_TOKEN: boolean;
|
|
||||||
TYPEBOT_START: boolean;
|
TYPEBOT_START: boolean;
|
||||||
TYPEBOT_CHANGE_STATUS: boolean;
|
TYPEBOT_CHANGE_STATUS: boolean;
|
||||||
};
|
};
|
||||||
@ -153,22 +153,17 @@ export type EventsWebhook = {
|
|||||||
GROUP_UPDATE: boolean;
|
GROUP_UPDATE: boolean;
|
||||||
GROUP_PARTICIPANTS_UPDATE: boolean;
|
GROUP_PARTICIPANTS_UPDATE: boolean;
|
||||||
CALL: boolean;
|
CALL: boolean;
|
||||||
NEW_JWT_TOKEN: boolean;
|
|
||||||
TYPEBOT_START: boolean;
|
TYPEBOT_START: boolean;
|
||||||
TYPEBOT_CHANGE_STATUS: boolean;
|
TYPEBOT_CHANGE_STATUS: boolean;
|
||||||
CHAMA_AI_ACTION: boolean;
|
|
||||||
ERRORS: boolean;
|
ERRORS: boolean;
|
||||||
ERRORS_WEBHOOK: string;
|
ERRORS_WEBHOOK: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ApiKey = { KEY: string };
|
export type ApiKey = { KEY: string };
|
||||||
export type Jwt = { EXPIRIN_IN: number; SECRET: string };
|
|
||||||
|
|
||||||
export type Auth = {
|
export type Auth = {
|
||||||
API_KEY: ApiKey;
|
API_KEY: ApiKey;
|
||||||
EXPOSE_IN_FETCH_INSTANCES: boolean;
|
EXPOSE_IN_FETCH_INSTANCES: boolean;
|
||||||
JWT: Jwt;
|
|
||||||
TYPE: 'jwt' | 'apikey';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DelInstance = number | boolean;
|
export type DelInstance = number | boolean;
|
||||||
@ -252,7 +247,7 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private loadEnv() {
|
private loadEnv() {
|
||||||
this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess();
|
this.env = this.envProcess();
|
||||||
this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';
|
this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';
|
||||||
if (process.env?.DOCKER_ENV === 'true') {
|
if (process.env?.DOCKER_ENV === 'true') {
|
||||||
this.env.SERVER.TYPE = process.env.SERVER_TYPE as 'http' | 'http';
|
this.env.SERVER.TYPE = process.env.SERVER_TYPE as 'http' | 'http';
|
||||||
@ -260,10 +255,6 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private envYaml(): Env {
|
|
||||||
return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env;
|
|
||||||
}
|
|
||||||
|
|
||||||
private envProcess(): Env {
|
private envProcess(): Env {
|
||||||
return {
|
return {
|
||||||
SERVER: {
|
SERVER: {
|
||||||
@ -310,6 +301,7 @@ export class ConfigService {
|
|||||||
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution',
|
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution',
|
||||||
},
|
},
|
||||||
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
||||||
|
PROVIDER: process.env.DATABASE_PROVIDER || 'mongodb',
|
||||||
SAVE_DATA: {
|
SAVE_DATA: {
|
||||||
INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',
|
INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',
|
||||||
NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',
|
NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',
|
||||||
@ -349,7 +341,6 @@ export class ConfigService {
|
|||||||
GROUP_UPDATE: process.env?.RABBITMQ_EVENTS_GROUPS_UPDATE === 'true',
|
GROUP_UPDATE: process.env?.RABBITMQ_EVENTS_GROUPS_UPDATE === 'true',
|
||||||
GROUP_PARTICIPANTS_UPDATE: process.env?.RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',
|
GROUP_PARTICIPANTS_UPDATE: process.env?.RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',
|
||||||
CALL: process.env?.RABBITMQ_EVENTS_CALL === 'true',
|
CALL: process.env?.RABBITMQ_EVENTS_CALL === 'true',
|
||||||
NEW_JWT_TOKEN: process.env?.RABBITMQ_EVENTS_NEW_JWT_TOKEN === 'true',
|
|
||||||
TYPEBOT_START: process.env?.RABBITMQ_EVENTS_TYPEBOT_START === 'true',
|
TYPEBOT_START: process.env?.RABBITMQ_EVENTS_TYPEBOT_START === 'true',
|
||||||
TYPEBOT_CHANGE_STATUS: process.env?.RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
TYPEBOT_CHANGE_STATUS: process.env?.RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
||||||
},
|
},
|
||||||
@ -423,10 +414,8 @@ export class ConfigService {
|
|||||||
GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true',
|
GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true',
|
||||||
GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',
|
GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',
|
||||||
CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true',
|
CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true',
|
||||||
NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true',
|
|
||||||
TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',
|
TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',
|
||||||
TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
||||||
CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true',
|
|
||||||
ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',
|
ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',
|
||||||
ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',
|
ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',
|
||||||
},
|
},
|
||||||
@ -470,17 +459,10 @@ export class ConfigService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
AUTHENTICATION: {
|
AUTHENTICATION: {
|
||||||
TYPE: process.env.AUTHENTICATION_TYPE as 'apikey',
|
|
||||||
API_KEY: {
|
API_KEY: {
|
||||||
KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',
|
KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',
|
||||||
},
|
},
|
||||||
EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true',
|
EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true',
|
||||||
JWT: {
|
|
||||||
EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN)
|
|
||||||
? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN)
|
|
||||||
: 3600,
|
|
||||||
SECRET: process.env.AUTHENTICATION_JWT_SECRET || 'L=0YWt]b2w[WF>#>:&E`',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
236
src/dev-env.yml
236
src/dev-env.yml
@ -1,236 +0,0 @@
|
|||||||
# ⚠️
|
|
||||||
# ⚠️ ALL SETTINGS DEFINED IN THIS FILE ARE APPLIED TO ALL INSTANCES.
|
|
||||||
# ⚠️
|
|
||||||
|
|
||||||
# ⚠️ RENAME THIS FILE TO env.yml
|
|
||||||
|
|
||||||
# Choose the server type for the application
|
|
||||||
SERVER:
|
|
||||||
TYPE: http # https
|
|
||||||
PORT: 8080 # 443
|
|
||||||
URL: localhost
|
|
||||||
DISABLE_MANAGER: false
|
|
||||||
DISABLE_DOCS: false
|
|
||||||
|
|
||||||
CORS:
|
|
||||||
ORIGIN:
|
|
||||||
- "*"
|
|
||||||
# - yourdomain.com
|
|
||||||
METHODS:
|
|
||||||
- POST
|
|
||||||
- GET
|
|
||||||
- PUT
|
|
||||||
- DELETE
|
|
||||||
CREDENTIALS: true
|
|
||||||
|
|
||||||
# Install ssl certificate and replace string <domain> with domain name
|
|
||||||
# Access: https://certbot.eff.org/instructions?ws=other&os=ubuntufocal
|
|
||||||
SSL_CONF:
|
|
||||||
PRIVKEY: /etc/letsencrypt/live/<domain>/privkey.pem
|
|
||||||
FULLCHAIN: /etc/letsencrypt/live/<domain>/fullchain.pem
|
|
||||||
|
|
||||||
# Determine the logs to be displayed
|
|
||||||
LOG:
|
|
||||||
LEVEL:
|
|
||||||
- ERROR
|
|
||||||
- WARN
|
|
||||||
- DEBUG
|
|
||||||
- INFO
|
|
||||||
- LOG
|
|
||||||
- VERBOSE
|
|
||||||
- DARK
|
|
||||||
- WEBHOOKS
|
|
||||||
COLOR: true
|
|
||||||
BAILEYS: error # fatal | error | warn | info | debug | trace
|
|
||||||
|
|
||||||
# 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 # or false
|
|
||||||
DEL_TEMP_INSTANCES: true # Delete instances with status closed on start
|
|
||||||
|
|
||||||
# Seesion Files Providers
|
|
||||||
# Provider responsible for managing credentials files and WhatsApp sessions.
|
|
||||||
PROVIDER:
|
|
||||||
ENABLED: true
|
|
||||||
HOST: 127.0.0.1
|
|
||||||
PORT: 5656
|
|
||||||
PREFIX: evolution
|
|
||||||
|
|
||||||
# Temporary data storage
|
|
||||||
STORE:
|
|
||||||
MESSAGES: true
|
|
||||||
MESSAGE_UP: true
|
|
||||||
CONTACTS: true
|
|
||||||
CHATS: true
|
|
||||||
|
|
||||||
CLEAN_STORE:
|
|
||||||
CLEANING_INTERVAL: 7200 # 7200 seconds === 2h
|
|
||||||
MESSAGES: true
|
|
||||||
MESSAGE_UP: true
|
|
||||||
CONTACTS: true
|
|
||||||
CHATS: true
|
|
||||||
|
|
||||||
# Permanent data storage
|
|
||||||
DATABASE:
|
|
||||||
ENABLED: false
|
|
||||||
CONNECTION:
|
|
||||||
URI: "mongodb://root:root@localhost:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true"
|
|
||||||
DB_PREFIX_NAME: evolution
|
|
||||||
# Choose the data you want to save in the application's database or store
|
|
||||||
SAVE_DATA:
|
|
||||||
INSTANCE: false
|
|
||||||
NEW_MESSAGE: false
|
|
||||||
MESSAGE_UPDATE: false
|
|
||||||
CONTACTS: false
|
|
||||||
CHATS: false
|
|
||||||
|
|
||||||
RABBITMQ:
|
|
||||||
ENABLED: false
|
|
||||||
URI: "amqp://guest:guest@localhost:5672"
|
|
||||||
EXCHANGE_NAME: evolution_exchange
|
|
||||||
GLOBAL_ENABLED: true
|
|
||||||
EVENTS:
|
|
||||||
APPLICATION_STARTUP: false
|
|
||||||
INSTANCE_CREATE: false
|
|
||||||
INSTANCE_DELETE: false
|
|
||||||
QRCODE_UPDATED: false
|
|
||||||
MESSAGES_SET: false
|
|
||||||
MESSAGES_UPSERT: true
|
|
||||||
MESSAGES_UPDATE: true
|
|
||||||
MESSAGES_DELETE: false
|
|
||||||
SEND_MESSAGE: false
|
|
||||||
CONTACTS_SET: false
|
|
||||||
CONTACTS_UPSERT: false
|
|
||||||
CONTACTS_UPDATE: false
|
|
||||||
PRESENCE_UPDATE: false
|
|
||||||
CHATS_SET: false
|
|
||||||
CHATS_UPSERT: false
|
|
||||||
CHATS_UPDATE: false
|
|
||||||
CHATS_DELETE: false
|
|
||||||
GROUPS_UPSERT: true
|
|
||||||
GROUP_UPDATE: true
|
|
||||||
GROUP_PARTICIPANTS_UPDATE: true
|
|
||||||
CONNECTION_UPDATE: true
|
|
||||||
CALL: false
|
|
||||||
# This events is used with Typebot
|
|
||||||
TYPEBOT_START: false
|
|
||||||
TYPEBOT_CHANGE_STATUS: false
|
|
||||||
|
|
||||||
SQS:
|
|
||||||
ENABLED: true
|
|
||||||
ACCESS_KEY_ID: ""
|
|
||||||
SECRET_ACCESS_KEY: ""
|
|
||||||
ACCOUNT_ID: ""
|
|
||||||
REGION: "us-east-1"
|
|
||||||
|
|
||||||
WEBSOCKET:
|
|
||||||
ENABLED: false
|
|
||||||
GLOBAL_EVENTS: false
|
|
||||||
|
|
||||||
WA_BUSINESS:
|
|
||||||
TOKEN_WEBHOOK: evolution
|
|
||||||
URL: https://graph.facebook.com
|
|
||||||
VERSION: v18.0
|
|
||||||
LANGUAGE: pt_BR
|
|
||||||
|
|
||||||
# Global Webhook Settings
|
|
||||||
# Each instance's Webhook URL and events will be requested at the time it is created
|
|
||||||
WEBHOOK:
|
|
||||||
# Define a global webhook that will listen for enabled events from all instances
|
|
||||||
GLOBAL:
|
|
||||||
URL: <url>
|
|
||||||
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_BY_EVENTS: false
|
|
||||||
# Automatically maps webhook paths
|
|
||||||
# Set the events you want to hear
|
|
||||||
EVENTS:
|
|
||||||
APPLICATION_STARTUP: false
|
|
||||||
QRCODE_UPDATED: true
|
|
||||||
MESSAGES_SET: true
|
|
||||||
MESSAGES_UPSERT: true
|
|
||||||
MESSAGES_UPDATE: true
|
|
||||||
MESSAGES_DELETE: true
|
|
||||||
SEND_MESSAGE: true
|
|
||||||
CONTACTS_SET: true
|
|
||||||
CONTACTS_UPSERT: true
|
|
||||||
CONTACTS_UPDATE: true
|
|
||||||
PRESENCE_UPDATE: true
|
|
||||||
CHATS_SET: true
|
|
||||||
CHATS_UPSERT: true
|
|
||||||
CHATS_UPDATE: true
|
|
||||||
CHATS_DELETE: true
|
|
||||||
GROUPS_UPSERT: true
|
|
||||||
GROUP_UPDATE: true
|
|
||||||
GROUP_PARTICIPANTS_UPDATE: true
|
|
||||||
CONNECTION_UPDATE: true
|
|
||||||
LABELS_EDIT: true
|
|
||||||
LABELS_ASSOCIATION: true
|
|
||||||
CALL: true
|
|
||||||
# This event fires every time a new token is requested via the refresh route
|
|
||||||
NEW_JWT_TOKEN: false
|
|
||||||
# This events is used with Typebot
|
|
||||||
TYPEBOT_START: false
|
|
||||||
TYPEBOT_CHANGE_STATUS: false
|
|
||||||
# This event is used with Chama AI
|
|
||||||
CHAMA_AI_ACTION: false
|
|
||||||
# This event is used to send errors to the webhook
|
|
||||||
ERRORS: false
|
|
||||||
ERRORS_WEBHOOK: <url>
|
|
||||||
|
|
||||||
CONFIG_SESSION_PHONE:
|
|
||||||
# Name that will be displayed on smartphone connection
|
|
||||||
CLIENT: "Evolution API"
|
|
||||||
NAME: Chrome # Chrome | Firefox | Edge | Opera | Safari
|
|
||||||
|
|
||||||
# Set qrcode display limit
|
|
||||||
QRCODE:
|
|
||||||
LIMIT: 30
|
|
||||||
COLOR: "#198754"
|
|
||||||
|
|
||||||
TYPEBOT:
|
|
||||||
API_VERSION: "old" # old | latest
|
|
||||||
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.
|
|
||||||
MESSAGE_DELETE: true # 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.
|
|
||||||
MESSAGE_READ: false # false | true
|
|
||||||
IMPORT:
|
|
||||||
# This db connection is used to import messages from whatsapp to chatwoot database
|
|
||||||
DATABASE:
|
|
||||||
CONNECTION:
|
|
||||||
URI: "postgres://user:password@hostname:port/dbname?sslmode=disable"
|
|
||||||
PLACEHOLDER_MEDIA_MESSAGE: true
|
|
||||||
|
|
||||||
# Cache to optimize application performance
|
|
||||||
CACHE:
|
|
||||||
REDIS:
|
|
||||||
ENABLED: false
|
|
||||||
URI: "redis://localhost:6379"
|
|
||||||
PREFIX_KEY: "evolution"
|
|
||||||
TTL: 604800
|
|
||||||
SAVE_INSTANCES: false
|
|
||||||
LOCAL:
|
|
||||||
ENABLED: false
|
|
||||||
TTL: 86400
|
|
||||||
|
|
||||||
# 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
|
|
||||||
AUTHENTICATION:
|
|
||||||
TYPE: apikey # jwt or apikey
|
|
||||||
# Define a global apikey to access all instances
|
|
||||||
API_KEY:
|
|
||||||
# OBS: This key must be inserted in the request header to create an instance.
|
|
||||||
KEY: B6D711FCDE4D4FD5936544120E713976
|
|
||||||
# Expose the api key on return from fetch instances
|
|
||||||
EXPOSE_IN_FETCH_INSTANCES: true
|
|
||||||
# Set the secret key to encrypt and decrypt your token and its expiration time.
|
|
||||||
JWT:
|
|
||||||
EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires
|
|
||||||
SECRET: L=0YWt]b2w[WF>#>:&E`
|
|
||||||
|
|
||||||
LANGUAGE: "pt-BR" # pt-BR, en
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Router } from 'express';
|
|
||||||
import { join } from 'path';
|
|
||||||
import swaggerUi from 'swagger-ui-express';
|
|
||||||
import YAML from 'yamljs';
|
|
||||||
|
|
||||||
const document = YAML.load(join(process.cwd(), 'src', 'docs', 'swagger.yaml'));
|
|
||||||
|
|
||||||
const router = Router();
|
|
||||||
|
|
||||||
export const swaggerRouter = router.use('/docs', swaggerUi.serve).get(
|
|
||||||
'/docs',
|
|
||||||
swaggerUi.setup(document, {
|
|
||||||
customCssUrl: '/css/dark-theme-swagger.css',
|
|
||||||
customSiteTitle: 'Evolution API',
|
|
||||||
customfavIcon: '/images/logo.svg',
|
|
||||||
}),
|
|
||||||
);
|
|
File diff suppressed because it is too large
Load Diff
@ -6,8 +6,8 @@ import { Logger } from '../config/logger.config';
|
|||||||
const logger = new Logger('MongoDB');
|
const logger = new Logger('MongoDB');
|
||||||
|
|
||||||
const db = configService.get<Database>('DATABASE');
|
const db = configService.get<Database>('DATABASE');
|
||||||
export const dbserver = (() => {
|
export const mongodbServer = (() => {
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED && db.PROVIDER === 'mongodb') {
|
||||||
logger.verbose('connecting');
|
logger.verbose('connecting');
|
||||||
const dbs = mongoose.createConnection(db.CONNECTION.URI, {
|
const dbs = mongoose.createConnection(db.CONNECTION.URI, {
|
||||||
dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api',
|
dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api',
|
||||||
@ -17,7 +17,7 @@ export const dbserver = (() => {
|
|||||||
|
|
||||||
process.on('beforeExit', () => {
|
process.on('beforeExit', () => {
|
||||||
logger.verbose('instance destroyed');
|
logger.verbose('instance destroyed');
|
||||||
dbserver.destroy(true, (error) => logger.error(error));
|
mongodbServer.destroy(true, (error) => logger.error(error));
|
||||||
});
|
});
|
||||||
|
|
||||||
return dbs;
|
return dbs;
|
23
src/libs/prisma.connect.ts
Normal file
23
src/libs/prisma.connect.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
|
import { configService, Database } from '../config/env.config';
|
||||||
|
import { Logger } from '../config/logger.config';
|
||||||
|
|
||||||
|
const logger = new Logger('MongoDB');
|
||||||
|
|
||||||
|
const db = configService.get<Database>('DATABASE');
|
||||||
|
export const prismaServer = (() => {
|
||||||
|
if (db.ENABLED && db.PROVIDER !== 'mongodb') {
|
||||||
|
logger.verbose('connecting');
|
||||||
|
const db = new PrismaClient();
|
||||||
|
|
||||||
|
logger.verbose('connected in ' + db.$connect);
|
||||||
|
|
||||||
|
process.on('beforeExit', () => {
|
||||||
|
logger.verbose('instance destroyed');
|
||||||
|
db.$disconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
})();
|
@ -16,7 +16,6 @@ import { Auth, configService, Cors, HttpServer, Rabbitmq, Sqs, Webhook } from '.
|
|||||||
import { onUnexpectedError } from './config/error.config';
|
import { onUnexpectedError } from './config/error.config';
|
||||||
import { Logger } from './config/logger.config';
|
import { Logger } from './config/logger.config';
|
||||||
import { ROOT_DIR } from './config/path.config';
|
import { ROOT_DIR } from './config/path.config';
|
||||||
import { swaggerRouter } from './docs/swagger.conf';
|
|
||||||
import { ServerUP } from './utils/server-up';
|
import { ServerUP } from './utils/server-up';
|
||||||
|
|
||||||
function initWA() {
|
function initWA() {
|
||||||
@ -59,8 +58,6 @@ async function bootstrap() {
|
|||||||
|
|
||||||
app.use('/', router);
|
app.use('/', router);
|
||||||
|
|
||||||
if (!configService.get('SERVER').DISABLE_DOCS) app.use(swaggerRouter);
|
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -9,14 +9,14 @@ import {
|
|||||||
|
|
||||||
import { configService, Database } from '../config/env.config';
|
import { configService, Database } from '../config/env.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
import { dbserver } from '../libs/db.connect';
|
import { mongodbServer } from '../libs/mongodb.connect';
|
||||||
|
|
||||||
export async function useMultiFileAuthStateDb(
|
export async function useMultiFileAuthStateMongoDb(
|
||||||
coll: string,
|
coll: string,
|
||||||
): Promise<{ state: AuthenticationState; saveCreds: () => Promise<void> }> {
|
): Promise<{ state: AuthenticationState; saveCreds: () => Promise<void> }> {
|
||||||
const logger = new Logger(useMultiFileAuthStateDb.name);
|
const logger = new Logger(useMultiFileAuthStateMongoDb.name);
|
||||||
|
|
||||||
const client = dbserver.getClient();
|
const client = mongodbServer.getClient();
|
||||||
|
|
||||||
const collection = client
|
const collection = client
|
||||||
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
158
src/utils/use-multi-file-auth-state-prisma.ts
Normal file
158
src/utils/use-multi-file-auth-state-prisma.ts
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
import { BufferJSON, initAuthCreds, WAProto as proto } from '@whiskeysockets/baileys';
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
const fixFileName = (file) => {
|
||||||
|
if (!file) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const replacedSlash = file.replace(/\//g, '__');
|
||||||
|
const replacedColon = replacedSlash.replace(/:/g, '-');
|
||||||
|
return replacedColon;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function keyExists(sessionId) {
|
||||||
|
try {
|
||||||
|
const key = await prisma.session.findUnique({ where: { sessionId: sessionId } });
|
||||||
|
return !!key;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`${error}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveKey(sessionId, keyJson) {
|
||||||
|
const jaExiste = await keyExists(sessionId);
|
||||||
|
try {
|
||||||
|
if (!jaExiste)
|
||||||
|
return await prisma.session.create({ data: { sessionId: sessionId, creds: JSON.stringify(keyJson) } as any });
|
||||||
|
await prisma.session.update({ where: { sessionId: sessionId }, data: { creds: JSON.stringify(keyJson) } });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`${error}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAuthKey(sessionId) {
|
||||||
|
try {
|
||||||
|
const registro = await keyExists(sessionId);
|
||||||
|
if (!registro) return null;
|
||||||
|
const auth = await prisma.session.findUnique({ where: { sessionId: sessionId } });
|
||||||
|
return JSON.parse(auth?.creds);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`${error}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteAuthKey(sessionId) {
|
||||||
|
try {
|
||||||
|
const registro = await keyExists(sessionId);
|
||||||
|
if (!registro) return;
|
||||||
|
await prisma.session.delete({ where: { sessionId: sessionId } });
|
||||||
|
} catch (error) {
|
||||||
|
console.log('2', `${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fileExists(file) {
|
||||||
|
try {
|
||||||
|
const stat = await fs.stat(file);
|
||||||
|
if (stat.isFile()) return true;
|
||||||
|
} catch (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function useMultiFileAuthStatePrisma(sessionId) {
|
||||||
|
const localFolder = path.join(process.cwd(), 'sessions', sessionId);
|
||||||
|
const localFile = (key) => path.join(localFolder, fixFileName(key) + '.json');
|
||||||
|
await fs.mkdir(localFolder, { recursive: true });
|
||||||
|
|
||||||
|
async function writeData(data, key) {
|
||||||
|
const dataString = JSON.stringify(data, BufferJSON.replacer);
|
||||||
|
|
||||||
|
if (key != 'creds') {
|
||||||
|
await fs.writeFile(localFile(key), dataString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await saveKey(sessionId, dataString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readData(key) {
|
||||||
|
try {
|
||||||
|
let rawData;
|
||||||
|
|
||||||
|
if (key != 'creds') {
|
||||||
|
if (!(await fileExists(localFile(key)))) return null;
|
||||||
|
rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' });
|
||||||
|
} else {
|
||||||
|
rawData = await getAuthKey(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedData = JSON.parse(rawData, BufferJSON.reviver);
|
||||||
|
return parsedData;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeData(key) {
|
||||||
|
try {
|
||||||
|
if (key != 'creds') {
|
||||||
|
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: () => {
|
||||||
|
return writeData(creds, 'creds');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -2,7 +2,6 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
|
|||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
// Integrations Schema
|
// Integrations Schema
|
||||||
export * from '../api/integrations/chamaai/validate/chamaai.schema';
|
|
||||||
export * from '../api/integrations/chatwoot/validate/chatwoot.schema';
|
export * from '../api/integrations/chatwoot/validate/chatwoot.schema';
|
||||||
export * from '../api/integrations/rabbitmq/validate/rabbitmq.schema';
|
export * from '../api/integrations/rabbitmq/validate/rabbitmq.schema';
|
||||||
export * from '../api/integrations/sqs/validate/sqs.schema';
|
export * from '../api/integrations/sqs/validate/sqs.schema';
|
||||||
@ -63,10 +62,8 @@ export const instanceNameSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -979,10 +976,8 @@ export const webhookSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1040,10 +1035,8 @@ export const websocketSchema: JSONSchema7 = {
|
|||||||
'LABELS_EDIT',
|
'LABELS_EDIT',
|
||||||
'LABELS_ASSOCIATION',
|
'LABELS_ASSOCIATION',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user