first commit

This commit is contained in:
Pedro Henrique 2025-01-18 18:03:50 -03:00
parent 1665654676
commit 908d5be53f
10 changed files with 320 additions and 11 deletions

BIN
.DS_Store vendored

Binary file not shown.

281
.env Normal file
View File

@ -0,0 +1,281 @@
SERVER_TYPE=http
SERVER_PORT=8080
# Server URL - Set your application url
SERVER_URL=http://host.docker.internal:8080
SENTRY_DSN=
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
CORS_ORIGIN=*
CORS_METHODS=GET,POST,PUT,DELETE
CORS_CREDENTIALS=true
# Determine the logs to be displayed
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS,WEBSOCKET
LOG_COLOR=true
# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace"
LOG_BAILEYS=error
# Set the maximum number of listeners that can be registered for an event
EVENT_EMITTER_MAX_LISTENERS=50
# Determine how long the instance should be deleted from memory in case of no connection.
# Default time: 5 minutes
# If you don't even want an expiration, enter the value false
DEL_INSTANCE=false
# Provider: postgresql | mysql
DATABASE_PROVIDER=postgresql
DATABASE_CONNECTION_URI='postgresql://postgres:kajsdnfjknsadkfjnkasd154asd@postgres:5432/evolution?schema=public'
# DATABASE_CONNECTION_URI='postgresql://postgres:kajsdnfjknsadkfjnkasd154asd@localhost:5433/evolution?schema=public'
# Client name for the database connection
# It is used to separate an API installation from another that uses the same database.
DATABASE_CONNECTION_CLIENT_NAME=evolution_exchange
# Choose the data you want to save in the application's database
DATABASE_SAVE_DATA_INSTANCE=true
DATABASE_SAVE_DATA_NEW_MESSAGE=true
DATABASE_SAVE_MESSAGE_UPDATE=true
DATABASE_SAVE_DATA_CONTACTS=true
DATABASE_SAVE_DATA_CHATS=true
DATABASE_SAVE_DATA_LABELS=true
DATABASE_SAVE_DATA_HISTORIC=true
DATABASE_SAVE_IS_ON_WHATSAPP=true
DATABASE_SAVE_IS_ON_WHATSAPP_DAYS=7
DATABASE_DELETE_MESSAGE=true
# RabbitMQ - Environment variables
RABBITMQ_ENABLED=false
RABBITMQ_URI=amqp://localhost
RABBITMQ_EXCHANGE_NAME=evolution
# Global events - By enabling this variable, events from all instances are sent in the same event queue.
RABBITMQ_GLOBAL_ENABLED=false
# Choose the events you want to send to RabbitMQ
RABBITMQ_EVENTS_APPLICATION_STARTUP=false
RABBITMQ_EVENTS_INSTANCE_CREATE=false
RABBITMQ_EVENTS_INSTANCE_DELETE=false
RABBITMQ_EVENTS_QRCODE_UPDATED=false
RABBITMQ_EVENTS_MESSAGES_SET=false
RABBITMQ_EVENTS_MESSAGES_UPSERT=false
RABBITMQ_EVENTS_MESSAGES_EDITED=false
RABBITMQ_EVENTS_MESSAGES_UPDATE=false
RABBITMQ_EVENTS_MESSAGES_DELETE=false
RABBITMQ_EVENTS_SEND_MESSAGE=false
RABBITMQ_EVENTS_CONTACTS_SET=false
RABBITMQ_EVENTS_CONTACTS_UPSERT=false
RABBITMQ_EVENTS_CONTACTS_UPDATE=false
RABBITMQ_EVENTS_PRESENCE_UPDATE=false
RABBITMQ_EVENTS_CHATS_SET=false
RABBITMQ_EVENTS_CHATS_UPSERT=false
RABBITMQ_EVENTS_CHATS_UPDATE=false
RABBITMQ_EVENTS_CHATS_DELETE=false
RABBITMQ_EVENTS_GROUPS_UPSERT=false
RABBITMQ_EVENTS_GROUP_UPDATE=false
RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=false
RABBITMQ_EVENTS_CONNECTION_UPDATE=false
RABBITMQ_EVENTS_REMOVE_INSTANCE=false
RABBITMQ_EVENTS_LOGOUT_INSTANCE=false
RABBITMQ_EVENTS_CALL=false
RABBITMQ_EVENTS_TYPEBOT_START=false
RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false
# SQS - Environment variables
SQS_ENABLED=false
SQS_ACCESS_KEY_ID=
SQS_SECRET_ACCESS_KEY=
SQS_ACCOUNT_ID=
SQS_REGION=
# Websocket - Environment variables
WEBSOCKET_ENABLED=false
WEBSOCKET_GLOBAL_EVENTS=false
# Pusher - Environment variables
PUSHER_ENABLED=false
PUSHER_GLOBAL_ENABLED=false
PUSHER_GLOBAL_APP_ID=
PUSHER_GLOBAL_KEY=
PUSHER_GLOBAL_SECRET=
PUSHER_GLOBAL_CLUSTER=
PUSHER_GLOBAL_USE_TLS=true
# Choose the events you want to send to Pusher
PUSHER_EVENTS_APPLICATION_STARTUP=true
PUSHER_EVENTS_QRCODE_UPDATED=true
PUSHER_EVENTS_MESSAGES_SET=true
PUSHER_EVENTS_MESSAGES_UPSERT=true
PUSHER_EVENTS_MESSAGES_EDITED=true
PUSHER_EVENTS_MESSAGES_UPDATE=true
PUSHER_EVENTS_MESSAGES_DELETE=true
PUSHER_EVENTS_SEND_MESSAGE=true
PUSHER_EVENTS_CONTACTS_SET=true
PUSHER_EVENTS_CONTACTS_UPSERT=true
PUSHER_EVENTS_CONTACTS_UPDATE=true
PUSHER_EVENTS_PRESENCE_UPDATE=true
PUSHER_EVENTS_CHATS_SET=true
PUSHER_EVENTS_CHATS_UPSERT=true
PUSHER_EVENTS_CHATS_UPDATE=true
PUSHER_EVENTS_CHATS_DELETE=true
PUSHER_EVENTS_GROUPS_UPSERT=true
PUSHER_EVENTS_GROUPS_UPDATE=true
PUSHER_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
PUSHER_EVENTS_CONNECTION_UPDATE=true
PUSHER_EVENTS_LABELS_EDIT=true
PUSHER_EVENTS_LABELS_ASSOCIATION=true
PUSHER_EVENTS_CALL=true
PUSHER_EVENTS_TYPEBOT_START=false
PUSHER_EVENTS_TYPEBOT_CHANGE_STATUS=false
# WhatsApp Business API - Environment variables
# Token used to validate the webhook on the Facebook APP
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com
WA_BUSINESS_VERSION=v20.0
WA_BUSINESS_LANGUAGE=en_US
# Global Webhook Settings
# Each instance's Webhook URL and events will be requested at the time it is created
WEBHOOK_GLOBAL_ENABLED=false
# Define a global webhook that will listen for enabled events from all instances
WEBHOOK_GLOBAL_URL=''
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
# Set the events you want to hear
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=false
WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_EDITED=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true
WEBHOOK_EVENTS_CONTACTS_SET=true
WEBHOOK_EVENTS_CONTACTS_UPSERT=true
WEBHOOK_EVENTS_CONTACTS_UPDATE=true
WEBHOOK_EVENTS_PRESENCE_UPDATE=true
WEBHOOK_EVENTS_CHATS_SET=true
WEBHOOK_EVENTS_CHATS_UPSERT=true
WEBHOOK_EVENTS_CHATS_UPDATE=true
WEBHOOK_EVENTS_CHATS_DELETE=true
WEBHOOK_EVENTS_GROUPS_UPSERT=true
WEBHOOK_EVENTS_GROUPS_UPDATE=true
WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true
WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_REMOVE_INSTANCE=false
WEBHOOK_EVENTS_LOGOUT_INSTANCE=false
WEBHOOK_EVENTS_LABELS_EDIT=true
WEBHOOK_EVENTS_LABELS_ASSOCIATION=true
WEBHOOK_EVENTS_CALL=true
# This events is used with Typebot
WEBHOOK_EVENTS_TYPEBOT_START=false
WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
# This event is used to send errors
WEBHOOK_EVENTS_ERRORS=false
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
# Name that will be displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT=Evolution
# Browser Name = Chrome | Firefox | Edge | Opera | Safari
CONFIG_SESSION_PHONE_NAME=Chrome
# Whatsapp Web version for baileys channel
# https://web.whatsapp.com/check-update?version=0&platform=web
CONFIG_SESSION_PHONE_VERSION=2.3000.1015901307
# Set qrcode display limit
QRCODE_LIMIT=30
# Color of the QRCode on base64
QRCODE_COLOR='#175197'
# Typebot - Environment variables
TYPEBOT_ENABLED=false
# old | latest
TYPEBOT_API_VERSION=latest
# Chatwoot - Environment variables
CHATWOOT_ENABLED=true
# If you leave this option as false, when deleting the message for everyone on WhatsApp, it will not be deleted on Chatwoot.
CHATWOOT_MESSAGE_READ=true
# If you leave this option as true, when sending a message in Chatwoot, the client's last message will be marked as read on WhatsApp.
CHATWOOT_MESSAGE_DELETE=true
# If you leave this option as true, a contact will be created on Chatwoot to provide the QR Code and update messages about the instance.
CHATWOOT_BOT_CONTACT=true
# This db connection is used to import messages from whatsapp to chatwoot database
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://postgres:postgres@host.docker.internal:5434/chatwoot?sslmode=disable
# CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://postgres:postgres@localhost:5434/chatwoot?sslmode=disable
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true
# OpenAI - Environment variables
OPENAI_ENABLED=false
# Dify - Environment variables
DIFY_ENABLED=false
# Cache - Environment variables
# Redis Cache enabled
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://redis:6379/6
CACHE_REDIS_TTL=604800
# Prefix serves to differentiate data from one installation to another that are using the same redis
CACHE_REDIS_PREFIX_KEY=evolution
# Enabling this variable will save the connection information in Redis and not in the database.
CACHE_REDIS_SAVE_INSTANCES=false
# Local Cache enabled
CACHE_LOCAL_ENABLED=false
# Amazon S3 - Environment variables
S3_ENABLED=false
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_BUCKET=evolution
S3_PORT=443
S3_ENDPOINT=s3.domain.com
S3_REGION=eu-west-3
S3_USE_SSL=true
# AMAZON S3 - Environment variables
# S3_ENABLED=true
# S3_BUCKET=bucket_name
# S3_ACCESS_KEY=access_key_id
# S3_SECRET_KEY=secret_access_key
# S3_ENDPOINT=s3.amazonaws.com # region: s3.eu-west-3.amazonaws.com
# S3_REGION=eu-west-3
# MINIO Use SSL - Environment variables
# S3_ENABLED=true
# S3_ACCESS_KEY=access_key_id
# S3_SECRET_KEY=secret_access_key
# S3_BUCKET=bucket_name
# S3_PORT=443
# S3_ENDPOINT=s3.domain.com
# S3_USE_SSL=true
# S3_REGION=eu-south
# Evolution Audio Converter - Environment variables - https://github.com/EvolutionAPI/evolution-audio-converter
# API_AUDIO_CONVERTER=http://localhost:4040/process-audio
# API_AUDIO_CONVERTER_KEY=429683C4C977415CAAFCCE10F7D57E11
# Define a global apikey to access all instances.
# OBS: This key must be inserted in the request header to create an instance.
AUTHENTICATION_TYPE=apikey
AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11
# If you leave this option as true, the instances will be exposed in the fetch instances endpoint.
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
LANGUAGE=en
# Define a global proxy to be used if the instance does not have one
# PROXY_HOST=
# PROXY_PORT=80
# PROXY_PROTOCOL=http
# PROXY_USERNAME=
# PROXY_PASSWORD=
STORE_CHATS=true
CLEAN_STORE_CLEANING_INTERVAL=7200 # seconds === 2h
CLEAN_STORE_MESSAGES=true
CLEAN_STORE_MESSAGE_UP=true
CLEAN_STORE_CONTACTS=true
CLEAN_STORE_CHATS=true
QRCODE_LIMIT=30

1
.gitignore vendored
View File

@ -38,7 +38,6 @@ lerna-debug.log*
/test/
/src/env.yml
/store
*.env
/temp/*

View File

@ -7,7 +7,6 @@ if [ "$DOCKER_ENV" != "true" ]; then
fi
if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" ]]; then
export DATABASE_URL
echo "Generating database for $DATABASE_PROVIDER"
echo "Database URL: $DATABASE_URL"
npm run db:generate

View File

@ -1,7 +1,7 @@
FROM node:20-alpine AS builder
RUN apk update && \
apk add git ffmpeg wget curl bash
apk add git ffmpeg wget curl bash openssl
LABEL version="2.2.0" description="Api to control whatsapp features through http requests."
LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes"
@ -23,6 +23,7 @@ COPY ./tsup.config.ts ./
COPY ./Docker ./Docker
RUN chmod +x ./Docker/scripts/* && dos2unix ./Docker/scripts/*
RUN ./Docker/scripts/generate_database.sh
@ -32,7 +33,7 @@ RUN npm run build
FROM node:20-alpine AS final
RUN apk update && \
apk add tzdata ffmpeg bash
apk add tzdata ffmpeg bash openssl
ENV TZ=America/Sao_Paulo

View File

@ -2,6 +2,7 @@ services:
api:
container_name: evolution_api
image: atendai/evolution-api:homolog
build: .
restart: always
depends_on:
- redis
@ -27,19 +28,19 @@ services:
volumes:
- evolution_redis:/data
ports:
- 6379:6379
- 6380:6379
postgres:
container_name: postgres
image: postgres:15
networks:
- evolution-net
command: ["postgres", "-c", "max_connections=1000"]
command: [ "postgres", "-c", "max_connections=1000" ]
restart: always
ports:
- 5432:5432
- 5433:5432
environment:
- POSTGRES_PASSWORD=PASSWORD
- POSTGRES_PASSWORD=kajsdnfjknsadkfjnkasd154asd
volumes:
- postgres_data:/var/lib/postgresql/data
expose:

View File

@ -55,7 +55,7 @@
"@sentry/node": "^8.28.0",
"amqplib": "^0.10.3",
"axios": "^1.6.5",
"baileys": "github:EvolutionAPI/Baileys",
"baileys": "^6.7.9",
"class-validator": "^0.14.1",
"compression": "^1.7.4",
"cors": "^2.8.5",

View File

@ -125,6 +125,7 @@ model Chat {
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
unreadMessages Int @default(0)
@@index([instanceId])
@@index([remoteJid])
}
@ -168,6 +169,7 @@ model Message {
sessionId String?
session IntegrationSession? @relation(fields: [sessionId], references: [id])
@@index([instanceId])
}
@ -183,6 +185,7 @@ model MessageUpdate {
messageId String
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
@@index([instanceId])
@@index([messageId])
}
@ -199,6 +202,7 @@ model Webhook {
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
@@index([instanceId])
}
@ -268,6 +272,7 @@ model Setting {
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
@@index([instanceId])
}

View File

@ -1855,8 +1855,8 @@ export class BaileysStartupService extends ChannelStartupService {
const jid = this.createJid(number);
try {
const call = await this.client.offerCall(jid, isVideo);
setTimeout(() => this.client.terminateCall(call.id, call.to), callDuration * 1000);
const call = await this.client['offerCall'](jid, isVideo);
setTimeout(() => this.client['terminateCall'](call.id, call.to), callDuration * 1000);
return call;
} catch (error) {

View File

@ -13,12 +13,35 @@ import compression from 'compression';
import cors from 'cors';
import express, { json, NextFunction, Request, Response, urlencoded } from 'express';
import { join } from 'path';
import { Client } from 'pg';
function initWA() {
waMonitor.loadInstance();
}
async function bootstrap() {
const client = new Client({
connectionString: process.env.CHATWOOT_IMPORT_DATABASE_CONNECTION_URI,
});
console.log(`Connecting to the database ${process.env.CHATWOOT_IMPORT_DATABASE_CONNECTION_URI}...`);
await client
.connect()
.then(() => {
console.log('Connected to the database successfully');
return client.query('SELECT 1'); // Simple query to check the connection
})
.then(() => {
console.log('Ping successful');
})
.catch((err) => {
console.error('Error connecting to the database:', err.stack);
})
.finally(() => {
client.end(); // Close the connection
});
const logger = new Logger('SERVER');
const app = express();
const dsn = process.env.SENTRY_DSN;