{"version":3,"sources":["../../../../../../src/config/env.config.ts","../../../../../../src/config/logger.config.ts","../../../../../../src/api/integrations/chatbot/chatwoot/libs/postgres.client.ts","../../../../../../src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts","../../../../../../src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts","../../../../../../src/utils/i18n.ts","../../../../../../src/utils/sendTelemetry.ts"],"sourcesContent":["import { isBooleanString } from 'class-validator';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\nexport type HttpServer = {\n  NAME: string;\n  TYPE: 'http' | 'https';\n  PORT: number;\n  URL: string;\n  DISABLE_DOCS: boolean;\n  DISABLE_MANAGER: boolean;\n};\n\nexport type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE';\nexport type Cors = {\n  ORIGIN: string[];\n  METHODS: HttpMethods[];\n  CREDENTIALS: boolean;\n};\n\nexport type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\nexport type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS' | 'WEBSOCKET';\n\nexport type Log = {\n  LEVEL: LogLevel[];\n  COLOR: boolean;\n  BAILEYS: LogBaileys;\n};\n\nexport type ProviderSession = {\n  ENABLED: boolean;\n  HOST: string;\n  PORT: string;\n  PREFIX: string;\n};\n\nexport type SaveData = {\n  INSTANCE: boolean;\n  HISTORIC: boolean;\n  NEW_MESSAGE: boolean;\n  MESSAGE_UPDATE: boolean;\n  CONTACTS: boolean;\n  CHATS: boolean;\n  LABELS: boolean;\n  IS_ON_WHATSAPP: boolean;\n  IS_ON_WHATSAPP_DAYS: number;\n};\n\nexport type DBConnection = {\n  URI: string;\n  CLIENT_NAME: string;\n};\nexport type Database = {\n  CONNECTION: DBConnection;\n  PROVIDER: string;\n  SAVE_DATA: SaveData;\n  DELETE_DATA: DeleteData;\n};\n\nexport type DeleteData = {\n  LOGICAL_MESSAGE_DELETE: boolean;\n};\nexport type EventsRabbitmq = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n};\n\nexport type Rabbitmq = {\n  ENABLED: boolean;\n  URI: string;\n  FRAME_MAX: number;\n  EXCHANGE_NAME: string;\n  GLOBAL_ENABLED: boolean;\n  EVENTS: EventsRabbitmq;\n  PREFIX_KEY?: string;\n};\n\nexport type Nats = {\n  ENABLED: boolean;\n  URI: string;\n  EXCHANGE_NAME: string;\n  GLOBAL_ENABLED: boolean;\n  EVENTS: EventsRabbitmq;\n  PREFIX_KEY?: string;\n};\n\nexport type Sqs = {\n  ENABLED: boolean;\n  GLOBAL_ENABLED: boolean;\n  GLOBAL_FORCE_SINGLE_QUEUE: boolean;\n  GLOBAL_PREFIX_NAME: string;\n  ACCESS_KEY_ID: string;\n  SECRET_ACCESS_KEY: string;\n  ACCOUNT_ID: string;\n  REGION: string;\n  MAX_PAYLOAD_SIZE: number;\n  EVENTS: {\n    APPLICATION_STARTUP: boolean;\n    CALL: boolean;\n    CHATS_DELETE: boolean;\n    CHATS_SET: boolean;\n    CHATS_UPDATE: boolean;\n    CHATS_UPSERT: boolean;\n    CONNECTION_UPDATE: boolean;\n    CONTACTS_SET: boolean;\n    CONTACTS_UPDATE: boolean;\n    CONTACTS_UPSERT: boolean;\n    GROUP_PARTICIPANTS_UPDATE: boolean;\n    GROUPS_UPDATE: boolean;\n    GROUPS_UPSERT: boolean;\n    LABELS_ASSOCIATION: boolean;\n    LABELS_EDIT: boolean;\n    LOGOUT_INSTANCE: boolean;\n    MESSAGES_DELETE: boolean;\n    MESSAGES_EDITED: boolean;\n    MESSAGES_SET: boolean;\n    MESSAGES_UPDATE: boolean;\n    MESSAGES_UPSERT: boolean;\n    PRESENCE_UPDATE: boolean;\n    QRCODE_UPDATED: boolean;\n    REMOVE_INSTANCE: boolean;\n    SEND_MESSAGE: boolean;\n    TYPEBOT_CHANGE_STATUS: boolean;\n    TYPEBOT_START: boolean;\n  };\n};\n\nexport type Kafka = {\n  ENABLED: boolean;\n  CLIENT_ID: string;\n  BROKERS: string[];\n  CONNECTION_TIMEOUT: number;\n  REQUEST_TIMEOUT: number;\n  GLOBAL_ENABLED: boolean;\n  CONSUMER_GROUP_ID: string;\n  TOPIC_PREFIX: string;\n  NUM_PARTITIONS: number;\n  REPLICATION_FACTOR: number;\n  AUTO_CREATE_TOPICS: boolean;\n  EVENTS: EventsRabbitmq;\n  SASL?: {\n    ENABLED: boolean;\n    MECHANISM: string;\n    USERNAME: string;\n    PASSWORD: string;\n  };\n  SSL?: {\n    ENABLED: boolean;\n    REJECT_UNAUTHORIZED: boolean;\n    CA?: string;\n    KEY?: string;\n    CERT?: string;\n  };\n};\n\nexport type Websocket = {\n  ENABLED: boolean;\n  GLOBAL_EVENTS: boolean;\n  ALLOWED_HOSTS?: string;\n};\n\nexport type WaBusiness = {\n  TOKEN_WEBHOOK: string;\n  URL: string;\n  VERSION: string;\n  LANGUAGE: string;\n};\n\nexport type EventsWebhook = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n  ERRORS: boolean;\n  ERRORS_WEBHOOK: string;\n};\n\nexport type EventsPusher = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n};\n\nexport type ApiKey = { KEY: string };\n\nexport type Auth = {\n  API_KEY: ApiKey;\n  EXPOSE_IN_FETCH_INSTANCES: boolean;\n};\n\nexport type DelInstance = number | boolean;\n\nexport type Language = string | 'en';\n\nexport type GlobalWebhook = {\n  URL: string;\n  ENABLED: boolean;\n  WEBHOOK_BY_EVENTS: boolean;\n};\n\nexport type GlobalPusher = {\n  ENABLED: boolean;\n  APP_ID: string;\n  KEY: string;\n  SECRET: string;\n  CLUSTER: string;\n  USE_TLS: boolean;\n};\n\nexport type CacheConfRedis = {\n  ENABLED: boolean;\n  URI: string;\n  PREFIX_KEY: string;\n  TTL: number;\n  SAVE_INSTANCES: boolean;\n};\nexport type CacheConfLocal = {\n  ENABLED: boolean;\n  TTL: number;\n};\nexport type SslConf = { PRIVKEY: string; FULLCHAIN: string };\nexport type Webhook = {\n  GLOBAL?: GlobalWebhook;\n  EVENTS: EventsWebhook;\n  REQUEST?: {\n    TIMEOUT_MS?: number;\n  };\n  RETRY?: {\n    MAX_ATTEMPTS?: number;\n    INITIAL_DELAY_SECONDS?: number;\n    USE_EXPONENTIAL_BACKOFF?: boolean;\n    MAX_DELAY_SECONDS?: number;\n    JITTER_FACTOR?: number;\n    NON_RETRYABLE_STATUS_CODES?: number[];\n  };\n};\nexport type Pusher = { ENABLED: boolean; GLOBAL?: GlobalPusher; EVENTS: EventsPusher };\nexport type ConfigSessionPhone = { CLIENT: string; NAME: string };\nexport type QrCode = { LIMIT: number; COLOR: string };\nexport type Typebot = { ENABLED: boolean; API_VERSION: string; SEND_MEDIA_BASE64: boolean };\nexport type Chatwoot = {\n  ENABLED: boolean;\n  MESSAGE_DELETE: boolean;\n  MESSAGE_READ: boolean;\n  BOT_CONTACT: boolean;\n  IMPORT: {\n    DATABASE: {\n      CONNECTION: {\n        URI: string;\n      };\n    };\n    PLACEHOLDER_MEDIA_MESSAGE: boolean;\n  };\n};\nexport type Openai = { ENABLED: boolean; API_KEY_GLOBAL?: string };\nexport type Dify = { ENABLED: boolean };\nexport type N8n = { ENABLED: boolean };\nexport type Evoai = { ENABLED: boolean };\nexport type Flowise = { ENABLED: boolean };\n\nexport type S3 = {\n  ACCESS_KEY: string;\n  SECRET_KEY: string;\n  ENDPOINT: string;\n  BUCKET_NAME: string;\n  ENABLE: boolean;\n  PORT?: number;\n  USE_SSL?: boolean;\n  REGION?: string;\n  SKIP_POLICY?: boolean;\n  SAVE_VIDEO?: boolean;\n};\n\nexport type CacheConf = { REDIS: CacheConfRedis; LOCAL: CacheConfLocal };\nexport type Metrics = {\n  ENABLED: boolean;\n  AUTH_REQUIRED: boolean;\n  USER?: string;\n  PASSWORD?: string;\n  ALLOWED_IPS?: string;\n};\n\nexport type Telemetry = {\n  ENABLED: boolean;\n  URL?: string;\n};\n\nexport type Proxy = {\n  HOST?: string;\n  PORT?: string;\n  PROTOCOL?: string;\n  USERNAME?: string;\n  PASSWORD?: string;\n};\n\nexport type AudioConverter = {\n  API_URL?: string;\n  API_KEY?: string;\n};\n\nexport type Facebook = {\n  APP_ID?: string;\n  CONFIG_ID?: string;\n  USER_TOKEN?: string;\n};\n\nexport type Sentry = {\n  DSN?: string;\n};\n\nexport type EventEmitter = {\n  MAX_LISTENERS: number;\n};\n\nexport type Production = boolean;\n\nexport interface Env {\n  SERVER: HttpServer;\n  CORS: Cors;\n  SSL_CONF: SslConf;\n  PROVIDER: ProviderSession;\n  DATABASE: Database;\n  RABBITMQ: Rabbitmq;\n  NATS: Nats;\n  SQS: Sqs;\n  KAFKA: Kafka;\n  WEBSOCKET: Websocket;\n  WA_BUSINESS: WaBusiness;\n  LOG: Log;\n  DEL_INSTANCE: DelInstance;\n  DEL_TEMP_INSTANCES: boolean;\n  LANGUAGE: Language;\n  WEBHOOK: Webhook;\n  PUSHER: Pusher;\n  CONFIG_SESSION_PHONE: ConfigSessionPhone;\n  QRCODE: QrCode;\n  TYPEBOT: Typebot;\n  CHATWOOT: Chatwoot;\n  OPENAI: Openai;\n  DIFY: Dify;\n  N8N: N8n;\n  EVOAI: Evoai;\n  FLOWISE: Flowise;\n  CACHE: CacheConf;\n  S3?: S3;\n  AUTHENTICATION: Auth;\n  METRICS: Metrics;\n  TELEMETRY: Telemetry;\n  PROXY: Proxy;\n  AUDIO_CONVERTER: AudioConverter;\n  FACEBOOK: Facebook;\n  SENTRY: Sentry;\n  EVENT_EMITTER: EventEmitter;\n  PRODUCTION?: Production;\n}\n\nexport type Key = keyof Env;\n\nexport class ConfigService {\n  constructor() {\n    this.loadEnv();\n  }\n\n  private env: Env;\n\n  public get<T = any>(key: Key) {\n    return this.env[key] as T;\n  }\n\n  private loadEnv() {\n    this.env = this.envProcess();\n    this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';\n    if (process.env?.DOCKER_ENV === 'true') {\n      this.env.SERVER.TYPE = process.env.SERVER_TYPE as 'http' | 'http';\n      this.env.SERVER.PORT = Number.parseInt(process.env.SERVER_PORT) || 8080;\n    }\n  }\n\n  private envProcess(): Env {\n    return {\n      SERVER: {\n        NAME: process.env?.SERVER_NAME || 'evolution',\n        TYPE: (process.env.SERVER_TYPE as 'http' | 'https') || 'http',\n        PORT: Number.parseInt(process.env.SERVER_PORT) || 8080,\n        URL: process.env.SERVER_URL,\n        DISABLE_DOCS: process.env?.SERVER_DISABLE_DOCS === 'true',\n        DISABLE_MANAGER: process.env?.SERVER_DISABLE_MANAGER === 'true',\n      },\n      CORS: {\n        ORIGIN: process.env.CORS_ORIGIN?.split(',') || ['*'],\n        METHODS:\n          (process.env.CORS_METHODS?.split(',') as HttpMethods[]) ||\n          (['POST', 'GET', 'PUT', 'DELETE'] as HttpMethods[]),\n        CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true',\n      },\n      SSL_CONF: {\n        PRIVKEY: process.env?.SSL_CONF_PRIVKEY || '',\n        FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN || '',\n      },\n      PROVIDER: {\n        ENABLED: process.env?.PROVIDER_ENABLED === 'true',\n        HOST: process.env.PROVIDER_HOST,\n        PORT: process.env?.PROVIDER_PORT || '5656',\n        PREFIX: process.env?.PROVIDER_PREFIX || 'evolution',\n      },\n      DATABASE: {\n        CONNECTION: {\n          URI: process.env.DATABASE_CONNECTION_URI || '',\n          CLIENT_NAME: process.env.DATABASE_CONNECTION_CLIENT_NAME || 'evolution',\n        },\n        PROVIDER: process.env.DATABASE_PROVIDER || 'postgresql',\n        SAVE_DATA: {\n          INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',\n          NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',\n          MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true',\n          CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true',\n          CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true',\n          HISTORIC: process.env?.DATABASE_SAVE_DATA_HISTORIC === 'true',\n          LABELS: process.env?.DATABASE_SAVE_DATA_LABELS === 'true',\n          IS_ON_WHATSAPP: process.env?.DATABASE_SAVE_IS_ON_WHATSAPP === 'true',\n          IS_ON_WHATSAPP_DAYS: Number.parseInt(process.env?.DATABASE_SAVE_IS_ON_WHATSAPP_DAYS ?? '7'),\n        },\n        DELETE_DATA: {\n          LOGICAL_MESSAGE_DELETE: process.env?.DATABASE_DELETE_MESSAGE === 'true',\n        },\n      },\n      RABBITMQ: {\n        ENABLED: process.env?.RABBITMQ_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.RABBITMQ_GLOBAL_ENABLED === 'true',\n        PREFIX_KEY: process.env?.RABBITMQ_PREFIX_KEY,\n        EXCHANGE_NAME: process.env?.RABBITMQ_EXCHANGE_NAME || 'evolution_exchange',\n        URI: process.env.RABBITMQ_URI || '',\n        FRAME_MAX: Number.parseInt(process.env.RABBITMQ_FRAME_MAX) || 8192,\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.RABBITMQ_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.RABBITMQ_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.RABBITMQ_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.RABBITMQ_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.RABBITMQ_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.RABBITMQ_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.RABBITMQ_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.RABBITMQ_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.RABBITMQ_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.RABBITMQ_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.RABBITMQ_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.RABBITMQ_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.RABBITMQ_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.RABBITMQ_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.RABBITMQ_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.RABBITMQ_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.RABBITMQ_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.RABBITMQ_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.RABBITMQ_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.RABBITMQ_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.RABBITMQ_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.RABBITMQ_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.RABBITMQ_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.RABBITMQ_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      NATS: {\n        ENABLED: process.env?.NATS_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.NATS_GLOBAL_ENABLED === 'true',\n        PREFIX_KEY: process.env?.NATS_PREFIX_KEY,\n        EXCHANGE_NAME: process.env?.NATS_EXCHANGE_NAME || 'evolution_exchange',\n        URI: process.env.NATS_URI || '',\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.NATS_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.NATS_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.NATS_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.NATS_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.NATS_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.NATS_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.NATS_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.NATS_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.NATS_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.NATS_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.NATS_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.NATS_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.NATS_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.NATS_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.NATS_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.NATS_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.NATS_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.NATS_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.NATS_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.NATS_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.NATS_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.NATS_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.NATS_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.NATS_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.NATS_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.NATS_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.NATS_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.NATS_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      SQS: {\n        ENABLED: process.env?.SQS_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.SQS_GLOBAL_ENABLED === 'true',\n        GLOBAL_FORCE_SINGLE_QUEUE: process.env?.SQS_GLOBAL_FORCE_SINGLE_QUEUE === 'true',\n        GLOBAL_PREFIX_NAME: process.env?.SQS_GLOBAL_PREFIX_NAME || 'global',\n        ACCESS_KEY_ID: process.env.SQS_ACCESS_KEY_ID || '',\n        SECRET_ACCESS_KEY: process.env.SQS_SECRET_ACCESS_KEY || '',\n        ACCOUNT_ID: process.env.SQS_ACCOUNT_ID || '',\n        REGION: process.env.SQS_REGION || '',\n        MAX_PAYLOAD_SIZE: Number.parseInt(process.env.SQS_MAX_PAYLOAD_SIZE ?? '1048576'),\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.SQS_GLOBAL_APPLICATION_STARTUP === 'true',\n          CALL: process.env?.SQS_GLOBAL_CALL === 'true',\n          CHATS_DELETE: process.env?.SQS_GLOBAL_CHATS_DELETE === 'true',\n          CHATS_SET: process.env?.SQS_GLOBAL_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.SQS_GLOBAL_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.SQS_GLOBAL_CHATS_UPSERT === 'true',\n          CONNECTION_UPDATE: process.env?.SQS_GLOBAL_CONNECTION_UPDATE === 'true',\n          CONTACTS_SET: process.env?.SQS_GLOBAL_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.SQS_GLOBAL_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.SQS_GLOBAL_CONTACTS_UPSERT === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.SQS_GLOBAL_GROUP_PARTICIPANTS_UPDATE === 'true',\n          GROUPS_UPDATE: process.env?.SQS_GLOBAL_GROUPS_UPDATE === 'true',\n          GROUPS_UPSERT: process.env?.SQS_GLOBAL_GROUPS_UPSERT === 'true',\n          LABELS_ASSOCIATION: process.env?.SQS_GLOBAL_LABELS_ASSOCIATION === 'true',\n          LABELS_EDIT: process.env?.SQS_GLOBAL_LABELS_EDIT === 'true',\n          LOGOUT_INSTANCE: process.env?.SQS_GLOBAL_LOGOUT_INSTANCE === 'true',\n          MESSAGES_DELETE: process.env?.SQS_GLOBAL_MESSAGES_DELETE === 'true',\n          MESSAGES_EDITED: process.env?.SQS_GLOBAL_MESSAGES_EDITED === 'true',\n          MESSAGES_SET: process.env?.SQS_GLOBAL_MESSAGES_SET === 'true',\n          MESSAGES_UPDATE: process.env?.SQS_GLOBAL_MESSAGES_UPDATE === 'true',\n          MESSAGES_UPSERT: process.env?.SQS_GLOBAL_MESSAGES_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.SQS_GLOBAL_PRESENCE_UPDATE === 'true',\n          QRCODE_UPDATED: process.env?.SQS_GLOBAL_QRCODE_UPDATED === 'true',\n          REMOVE_INSTANCE: process.env?.SQS_GLOBAL_REMOVE_INSTANCE === 'true',\n          SEND_MESSAGE: process.env?.SQS_GLOBAL_SEND_MESSAGE === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.SQS_GLOBAL_TYPEBOT_CHANGE_STATUS === 'true',\n          TYPEBOT_START: process.env?.SQS_GLOBAL_TYPEBOT_START === 'true',\n        },\n      },\n      KAFKA: {\n        ENABLED: process.env?.KAFKA_ENABLED === 'true',\n        CLIENT_ID: process.env?.KAFKA_CLIENT_ID || 'evolution-api',\n        BROKERS: process.env?.KAFKA_BROKERS?.split(',') || ['localhost:9092'],\n        CONNECTION_TIMEOUT: Number.parseInt(process.env?.KAFKA_CONNECTION_TIMEOUT || '3000'),\n        REQUEST_TIMEOUT: Number.parseInt(process.env?.KAFKA_REQUEST_TIMEOUT || '30000'),\n        GLOBAL_ENABLED: process.env?.KAFKA_GLOBAL_ENABLED === 'true',\n        CONSUMER_GROUP_ID: process.env?.KAFKA_CONSUMER_GROUP_ID || 'evolution-api-consumers',\n        TOPIC_PREFIX: process.env?.KAFKA_TOPIC_PREFIX || 'evolution',\n        NUM_PARTITIONS: Number.parseInt(process.env?.KAFKA_NUM_PARTITIONS || '1'),\n        REPLICATION_FACTOR: Number.parseInt(process.env?.KAFKA_REPLICATION_FACTOR || '1'),\n        AUTO_CREATE_TOPICS: process.env?.KAFKA_AUTO_CREATE_TOPICS === 'true',\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.KAFKA_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.KAFKA_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.KAFKA_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.KAFKA_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.KAFKA_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.KAFKA_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.KAFKA_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.KAFKA_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.KAFKA_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.KAFKA_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.KAFKA_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.KAFKA_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPSERT: process.env?.KAFKA_EVENTS_CONTACTS_UPSERT === 'true',\n          CONTACTS_UPDATE: process.env?.KAFKA_EVENTS_CONTACTS_UPDATE === 'true',\n          PRESENCE_UPDATE: process.env?.KAFKA_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.KAFKA_EVENTS_CHATS_SET === 'true',\n          CHATS_UPSERT: process.env?.KAFKA_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_UPDATE: process.env?.KAFKA_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_DELETE: process.env?.KAFKA_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.KAFKA_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.KAFKA_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.KAFKA_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.KAFKA_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.KAFKA_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.KAFKA_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.KAFKA_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.KAFKA_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.KAFKA_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n        SASL:\n          process.env?.KAFKA_SASL_ENABLED === 'true'\n            ? {\n                ENABLED: true,\n                MECHANISM: process.env?.KAFKA_SASL_MECHANISM || 'plain',\n                USERNAME: process.env?.KAFKA_SASL_USERNAME || '',\n                PASSWORD: process.env?.KAFKA_SASL_PASSWORD || '',\n              }\n            : undefined,\n        SSL:\n          process.env?.KAFKA_SSL_ENABLED === 'true'\n            ? {\n                ENABLED: true,\n                REJECT_UNAUTHORIZED: process.env?.KAFKA_SSL_REJECT_UNAUTHORIZED !== 'false',\n                CA: process.env?.KAFKA_SSL_CA,\n                KEY: process.env?.KAFKA_SSL_KEY,\n                CERT: process.env?.KAFKA_SSL_CERT,\n              }\n            : undefined,\n      },\n      WEBSOCKET: {\n        ENABLED: process.env?.WEBSOCKET_ENABLED === 'true',\n        GLOBAL_EVENTS: process.env?.WEBSOCKET_GLOBAL_EVENTS === 'true',\n        ALLOWED_HOSTS: process.env?.WEBSOCKET_ALLOWED_HOSTS,\n      },\n      PUSHER: {\n        ENABLED: process.env?.PUSHER_ENABLED === 'true',\n        GLOBAL: {\n          ENABLED: process.env?.PUSHER_GLOBAL_ENABLED === 'true',\n          APP_ID: process.env?.PUSHER_GLOBAL_APP_ID || '',\n          KEY: process.env?.PUSHER_GLOBAL_KEY || '',\n          SECRET: process.env?.PUSHER_GLOBAL_SECRET || '',\n          CLUSTER: process.env?.PUSHER_GLOBAL_CLUSTER || '',\n          USE_TLS: process.env?.PUSHER_GLOBAL_USE_TLS === 'true',\n        },\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.PUSHER_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.PUSHER_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.PUSHER_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.PUSHER_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.PUSHER_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.PUSHER_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.PUSHER_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.PUSHER_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.PUSHER_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.PUSHER_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.PUSHER_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.PUSHER_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.PUSHER_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.PUSHER_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.PUSHER_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.PUSHER_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.PUSHER_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.PUSHER_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.PUSHER_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.PUSHER_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.PUSHER_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.PUSHER_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.PUSHER_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.PUSHER_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.PUSHER_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.PUSHER_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.PUSHER_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.PUSHER_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      WA_BUSINESS: {\n        TOKEN_WEBHOOK: process.env.WA_BUSINESS_TOKEN_WEBHOOK || 'evolution',\n        URL: process.env.WA_BUSINESS_URL || 'https://graph.facebook.com',\n        VERSION: process.env.WA_BUSINESS_VERSION || 'v18.0',\n        LANGUAGE: process.env.WA_BUSINESS_LANGUAGE || 'en',\n      },\n      LOG: {\n        LEVEL:\n          (process.env?.LOG_LEVEL?.split(',') as LogLevel[]) ||\n          (['ERROR', 'WARN', 'DEBUG', 'INFO', 'LOG', 'VERBOSE', 'DARK', 'WEBHOOKS', 'WEBSOCKET'] as LogLevel[]),\n        COLOR: process.env?.LOG_COLOR === 'true',\n        BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error',\n      },\n      DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE)\n        ? process.env.DEL_INSTANCE === 'true'\n        : Number.parseInt(process.env.DEL_INSTANCE) || false,\n      DEL_TEMP_INSTANCES: isBooleanString(process.env?.DEL_TEMP_INSTANCES)\n        ? process.env.DEL_TEMP_INSTANCES === 'true'\n        : true,\n      LANGUAGE: process.env?.LANGUAGE || 'en',\n      WEBHOOK: {\n        GLOBAL: {\n          URL: process.env?.WEBHOOK_GLOBAL_URL || '',\n          ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true',\n          WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true',\n        },\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.WEBHOOK_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.WEBHOOK_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.WEBHOOK_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.WEBHOOK_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.WEBHOOK_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n          ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',\n          ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',\n        },\n        REQUEST: {\n          TIMEOUT_MS: Number.parseInt(process.env?.WEBHOOK_REQUEST_TIMEOUT_MS) || 30000,\n        },\n        RETRY: {\n          MAX_ATTEMPTS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_ATTEMPTS) || 10,\n          INITIAL_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_INITIAL_DELAY_SECONDS) || 5,\n          USE_EXPONENTIAL_BACKOFF: process.env?.WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF !== 'false',\n          MAX_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_DELAY_SECONDS) || 300,\n          JITTER_FACTOR: Number.parseFloat(process.env?.WEBHOOK_RETRY_JITTER_FACTOR) || 0.2,\n          NON_RETRYABLE_STATUS_CODES: process.env?.WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES?.split(',').map(Number) || [\n            400, 401, 403, 404, 422,\n          ],\n        },\n      },\n      CONFIG_SESSION_PHONE: {\n        CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API',\n        NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'Chrome',\n      },\n      QRCODE: {\n        LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30,\n        COLOR: process.env.QRCODE_COLOR || '#198754',\n      },\n      TYPEBOT: {\n        ENABLED: process.env?.TYPEBOT_ENABLED === 'true',\n        API_VERSION: process.env?.TYPEBOT_API_VERSION || 'old',\n        SEND_MEDIA_BASE64: process.env?.TYPEBOT_SEND_MEDIA_BASE64 === 'true',\n      },\n      CHATWOOT: {\n        ENABLED: process.env?.CHATWOOT_ENABLED === 'true',\n        MESSAGE_DELETE: process.env.CHATWOOT_MESSAGE_DELETE === 'true',\n        MESSAGE_READ: process.env.CHATWOOT_MESSAGE_READ === 'true',\n        BOT_CONTACT: !process.env.CHATWOOT_BOT_CONTACT || process.env.CHATWOOT_BOT_CONTACT === 'true',\n        IMPORT: {\n          DATABASE: {\n            CONNECTION: {\n              URI: process.env.CHATWOOT_IMPORT_DATABASE_CONNECTION_URI || '',\n            },\n          },\n          PLACEHOLDER_MEDIA_MESSAGE: process.env?.CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE === 'true',\n        },\n      },\n      OPENAI: {\n        ENABLED: process.env?.OPENAI_ENABLED === 'true',\n        API_KEY_GLOBAL: process.env?.OPENAI_API_KEY_GLOBAL || null,\n      },\n      DIFY: {\n        ENABLED: process.env?.DIFY_ENABLED === 'true',\n      },\n      N8N: {\n        ENABLED: process.env?.N8N_ENABLED === 'true',\n      },\n      EVOAI: {\n        ENABLED: process.env?.EVOAI_ENABLED === 'true',\n      },\n      FLOWISE: {\n        ENABLED: process.env?.FLOWISE_ENABLED === 'true',\n      },\n      CACHE: {\n        REDIS: {\n          ENABLED: process.env?.CACHE_REDIS_ENABLED === 'true',\n          URI: process.env?.CACHE_REDIS_URI || '',\n          PREFIX_KEY: process.env?.CACHE_REDIS_PREFIX_KEY || 'evolution-cache',\n          TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 604800,\n          SAVE_INSTANCES: process.env?.CACHE_REDIS_SAVE_INSTANCES === 'true',\n        },\n        LOCAL: {\n          ENABLED: process.env?.CACHE_LOCAL_ENABLED === 'true',\n          TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 86400,\n        },\n      },\n      S3: {\n        ACCESS_KEY: process.env?.S3_ACCESS_KEY,\n        SECRET_KEY: process.env?.S3_SECRET_KEY,\n        ENDPOINT: process.env?.S3_ENDPOINT,\n        BUCKET_NAME: process.env?.S3_BUCKET,\n        ENABLE: process.env?.S3_ENABLED === 'true',\n        PORT: Number.parseInt(process.env?.S3_PORT || '9000'),\n        USE_SSL: process.env?.S3_USE_SSL === 'true',\n        REGION: process.env?.S3_REGION,\n        SKIP_POLICY: process.env?.S3_SKIP_POLICY === 'true',\n        SAVE_VIDEO: process.env?.S3_SAVE_VIDEO === 'true',\n      },\n      AUTHENTICATION: {\n        API_KEY: {\n          KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',\n        },\n        EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true',\n      },\n      METRICS: {\n        ENABLED: process.env?.PROMETHEUS_METRICS === 'true',\n        AUTH_REQUIRED: process.env?.METRICS_AUTH_REQUIRED === 'true',\n        USER: process.env?.METRICS_USER,\n        PASSWORD: process.env?.METRICS_PASSWORD,\n        ALLOWED_IPS: process.env?.METRICS_ALLOWED_IPS,\n      },\n      TELEMETRY: {\n        ENABLED: process.env?.TELEMETRY_ENABLED === undefined || process.env?.TELEMETRY_ENABLED === 'true',\n        URL: process.env?.TELEMETRY_URL,\n      },\n      PROXY: {\n        HOST: process.env?.PROXY_HOST,\n        PORT: process.env?.PROXY_PORT,\n        PROTOCOL: process.env?.PROXY_PROTOCOL,\n        USERNAME: process.env?.PROXY_USERNAME,\n        PASSWORD: process.env?.PROXY_PASSWORD,\n      },\n      AUDIO_CONVERTER: {\n        API_URL: process.env?.API_AUDIO_CONVERTER,\n        API_KEY: process.env?.API_AUDIO_CONVERTER_KEY,\n      },\n      FACEBOOK: {\n        APP_ID: process.env?.FACEBOOK_APP_ID,\n        CONFIG_ID: process.env?.FACEBOOK_CONFIG_ID,\n        USER_TOKEN: process.env?.FACEBOOK_USER_TOKEN,\n      },\n      SENTRY: {\n        DSN: process.env?.SENTRY_DSN,\n      },\n      EVENT_EMITTER: {\n        MAX_LISTENERS: Number.parseInt(process.env?.EVENT_EMITTER_MAX_LISTENERS) || 50,\n      },\n    };\n  }\n}\n\nexport const configService = new ConfigService();\n","import dayjs from 'dayjs';\nimport fs from 'fs';\n\nimport { configService, Log } from './env.config';\nconst packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));\n\nconst formatDateLog = (timestamp: number) =>\n  dayjs(timestamp)\n    .toDate()\n    .toString()\n    .replace(/\\sGMT.+/, '');\n\nenum Color {\n  LOG = '\\x1b[32m',\n  INFO = '\\x1b[34m',\n  WARN = '\\x1b[33m',\n  ERROR = '\\x1b[31m',\n  DEBUG = '\\x1b[36m',\n  VERBOSE = '\\x1b[37m',\n  DARK = '\\x1b[30m',\n}\n\nenum Command {\n  RESET = '\\x1b[0m',\n  BRIGHT = '\\x1b[1m',\n  UNDERSCORE = '\\x1b[4m',\n}\n\nenum Level {\n  LOG = Color.LOG + '%s' + Command.RESET,\n  DARK = Color.DARK + '%s' + Command.RESET,\n  INFO = Color.INFO + '%s' + Command.RESET,\n  WARN = Color.WARN + '%s' + Command.RESET,\n  ERROR = Color.ERROR + '%s' + Command.RESET,\n  DEBUG = Color.DEBUG + '%s' + Command.RESET,\n  VERBOSE = Color.VERBOSE + '%s' + Command.RESET,\n}\n\nenum Type {\n  LOG = 'LOG',\n  WARN = 'WARN',\n  INFO = 'INFO',\n  DARK = 'DARK',\n  ERROR = 'ERROR',\n  DEBUG = 'DEBUG',\n  VERBOSE = 'VERBOSE',\n}\n\nenum Background {\n  LOG = '\\x1b[42m',\n  INFO = '\\x1b[44m',\n  WARN = '\\x1b[43m',\n  DARK = '\\x1b[40m',\n  ERROR = '\\x1b[41m',\n  DEBUG = '\\x1b[46m',\n  VERBOSE = '\\x1b[47m',\n}\n\nexport class Logger {\n  private readonly configService = configService;\n  private context: string;\n\n  constructor(context = 'Logger') {\n    this.context = context;\n  }\n\n  private instance = null;\n\n  public setContext(value: string) {\n    this.context = value;\n  }\n\n  public setInstance(value: string) {\n    this.instance = value;\n  }\n\n  private console(value: any, type: Type) {\n    const types: Type[] = [];\n\n    this.configService.get<Log>('LOG').LEVEL.forEach((level) => types.push(Type[level]));\n\n    const typeValue = typeof value;\n    if (types.includes(type)) {\n      if (configService.get<Log>('LOG').COLOR) {\n        console.log(\n          /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type],\n          '[Evolution API]',\n          Command.BRIGHT + Color[type],\n          this.instance ? `[${this.instance}]` : '',\n          Command.BRIGHT + Color[type],\n          `v${packageJson.version}`,\n          Command.BRIGHT + Color[type],\n          process.pid.toString(),\n          Command.RESET,\n          Command.BRIGHT + Color[type],\n          '-',\n          Command.BRIGHT + Color.VERBOSE,\n          `${formatDateLog(Date.now())}  `,\n          Command.RESET,\n          Color[type] + Background[type] + Command.BRIGHT,\n          `${type} ` + Command.RESET,\n          Color.WARN + Command.BRIGHT,\n          `[${this.context}]` + Command.RESET,\n          Color[type] + Command.BRIGHT,\n          `[${typeValue}]` + Command.RESET,\n          Color[type],\n          typeValue !== 'object' ? value : '',\n          Command.RESET,\n        );\n        typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\\n') : '';\n      } else {\n        console.log(\n          '[Evolution API]',\n          this.instance ? `[${this.instance}]` : '',\n          process.pid.toString(),\n          '-',\n          `${formatDateLog(Date.now())}  `,\n          `${type} `,\n          `[${this.context}]`,\n          `[${typeValue}]`,\n          value,\n        );\n      }\n    }\n  }\n\n  public log(value: any) {\n    this.console(value, Type.LOG);\n  }\n\n  public info(value: any) {\n    this.console(value, Type.INFO);\n  }\n\n  public warn(value: any) {\n    this.console(value, Type.WARN);\n  }\n\n  public error(value: any) {\n    this.console(value, Type.ERROR);\n  }\n\n  public verbose(value: any) {\n    this.console(value, Type.VERBOSE);\n  }\n\n  public debug(value: any) {\n    this.console(value, Type.DEBUG);\n  }\n\n  public dark(value: any) {\n    this.console(value, Type.DARK);\n  }\n}\n","import { Chatwoot, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport postgresql from 'pg';\n\nconst { Pool } = postgresql;\n\nclass Postgres {\n  private logger = new Logger('Postgres');\n  private pool;\n  private connected = false;\n\n  getConnection(connectionString: string) {\n    if (this.connected) {\n      return this.pool;\n    } else {\n      this.pool = new Pool({\n        connectionString,\n        ssl: {\n          rejectUnauthorized: false,\n        },\n      });\n\n      this.pool.on('error', () => {\n        this.logger.error('postgres disconnected');\n        this.connected = false;\n      });\n\n      try {\n        this.connected = true;\n      } catch (e) {\n        this.connected = false;\n        this.logger.error('postgres connect exception caught: ' + e);\n        return null;\n      }\n\n      return this.pool;\n    }\n  }\n\n  getChatwootConnection() {\n    const uri = configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n    return this.getConnection(uri);\n  }\n}\n\nexport const postgresClient = new Postgres();\n","import { InstanceDto } from '@api/dto/instance.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';\nimport { ChatwootService } from '@api/integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { Chatwoot, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { inbox } from '@figuro/chatwoot-sdk';\nimport { Chatwoot as ChatwootModel, Contact, Message } from '@prisma/client';\nimport { proto } from 'baileys';\n\ntype ChatwootUser = {\n  user_type: string;\n  user_id: number;\n};\n\ntype FksChatwoot = {\n  phone_number: string;\n  contact_id: string;\n  conversation_id: string;\n};\n\ntype firstLastTimestamp = {\n  first: number;\n  last: number;\n};\n\ntype IWebMessageInfo = Omit<proto.IWebMessageInfo, 'key'> & Partial<Pick<proto.IWebMessageInfo, 'key'>>;\n\nclass ChatwootImport {\n  private logger = new Logger('ChatwootImport');\n  private repositoryMessagesCache = new Map<string, Set<string>>();\n  private historyMessages = new Map<string, Message[]>();\n  private historyContacts = new Map<string, Contact[]>();\n\n  public getRepositoryMessagesCache(instance: InstanceDto) {\n    return this.repositoryMessagesCache.has(instance.instanceName)\n      ? this.repositoryMessagesCache.get(instance.instanceName)\n      : null;\n  }\n\n  public setRepositoryMessagesCache(instance: InstanceDto, repositoryMessagesCache: Set<string>) {\n    this.repositoryMessagesCache.set(instance.instanceName, repositoryMessagesCache);\n  }\n\n  public deleteRepositoryMessagesCache(instance: InstanceDto) {\n    this.repositoryMessagesCache.delete(instance.instanceName);\n  }\n\n  public addHistoryMessages(instance: InstanceDto, messagesRaw: Message[]) {\n    const actualValue = this.historyMessages.has(instance.instanceName)\n      ? this.historyMessages.get(instance.instanceName)\n      : [];\n    this.historyMessages.set(instance.instanceName, [...actualValue, ...messagesRaw]);\n  }\n\n  public addHistoryContacts(instance: InstanceDto, contactsRaw: Contact[]) {\n    const actualValue = this.historyContacts.has(instance.instanceName)\n      ? this.historyContacts.get(instance.instanceName)\n      : [];\n    this.historyContacts.set(instance.instanceName, actualValue.concat(contactsRaw));\n  }\n\n  public deleteHistoryMessages(instance: InstanceDto) {\n    this.historyMessages.delete(instance.instanceName);\n  }\n\n  public deleteHistoryContacts(instance: InstanceDto) {\n    this.historyContacts.delete(instance.instanceName);\n  }\n\n  public clearAll(instance: InstanceDto) {\n    this.deleteRepositoryMessagesCache(instance);\n    this.deleteHistoryMessages(instance);\n    this.deleteHistoryContacts(instance);\n  }\n\n  public getHistoryMessagesLenght(instance: InstanceDto) {\n    return this.historyMessages.get(instance.instanceName)?.length ?? 0;\n  }\n\n  public async importHistoryContacts(instance: InstanceDto, provider: ChatwootDto) {\n    try {\n      if (this.getHistoryMessagesLenght(instance) > 0) {\n        return;\n      }\n\n      const pgClient = postgresClient.getChatwootConnection();\n\n      let totalContactsImported = 0;\n\n      const contacts = this.historyContacts.get(instance.instanceName) || [];\n      if (contacts.length === 0) {\n        return 0;\n      }\n\n      let contactsChunk: Contact[] = this.sliceIntoChunks(contacts, 3000);\n      while (contactsChunk.length > 0) {\n        const labelSql = `SELECT id FROM labels WHERE title = '${provider.nameInbox}' AND account_id = ${provider.accountId} LIMIT 1`;\n\n        let labelId = (await pgClient.query(labelSql))?.rows[0]?.id;\n\n        if (!labelId) {\n          // creating label in chatwoot db and getting the id\n          const sqlLabel = `INSERT INTO labels (title, color, show_on_sidebar, account_id, created_at, updated_at) VALUES ('${provider.nameInbox}', '#34039B', true, ${provider.accountId}, NOW(), NOW()) RETURNING id`;\n\n          labelId = (await pgClient.query(sqlLabel))?.rows[0]?.id;\n        }\n\n        // inserting contacts in chatwoot db\n        let sqlInsert = `INSERT INTO contacts\n          (name, phone_number, account_id, identifier, created_at, updated_at) VALUES `;\n        const bindInsert = [provider.accountId];\n\n        for (const contact of contactsChunk) {\n          const isGroup = this.isIgnorePhoneNumber(contact.remoteJid);\n\n          const contactName = isGroup ? `${contact.pushName} (GROUP)` : contact.pushName;\n          bindInsert.push(contactName);\n          const bindName = `$${bindInsert.length}`;\n\n          let bindPhoneNumber: string;\n          if (!isGroup) {\n            bindInsert.push(`+${contact.remoteJid.split('@')[0]}`);\n            bindPhoneNumber = `$${bindInsert.length}`;\n          } else {\n            bindPhoneNumber = 'NULL';\n          }\n          bindInsert.push(contact.remoteJid);\n          const bindIdentifier = `$${bindInsert.length}`;\n\n          sqlInsert += `(${bindName}, ${bindPhoneNumber}, $1, ${bindIdentifier}, NOW(), NOW()),`;\n        }\n        if (sqlInsert.slice(-1) === ',') {\n          sqlInsert = sqlInsert.slice(0, -1);\n        }\n        sqlInsert += ` ON CONFLICT (identifier, account_id)\n                       DO UPDATE SET\n                        name = EXCLUDED.name,\n                        phone_number = EXCLUDED.phone_number,\n                        updated_at = NOW()`;\n\n        totalContactsImported += (await pgClient.query(sqlInsert, bindInsert))?.rowCount ?? 0;\n\n        const sqlTags = `SELECT id FROM tags WHERE name = '${provider.nameInbox}' LIMIT 1`;\n\n        const tagData = (await pgClient.query(sqlTags))?.rows[0];\n        let tagId = tagData?.id;\n\n        const sqlTag = `INSERT INTO tags (name, taggings_count) VALUES ('${provider.nameInbox}', ${totalContactsImported}) ON CONFLICT (name) DO UPDATE SET taggings_count = tags.taggings_count + ${totalContactsImported} RETURNING id`;\n\n        tagId = (await pgClient.query(sqlTag))?.rows[0]?.id;\n\n        await pgClient.query(sqlTag);\n\n        let sqlInsertLabel = `INSERT INTO taggings (tag_id, taggable_type, taggable_id, context, created_at) VALUES `;\n\n        contactsChunk.forEach((contact) => {\n          const bindTaggableId = `(SELECT id FROM contacts WHERE identifier = '${contact.remoteJid}' AND account_id = ${provider.accountId})`;\n          sqlInsertLabel += `($1, $2, ${bindTaggableId}, $3, NOW()),`;\n        });\n\n        if (sqlInsertLabel.slice(-1) === ',') {\n          sqlInsertLabel = sqlInsertLabel.slice(0, -1);\n        }\n\n        await pgClient.query(sqlInsertLabel, [tagId, 'Contact', 'labels']);\n\n        contactsChunk = this.sliceIntoChunks(contacts, 3000);\n      }\n\n      this.deleteHistoryContacts(instance);\n\n      return totalContactsImported;\n    } catch (error) {\n      this.logger.error(`Error on import history contacts: ${error.toString()}`);\n    }\n  }\n\n  public async getExistingSourceIds(sourceIds: string[], conversationId?: number): Promise<Set<string>> {\n    try {\n      const existingSourceIdsSet = new Set<string>();\n\n      if (sourceIds.length === 0) {\n        return existingSourceIdsSet;\n      }\n\n      // Ensure all sourceIds are consistently prefixed with 'WAID:' as required by downstream systems and database queries.\n      const formattedSourceIds = sourceIds.map((sourceId) => `WAID:${sourceId.replace('WAID:', '')}`);\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const params = conversationId ? [formattedSourceIds, conversationId] : [formattedSourceIds];\n\n      const query = conversationId\n        ? 'SELECT source_id FROM messages WHERE source_id = ANY($1) AND conversation_id = $2'\n        : 'SELECT source_id FROM messages WHERE source_id = ANY($1)';\n\n      const result = await pgClient.query(query, params);\n      for (const row of result.rows) {\n        existingSourceIdsSet.add(row.source_id);\n      }\n\n      return existingSourceIdsSet;\n    } catch (error) {\n      this.logger.error(`Error on getExistingSourceIds: ${error.toString()}`);\n      return new Set<string>();\n    }\n  }\n\n  public async importHistoryMessages(\n    instance: InstanceDto,\n    chatwootService: ChatwootService,\n    inbox: inbox,\n    provider: ChatwootModel,\n  ) {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const chatwootUser = await this.getChatwootUser(provider);\n      if (!chatwootUser) {\n        throw new Error('User not found to import messages.');\n      }\n\n      let totalMessagesImported = 0;\n\n      let messagesOrdered = this.historyMessages.get(instance.instanceName) || [];\n      if (messagesOrdered.length === 0) {\n        return 0;\n      }\n\n      // ordering messages by number and timestamp asc\n      messagesOrdered.sort((a, b) => {\n        const aKey = a.key as {\n          remoteJid: string;\n        };\n\n        const bKey = b.key as {\n          remoteJid: string;\n        };\n\n        const aMessageTimestamp = a.messageTimestamp as any as number;\n        const bMessageTimestamp = b.messageTimestamp as any as number;\n\n        return parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) || aMessageTimestamp - bMessageTimestamp;\n      });\n\n      const allMessagesMappedByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesOrdered);\n      // Map structure: +552199999999 => { first message timestamp from number, last message timestamp from number}\n      const phoneNumbersWithTimestamp = new Map<string, firstLastTimestamp>();\n      allMessagesMappedByPhoneNumber.forEach((messages: Message[], phoneNumber: string) => {\n        phoneNumbersWithTimestamp.set(phoneNumber, {\n          first: messages[0]?.messageTimestamp as any as number,\n          last: messages[messages.length - 1]?.messageTimestamp as any as number,\n        });\n      });\n\n      const existingSourceIds = await this.getExistingSourceIds(messagesOrdered.map((message: any) => message.key.id));\n      messagesOrdered = messagesOrdered.filter((message: any) => !existingSourceIds.has(message.key.id));\n      // processing messages in batch\n      const batchSize = 4000;\n      let messagesChunk: Message[] = this.sliceIntoChunks(messagesOrdered, batchSize);\n      while (messagesChunk.length > 0) {\n        // Map structure: +552199999999 => Message[]\n        const messagesByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesChunk);\n\n        if (messagesByPhoneNumber.size > 0) {\n          const fksByNumber = await this.selectOrCreateFksFromChatwoot(\n            provider,\n            inbox,\n            phoneNumbersWithTimestamp,\n            messagesByPhoneNumber,\n          );\n\n          // inserting messages in chatwoot db\n          let sqlInsertMsg = `INSERT INTO messages\n            (content, processed_message_content, account_id, inbox_id, conversation_id, message_type, private, content_type,\n            sender_type, sender_id, source_id, created_at, updated_at) VALUES `;\n          const bindInsertMsg = [provider.accountId, inbox.id];\n\n          messagesByPhoneNumber.forEach((messages: any[], phoneNumber: string) => {\n            const fksChatwoot = fksByNumber.get(phoneNumber);\n\n            messages.forEach((message) => {\n              if (!message.message) {\n                return;\n              }\n\n              if (!fksChatwoot?.conversation_id || !fksChatwoot?.contact_id) {\n                return;\n              }\n\n              const contentMessage = this.getContentMessage(chatwootService, message);\n              if (!contentMessage) {\n                return;\n              }\n\n              bindInsertMsg.push(contentMessage);\n              const bindContent = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(fksChatwoot.conversation_id);\n              const bindConversationId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? '1' : '0');\n              const bindMessageType = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? chatwootUser.user_type : 'Contact');\n              const bindSenderType = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? chatwootUser.user_id : fksChatwoot.contact_id);\n              const bindSenderId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push('WAID:' + message.key.id);\n              const bindSourceId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.messageTimestamp as number);\n              const bindmessageTimestamp = `$${bindInsertMsg.length}`;\n\n              sqlInsertMsg += `(${bindContent}, ${bindContent}, $1, $2, ${bindConversationId}, ${bindMessageType}, FALSE, 0,\n                  ${bindSenderType},${bindSenderId},${bindSourceId}, to_timestamp(${bindmessageTimestamp}), to_timestamp(${bindmessageTimestamp})),`;\n            });\n          });\n          if (bindInsertMsg.length > 2) {\n            if (sqlInsertMsg.slice(-1) === ',') {\n              sqlInsertMsg = sqlInsertMsg.slice(0, -1);\n            }\n            totalMessagesImported += (await pgClient.query(sqlInsertMsg, bindInsertMsg))?.rowCount ?? 0;\n          }\n        }\n        messagesChunk = this.sliceIntoChunks(messagesOrdered, batchSize);\n      }\n\n      this.deleteHistoryMessages(instance);\n      this.deleteRepositoryMessagesCache(instance);\n\n      const providerData: ChatwootDto = {\n        ...provider,\n        ignoreJids: Array.isArray(provider.ignoreJids) ? provider.ignoreJids.map((event) => String(event)) : [],\n      };\n\n      this.importHistoryContacts(instance, providerData);\n\n      return totalMessagesImported;\n    } catch (error) {\n      this.logger.error(`Error on import history messages: ${error.toString()}`);\n\n      this.deleteHistoryMessages(instance);\n      this.deleteRepositoryMessagesCache(instance);\n    }\n  }\n\n  public async selectOrCreateFksFromChatwoot(\n    provider: ChatwootModel,\n    inbox: inbox,\n    phoneNumbersWithTimestamp: Map<string, firstLastTimestamp>,\n    messagesByPhoneNumber: Map<string, Message[]>,\n  ): Promise<Map<string, FksChatwoot>> {\n    const pgClient = postgresClient.getChatwootConnection();\n\n    const bindValues = [provider.accountId, inbox.id];\n    const phoneNumberBind = Array.from(messagesByPhoneNumber.keys())\n      .map((phoneNumber) => {\n        const phoneNumberTimestamp = phoneNumbersWithTimestamp.get(phoneNumber);\n\n        if (phoneNumberTimestamp) {\n          bindValues.push(phoneNumber);\n          let bindStr = `($${bindValues.length},`;\n\n          bindValues.push(phoneNumberTimestamp.first);\n          bindStr += `$${bindValues.length},`;\n\n          bindValues.push(phoneNumberTimestamp.last);\n          return `${bindStr}$${bindValues.length})`;\n        }\n      })\n      .join(',');\n\n    // select (or insert when necessary) data from tables contacts, contact_inboxes, conversations from chatwoot db\n    const sqlFromChatwoot = `WITH\n              phone_number AS (\n                SELECT phone_number, created_at::INTEGER, last_activity_at::INTEGER FROM (\n                  VALUES \n                   ${phoneNumberBind}\n                 ) as t (phone_number, created_at, last_activity_at)\n              ),\n\n              only_new_phone_number AS (\n                SELECT * FROM phone_number\n                WHERE phone_number NOT IN (\n                  SELECT phone_number\n                  FROM contacts\n                    JOIN contact_inboxes ci ON ci.contact_id = contacts.id AND ci.inbox_id = $2\n                    JOIN conversations con ON con.contact_inbox_id = ci.id \n                      AND con.account_id = $1\n                      AND con.inbox_id = $2\n                      AND con.contact_id = contacts.id\n                  WHERE contacts.account_id = $1\n                )\n              ),\n\n              new_contact AS (\n                INSERT INTO contacts (name, phone_number, account_id, identifier, created_at, updated_at)\n                SELECT REPLACE(p.phone_number, '+', ''), p.phone_number, $1, CONCAT(REPLACE(p.phone_number, '+', ''),\n                  '@s.whatsapp.net'), to_timestamp(p.created_at), to_timestamp(p.last_activity_at)\n                FROM only_new_phone_number AS p\n                ON CONFLICT(identifier, account_id) DO UPDATE SET updated_at = EXCLUDED.updated_at\n                RETURNING id, phone_number, created_at, updated_at\n              ),\n\n              new_contact_inbox AS (\n                INSERT INTO contact_inboxes (contact_id, inbox_id, source_id, created_at, updated_at)\n                SELECT new_contact.id, $2, gen_random_uuid(), new_contact.created_at, new_contact.updated_at\n                FROM new_contact \n                RETURNING id, contact_id, created_at, updated_at\n              ),\n\n              new_conversation AS (\n                INSERT INTO conversations (account_id, inbox_id, status, contact_id,\n                  contact_inbox_id, uuid, last_activity_at, created_at, updated_at)\n                SELECT $1, $2, 0, new_contact_inbox.contact_id, new_contact_inbox.id, gen_random_uuid(),\n                  new_contact_inbox.updated_at, new_contact_inbox.created_at, new_contact_inbox.updated_at\n                FROM new_contact_inbox\n                RETURNING id, contact_id\n              )\n\n              SELECT new_contact.phone_number, new_conversation.contact_id, new_conversation.id AS conversation_id\n              FROM new_conversation \n              JOIN new_contact ON new_conversation.contact_id = new_contact.id\n\n              UNION\n\n              SELECT p.phone_number, c.id contact_id, con.id conversation_id\n                FROM phone_number p\n              JOIN contacts c ON c.phone_number = p.phone_number\n              JOIN contact_inboxes ci ON ci.contact_id = c.id AND ci.inbox_id = $2\n              JOIN conversations con ON con.contact_inbox_id = ci.id AND con.account_id = $1\n                AND con.inbox_id = $2 AND con.contact_id = c.id`;\n\n    const fksFromChatwoot = await pgClient.query(sqlFromChatwoot, bindValues);\n\n    return new Map(fksFromChatwoot.rows.map((item: FksChatwoot) => [item.phone_number, item]));\n  }\n\n  public async getChatwootUser(provider: ChatwootModel): Promise<ChatwootUser> {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const sqlUser = `SELECT owner_type AS user_type, owner_id AS user_id\n                         FROM access_tokens\n                       WHERE token = $1`;\n\n      return (await pgClient.query(sqlUser, [provider.token]))?.rows[0] || false;\n    } catch (error) {\n      this.logger.error(`Error on getChatwootUser: ${error.toString()}`);\n    }\n  }\n\n  public createMessagesMapByPhoneNumber(messages: Message[]): Map<string, Message[]> {\n    return messages.reduce((acc: Map<string, Message[]>, message: Message) => {\n      const key = message?.key as {\n        remoteJid: string;\n      };\n      if (!this.isIgnorePhoneNumber(key?.remoteJid)) {\n        const phoneNumber = key?.remoteJid?.split('@')[0];\n        if (phoneNumber) {\n          const phoneNumberPlus = `+${phoneNumber}`;\n          const messages = acc.has(phoneNumberPlus) ? acc.get(phoneNumberPlus) : [];\n          messages.push(message);\n          acc.set(phoneNumberPlus, messages);\n        }\n      }\n\n      return acc;\n    }, new Map());\n  }\n\n  public async getContactsOrderByRecentConversations(\n    inbox: inbox,\n    provider: ChatwootModel,\n    limit = 50,\n  ): Promise<{ id: number; phone_number: string; identifier: string }[]> {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const sql = `SELECT contacts.id, contacts.identifier, contacts.phone_number\n                     FROM conversations\n                   JOIN contacts ON contacts.id = conversations.contact_id\n                   WHERE conversations.account_id = $1\n                     AND inbox_id = $2\n                   ORDER BY conversations.last_activity_at DESC\n                   LIMIT $3`;\n\n      return (await pgClient.query(sql, [provider.accountId, inbox.id, limit]))?.rows;\n    } catch (error) {\n      this.logger.error(`Error on get recent conversations: ${error.toString()}`);\n    }\n  }\n\n  public getContentMessage(chatwootService: ChatwootService, msg: IWebMessageInfo) {\n    const contentMessage = chatwootService.getConversationMessage(msg.message);\n    if (contentMessage) {\n      return contentMessage;\n    }\n\n    if (!configService.get<Chatwoot>('CHATWOOT').IMPORT.PLACEHOLDER_MEDIA_MESSAGE) {\n      return '';\n    }\n\n    const types = {\n      documentMessage: msg.message.documentMessage,\n      documentWithCaptionMessage: msg.message.documentWithCaptionMessage?.message?.documentMessage,\n      imageMessage: msg.message.imageMessage,\n      videoMessage: msg.message.videoMessage,\n      audioMessage: msg.message.audioMessage,\n      stickerMessage: msg.message.stickerMessage,\n      templateMessage: msg.message.templateMessage?.hydratedTemplate?.hydratedContentText,\n    };\n\n    const typeKey = Object.keys(types).find((key) => types[key] !== undefined && types[key] !== null);\n    switch (typeKey) {\n      case 'documentMessage': {\n        const doc = msg.message.documentMessage;\n        const fileName = doc?.fileName || 'document';\n        const caption = doc?.caption ? ` ${doc.caption}` : '';\n        return `_<File: ${fileName}${caption}>_`;\n      }\n\n      case 'documentWithCaptionMessage': {\n        const doc = msg.message.documentWithCaptionMessage?.message?.documentMessage;\n        const fileName = doc?.fileName || 'document';\n        const caption = doc?.caption ? ` ${doc.caption}` : '';\n        return `_<File: ${fileName}${caption}>_`;\n      }\n\n      case 'templateMessage': {\n        const template = msg.message.templateMessage?.hydratedTemplate;\n        return (\n          (template?.hydratedTitleText ? `*${template.hydratedTitleText}*\\n` : '') +\n          (template?.hydratedContentText || '')\n        );\n      }\n\n      case 'imageMessage':\n        return '_<Image Message>_';\n\n      case 'videoMessage':\n        return '_<Video Message>_';\n\n      case 'audioMessage':\n        return '_<Audio Message>_';\n\n      case 'stickerMessage':\n        return '_<Sticker Message>_';\n\n      default:\n        return '';\n    }\n  }\n\n  public sliceIntoChunks(arr: any[], chunkSize: number) {\n    return arr.splice(0, chunkSize);\n  }\n\n  public isGroup(remoteJid: string) {\n    return remoteJid.includes('@g.us');\n  }\n\n  public isIgnorePhoneNumber(remoteJid: string) {\n    return this.isGroup(remoteJid) || remoteJid === 'status@broadcast' || remoteJid === '0@s.whatsapp.net';\n  }\n\n  public updateMessageSourceID(messageId: string | number, sourceId: string) {\n    const pgClient = postgresClient.getChatwootConnection();\n\n    const sql = `UPDATE messages SET source_id = $1, status = 0, created_at = NOW(), updated_at = NOW() WHERE id = $2;`;\n\n    return pgClient.query(sql, [`WAID:${sourceId}`, messageId]);\n  }\n}\n\nexport const chatwootImport = new ChatwootImport();\n","import { InstanceDto } from '@api/dto/instance.dto';\nimport { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '@api/dto/sendMessage.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';\nimport { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { CacheService } from '@api/services/cache.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Events } from '@api/types/wa.types';\nimport { Chatwoot, ConfigService, Database, HttpServer } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport ChatwootClient, {\n  ChatwootAPIConfig,\n  contact,\n  contact_inboxes,\n  conversation,\n  conversation_show,\n  generic_id,\n  inbox,\n} from '@figuro/chatwoot-sdk';\nimport { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';\nimport { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client';\nimport i18next from '@utils/i18n';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { WAMessageContent, WAMessageKey } from 'baileys';\nimport dayjs from 'dayjs';\nimport FormData from 'form-data';\nimport { Jimp, JimpMime } from 'jimp';\nimport { parsePhoneNumberFromString } from 'libphonenumber-js';\nimport Long from 'long';\nimport mimeTypes from 'mime-types';\nimport path from 'path';\nimport { Readable } from 'stream';\n\ninterface ChatwootMessage {\n  messageId?: number;\n  inboxId?: number;\n  conversationId?: number;\n  contactInboxSourceId?: string;\n  isRead?: boolean;\n}\n\nexport class ChatwootService {\n  private readonly logger = new Logger('ChatwootService');\n\n  // Lock polling delay\n  private readonly LOCK_POLLING_DELAY_MS = 300; // Delay between lock status checks\n\n  private provider: any;\n\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    private readonly configService: ConfigService,\n    private readonly prismaRepository: PrismaRepository,\n    private readonly cache: CacheService,\n  ) {}\n\n  private pgClient = postgresClient.getChatwootConnection();\n\n  private async getProvider(instance: InstanceDto): Promise<ChatwootModel | null> {\n    const cacheKey = `${instance.instanceName}:getProvider`;\n    if (await this.cache.has(cacheKey)) {\n      const provider = (await this.cache.get(cacheKey)) as ChatwootModel;\n\n      return provider;\n    }\n\n    const provider = await this.waMonitor.waInstances[instance.instanceName]?.findChatwoot();\n\n    if (!provider) {\n      this.logger.warn('provider not found');\n      return null;\n    }\n\n    this.cache.set(cacheKey, provider);\n\n    return provider;\n  }\n\n  private async clientCw(instance: InstanceDto) {\n    const provider = await this.getProvider(instance);\n\n    if (!provider) {\n      this.logger.error('provider not found');\n      return null;\n    }\n\n    this.provider = provider;\n\n    const client = new ChatwootClient({\n      config: this.getClientCwConfig(),\n    });\n\n    return client;\n  }\n\n  public getClientCwConfig(): ChatwootAPIConfig & { nameInbox: string; mergeBrazilContacts: boolean } {\n    return {\n      basePath: this.provider.url,\n      with_credentials: true,\n      credentials: 'include',\n      token: this.provider.token,\n      nameInbox: this.provider.nameInbox,\n      mergeBrazilContacts: this.provider.mergeBrazilContacts,\n    };\n  }\n\n  public getCache() {\n    return this.cache;\n  }\n\n  public async create(instance: InstanceDto, data: ChatwootDto) {\n    await this.waMonitor.waInstances[instance.instanceName].setChatwoot(data);\n\n    if (data.autoCreate) {\n      this.logger.log('Auto create chatwoot instance');\n      const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n\n      await this.initInstanceChatwoot(\n        instance,\n        data.nameInbox ?? instance.instanceName.split('-cwId-')[0],\n        `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,\n        true,\n        data.number,\n        data.organization,\n        data.logo,\n      );\n    }\n    return data;\n  }\n\n  public async find(instance: InstanceDto): Promise<ChatwootDto> {\n    try {\n      return await this.waMonitor.waInstances[instance.instanceName].findChatwoot();\n    } catch {\n      this.logger.error('chatwoot not found');\n      return { enabled: null, url: '' };\n    }\n  }\n\n  public async getContact(instance: InstanceDto, id: number) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!id) {\n      this.logger.warn('id is required');\n      return null;\n    }\n\n    const contact = await client.contact.getContactable({\n      accountId: this.provider.accountId,\n      id,\n    });\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    return contact;\n  }\n\n  public async initInstanceChatwoot(\n    instance: InstanceDto,\n    inboxName: string,\n    webhookUrl: string,\n    qrcode: boolean,\n    number: string,\n    organization?: string,\n    logo?: string,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const findInbox: any = await client.inboxes.list({\n      accountId: this.provider.accountId,\n    });\n\n    const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName);\n\n    let inboxId: number;\n\n    this.logger.log('Creating chatwoot inbox');\n    if (!checkDuplicate) {\n      const data = {\n        type: 'api',\n        webhook_url: webhookUrl,\n      };\n\n      const inbox = await client.inboxes.create({\n        accountId: this.provider.accountId,\n        data: {\n          name: inboxName,\n          channel: data as any,\n        },\n      });\n\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      inboxId = inbox.id;\n    } else {\n      const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName);\n\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      inboxId = inbox.id;\n    }\n    this.logger.log(`Inbox created - inboxId: ${inboxId}`);\n\n    if (!this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT) {\n      this.logger.log('Chatwoot bot contact is disabled');\n\n      return true;\n    }\n\n    this.logger.log('Creating chatwoot bot contact');\n    const contact =\n      (await this.findContact(instance, '123456')) ||\n      ((await this.createContact(\n        instance,\n        '123456',\n        inboxId,\n        false,\n        organization ? organization : 'EvolutionAPI',\n        logo ? logo : 'https://evolution-api.com/files/evolution-api-favicon.png',\n      )) as any);\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const contactId = contact.id || contact.payload.contact.id;\n    this.logger.log(`Contact created - contactId: ${contactId}`);\n\n    if (qrcode) {\n      this.logger.log('QR code enabled');\n      const data = {\n        contact_id: contactId.toString(),\n        inbox_id: inboxId.toString(),\n      };\n\n      const conversation = await client.conversations.create({\n        accountId: this.provider.accountId,\n        data,\n      });\n\n      if (!conversation) {\n        this.logger.warn('conversation not found');\n        return null;\n      }\n\n      let contentMsg = 'init';\n\n      if (number) {\n        contentMsg = `init:${number}`;\n      }\n\n      const message = await client.messages.create({\n        accountId: this.provider.accountId,\n        conversationId: conversation.id,\n        data: {\n          content: contentMsg,\n          message_type: 'outgoing',\n        },\n      });\n\n      if (!message) {\n        this.logger.warn('conversation not found');\n        return null;\n      }\n      this.logger.log('Init message sent');\n    }\n\n    return true;\n  }\n\n  public async createContact(\n    instance: InstanceDto,\n    phoneNumber: string,\n    inboxId: number,\n    isGroup: boolean,\n    name?: string,\n    avatar_url?: string,\n    jid?: string,\n  ) {\n    try {\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      let data: any = {};\n      if (!isGroup) {\n        data = {\n          inbox_id: inboxId,\n          name: name || phoneNumber,\n          identifier: jid,\n          avatar_url: avatar_url,\n        };\n\n        if ((jid && jid.includes('@')) || !jid) {\n          data['phone_number'] = `+${phoneNumber}`;\n        }\n      } else {\n        data = {\n          inbox_id: inboxId,\n          name: name || phoneNumber,\n          identifier: phoneNumber,\n          avatar_url: avatar_url,\n        };\n      }\n\n      const contact = await client.contacts.create({\n        accountId: this.provider.accountId,\n        data,\n      });\n\n      if (!contact) {\n        this.logger.warn('contact not found');\n        return null;\n      }\n\n      const findContact = await this.findContact(instance, phoneNumber);\n\n      const contactId = findContact?.id;\n\n      await this.addLabelToContact(this.provider.nameInbox, contactId);\n\n      return contact;\n    } catch (error) {\n      if ((error.status === 422 || error.response?.status === 422) && jid) {\n        this.logger.warn(`Contact with identifier ${jid} creation failed (422). Checking if it already exists...`);\n        const existingContact = await this.findContactByIdentifier(instance, jid);\n        if (existingContact) {\n          const contactId = existingContact.id;\n          await this.addLabelToContact(this.provider.nameInbox, contactId);\n          return existingContact;\n        }\n      }\n\n      this.logger.error('Error creating contact');\n      console.log(error);\n      return null;\n    }\n  }\n\n  public async updateContact(instance: InstanceDto, id: number, data: any) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!id) {\n      this.logger.warn('id is required');\n      return null;\n    }\n\n    try {\n      const contact = await client.contacts.update({\n        accountId: this.provider.accountId,\n        id,\n        data,\n      });\n\n      return contact;\n    } catch {\n      return null;\n    }\n  }\n\n  public async addLabelToContact(nameInbox: string, contactId: number) {\n    try {\n      const uri = this.configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n      if (!uri) return false;\n\n      const sqlTags = `SELECT id, taggings_count FROM tags WHERE name = $1 LIMIT 1`;\n      const tagData = (await this.pgClient.query(sqlTags, [nameInbox]))?.rows[0];\n      let tagId = tagData?.id;\n      const taggingsCount = tagData?.taggings_count || 0;\n\n      const sqlTag = `INSERT INTO tags (name, taggings_count) \n                      VALUES ($1, $2) \n                      ON CONFLICT (name) \n                      DO UPDATE SET taggings_count = tags.taggings_count + 1 \n                      RETURNING id`;\n\n      tagId = (await this.pgClient.query(sqlTag, [nameInbox, taggingsCount + 1]))?.rows[0]?.id;\n\n      const sqlCheckTagging = `SELECT 1 FROM taggings \n                               WHERE tag_id = $1 AND taggable_type = 'Contact' AND taggable_id = $2 AND context = 'labels' LIMIT 1`;\n\n      const taggingExists = (await this.pgClient.query(sqlCheckTagging, [tagId, contactId]))?.rowCount > 0;\n\n      if (!taggingExists) {\n        const sqlInsertLabel = `INSERT INTO taggings (tag_id, taggable_type, taggable_id, context, created_at) \n                                VALUES ($1, 'Contact', $2, 'labels', NOW())`;\n\n        await this.pgClient.query(sqlInsertLabel, [tagId, contactId]);\n      }\n\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  public async findContactByIdentifier(instance: InstanceDto, identifier: string) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    // Direct search by query (q) - most common way to search by identifier/email/phone\n    const contact = (await (client as any).get('contacts/search', {\n      params: {\n        q: identifier,\n        sort: 'name',\n      },\n    })) as any;\n\n    if (contact && contact.data && contact.data.payload && contact.data.payload.length > 0) {\n      return contact.data.payload[0];\n    }\n\n    // Fallback for older API versions or different response structures\n    if (contact && contact.payload && contact.payload.length > 0) {\n      return contact.payload[0];\n    }\n\n    // Try search by attribute\n    const contactByAttr = (await (client as any).post('contacts/filter', {\n      payload: [\n        {\n          attribute_key: 'identifier',\n          filter_operator: 'equal_to',\n          values: [identifier],\n          query_operator: null,\n        },\n      ],\n    })) as any;\n\n    if (contactByAttr && contactByAttr.payload && contactByAttr.payload.length > 0) {\n      return contactByAttr.payload[0];\n    }\n\n    // Check inside data property if using axios interceptors wrapper\n    if (contactByAttr && contactByAttr.data && contactByAttr.data.payload && contactByAttr.data.payload.length > 0) {\n      return contactByAttr.data.payload[0];\n    }\n\n    return null;\n  }\n\n  public async findContact(instance: InstanceDto, phoneNumber: string) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    let query: any;\n    const isGroup = phoneNumber.includes('@g.us');\n\n    if (!isGroup) {\n      query = `+${phoneNumber}`;\n    } else {\n      query = phoneNumber;\n    }\n\n    let contact: any;\n\n    if (isGroup) {\n      contact = await client.contacts.search({\n        accountId: this.provider.accountId,\n        q: query,\n      });\n    } else {\n      contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/contacts/filter`,\n        body: {\n          payload: this.getFilterPayload(query),\n        },\n      });\n    }\n\n    if (!contact && contact?.payload?.length === 0) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    if (!isGroup) {\n      return contact.payload.length > 1 ? this.findContactInContactList(contact.payload, query) : contact.payload[0];\n    } else {\n      return contact.payload.find((contact) => contact.identifier === query);\n    }\n  }\n\n  private async mergeContacts(baseId: number, mergeId: number) {\n    try {\n      const contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/actions/contact_merge`,\n        body: {\n          base_contact_id: baseId,\n          mergee_contact_id: mergeId,\n        },\n      });\n\n      return contact;\n    } catch {\n      this.logger.error('Error merging contacts');\n      return null;\n    }\n  }\n\n  private async mergeBrazilianContacts(contacts: any[]) {\n    try {\n      const contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/actions/contact_merge`,\n        body: {\n          base_contact_id: contacts.find((contact) => contact.phone_number.length === 14)?.id,\n          mergee_contact_id: contacts.find((contact) => contact.phone_number.length === 13)?.id,\n        },\n      });\n\n      return contact;\n    } catch {\n      this.logger.error('Error merging contacts');\n      return null;\n    }\n  }\n\n  private findContactInContactList(contacts: any[], query: string) {\n    const phoneNumbers = this.getNumbers(query);\n    const searchableFields = this.getSearchableFields();\n\n    // eslint-disable-next-line prettier/prettier\n    if (contacts.length === 2 && this.getClientCwConfig().mergeBrazilContacts && query.startsWith('+55')) {\n      const contact = this.mergeBrazilianContacts(contacts);\n      if (contact) {\n        return contact;\n      }\n    }\n\n    const phone = phoneNumbers.reduce(\n      (savedNumber, number) => (number.length > savedNumber.length ? number : savedNumber),\n      '',\n    );\n\n    const contact_with9 = contacts.find((contact) => contact.phone_number === phone);\n    if (contact_with9) {\n      return contact_with9;\n    }\n\n    for (const contact of contacts) {\n      for (const field of searchableFields) {\n        if (contact[field] && phoneNumbers.includes(contact[field])) {\n          return contact;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  private getNumbers(query: string) {\n    const numbers = [];\n    numbers.push(query);\n\n    if (query.startsWith('+55') && query.length === 14) {\n      const withoutNine = query.slice(0, 5) + query.slice(6);\n      numbers.push(withoutNine);\n    } else if (query.startsWith('+55') && query.length === 13) {\n      const withNine = query.slice(0, 5) + '9' + query.slice(5);\n      numbers.push(withNine);\n    }\n\n    return numbers;\n  }\n\n  private getSearchableFields() {\n    return ['phone_number'];\n  }\n\n  private getFilterPayload(query: string) {\n    const filterPayload = [];\n\n    const numbers = this.getNumbers(query);\n    const fieldsToSearch = this.getSearchableFields();\n\n    fieldsToSearch.forEach((field, index1) => {\n      numbers.forEach((number, index2) => {\n        const queryOperator = fieldsToSearch.length - 1 === index1 && numbers.length - 1 === index2 ? null : 'OR';\n        filterPayload.push({\n          attribute_key: field,\n          filter_operator: 'equal_to',\n          values: [number.replace('+', '')],\n          query_operator: queryOperator,\n        });\n      });\n    });\n\n    return filterPayload;\n  }\n\n  public async createConversation(instance: InstanceDto, body: any) {\n    const isLid = body.key.addressingMode === 'lid';\n    const isGroup = body.key.remoteJid.endsWith('@g.us');\n    const phoneNumber = isLid && !isGroup ? body.key.remoteJidAlt : body.key.remoteJid;\n    const { remoteJid } = body.key;\n    const cacheKey = `${instance.instanceName}:createConversation-${remoteJid}`;\n    const lockKey = `${instance.instanceName}:lock:createConversation-${remoteJid}`;\n    const maxWaitTime = 5000; // 5 seconds\n    const client = await this.clientCw(instance);\n    if (!client) return null;\n\n    try {\n      // Processa atualização de contatos já criados @lid\n      if (phoneNumber && remoteJid && !isGroup) {\n        const contact = await this.findContact(instance, phoneNumber.split('@')[0]);\n        if (contact && contact.identifier !== remoteJid) {\n          this.logger.verbose(\n            `Identifier needs update: (contact.identifier: ${contact.identifier}, phoneNumber: ${phoneNumber}, body.key.remoteJidAlt: ${remoteJid}`,\n          );\n          const updateContact = await this.updateContact(instance, contact.id, {\n            identifier: phoneNumber,\n            phone_number: `+${phoneNumber.split('@')[0]}`,\n          });\n\n          if (updateContact === null) {\n            const baseContact = await this.findContact(instance, phoneNumber.split('@')[0]);\n            if (baseContact) {\n              await this.mergeContacts(baseContact.id, contact.id);\n              this.logger.verbose(\n                `Merge contacts: (${baseContact.id}) ${baseContact.phone_number} and (${contact.id}) ${contact.phone_number}`,\n              );\n            }\n          }\n        }\n      }\n      this.logger.verbose(`--- Start createConversation ---`);\n      this.logger.verbose(`Instance: ${JSON.stringify(instance)}`);\n\n      // If it already exists in the cache, return conversationId\n      if (await this.cache.has(cacheKey)) {\n        const conversationId = (await this.cache.get(cacheKey)) as number;\n        this.logger.verbose(`Found conversation to: ${phoneNumber}, conversation ID: ${conversationId}`);\n        let conversationExists: any;\n        try {\n          conversationExists = await client.conversations.get({\n            accountId: this.provider.accountId,\n            conversationId: conversationId,\n          });\n          this.logger.verbose(\n            `Conversation exists: ID: ${conversationExists.id} - Name: ${conversationExists.meta.sender.name} - Identifier: ${conversationExists.meta.sender.identifier}`,\n          );\n        } catch (error) {\n          this.logger.error(`Error getting conversation: ${error}`);\n          conversationExists = false;\n        }\n        if (!conversationExists) {\n          this.logger.verbose('Conversation does not exist, re-calling createConversation');\n          this.cache.delete(cacheKey);\n          return await this.createConversation(instance, body);\n        }\n        return conversationId;\n      }\n\n      // If lock already exists, wait until release or timeout\n      if (await this.cache.has(lockKey)) {\n        this.logger.verbose(`Operação de criação já em andamento para ${remoteJid}, aguardando resultado...`);\n        const start = Date.now();\n        while (await this.cache.has(lockKey)) {\n          if (Date.now() - start > maxWaitTime) {\n            this.logger.warn(`Timeout aguardando lock para ${remoteJid}`);\n            break;\n          }\n          await new Promise((res) => setTimeout(res, this.LOCK_POLLING_DELAY_MS));\n          if (await this.cache.has(cacheKey)) {\n            const conversationId = (await this.cache.get(cacheKey)) as number;\n            this.logger.verbose(`Resolves creation of: ${remoteJid}, conversation ID: ${conversationId}`);\n            return conversationId;\n          }\n        }\n      }\n\n      // Adquire lock\n      await this.cache.set(lockKey, true, 30);\n      this.logger.verbose(`Bloqueio adquirido para: ${lockKey}`);\n\n      try {\n        /*\n        Double check after lock\n        Utilizei uma nova verificação para evitar que outra thread execute entre o terminio do while e o set lock\n        */\n        if (await this.cache.has(cacheKey)) {\n          return (await this.cache.get(cacheKey)) as number;\n        }\n\n        const chatId = isGroup ? remoteJid : phoneNumber.split('@')[0].split(':')[0];\n        let nameContact = !body.key.fromMe ? body.pushName : chatId;\n        const filterInbox = await this.getInbox(instance);\n        if (!filterInbox) return null;\n\n        if (isGroup) {\n          this.logger.verbose(`Processing group conversation`);\n          const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId);\n          this.logger.verbose(`Group metadata: JID:${group.JID} - Subject:${group?.subject || group?.Name}`);\n\n          const participantJid = isLid && !body.key.fromMe ? body.key.participantAlt : body.key.participant;\n          nameContact = `${group.subject} (GROUP)`;\n\n          const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(\n            participantJid.split('@')[0],\n          );\n          this.logger.verbose(`Participant profile picture URL: ${JSON.stringify(picture_url)}`);\n\n          const findParticipant = await this.findContact(instance, participantJid.split('@')[0]);\n\n          if (findParticipant) {\n            this.logger.verbose(\n              `Found participant: ID:${findParticipant.id} - Name: ${findParticipant.name} - identifier: ${findParticipant.identifier}`,\n            );\n            if (!findParticipant.name || findParticipant.name === chatId) {\n              await this.updateContact(instance, findParticipant.id, {\n                name: body.pushName,\n                avatar_url: picture_url.profilePictureUrl || null,\n              });\n            }\n          } else {\n            await this.createContact(\n              instance,\n              participantJid.split('@')[0].split(':')[0],\n              filterInbox.id,\n              false,\n              body.pushName,\n              picture_url.profilePictureUrl || null,\n              participantJid,\n            );\n          }\n        }\n\n        const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId);\n        this.logger.verbose(`Contact profile picture URL: ${JSON.stringify(picture_url)}`);\n\n        this.logger.verbose(`Searching contact for: ${chatId}`);\n        let contact = await this.findContact(instance, chatId);\n\n        if (contact) {\n          this.logger.verbose(`Found contact: ID:${contact.id} - Name:${contact.name}`);\n          if (!body.key.fromMe) {\n            const waProfilePictureFile =\n              picture_url?.profilePictureUrl?.split('#')[0].split('?')[0].split('/').pop() || '';\n            const chatwootProfilePictureFile = contact?.thumbnail?.split('#')[0].split('?')[0].split('/').pop() || '';\n            const pictureNeedsUpdate = waProfilePictureFile !== chatwootProfilePictureFile;\n            const nameNeedsUpdate = !contact.name || contact.name === chatId;\n            this.logger.verbose(`Picture needs update: ${pictureNeedsUpdate}`);\n            this.logger.verbose(`Name needs update: ${nameNeedsUpdate}`);\n            if (pictureNeedsUpdate || nameNeedsUpdate) {\n              contact = await this.updateContact(instance, contact.id, {\n                ...(nameNeedsUpdate && { name: nameContact }),\n                ...(waProfilePictureFile === '' && { avatar: null }),\n                ...(pictureNeedsUpdate && { avatar_url: picture_url?.profilePictureUrl }),\n              });\n            }\n          }\n        } else {\n          contact = await this.createContact(\n            instance,\n            chatId,\n            filterInbox.id,\n            isGroup,\n            nameContact,\n            picture_url.profilePictureUrl || null,\n            phoneNumber,\n          );\n        }\n\n        if (!contact) {\n          this.logger.warn(`Contact not created or found`);\n          return null;\n        }\n\n        const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id;\n        this.logger.verbose(`Contact ID: ${contactId}`);\n\n        const contactConversations = (await client.contacts.listConversations({\n          accountId: this.provider.accountId,\n          id: contactId,\n        })) as any;\n\n        if (!contactConversations || !contactConversations.payload) {\n          this.logger.error(`No conversations found or payload is undefined`);\n          return null;\n        }\n\n        let inboxConversation = contactConversations.payload.find(\n          (conversation) => conversation.inbox_id == filterInbox.id,\n        );\n        if (inboxConversation) {\n          if (this.provider.reopenConversation) {\n            this.logger.verbose(\n              `Found conversation in reopenConversation mode: ID: ${inboxConversation.id} - Name: ${inboxConversation.meta.sender.name} - Identifier: ${inboxConversation.meta.sender.identifier}`,\n            );\n            if (inboxConversation && this.provider.conversationPending && inboxConversation.status !== 'open') {\n              await client.conversations.toggleStatus({\n                accountId: this.provider.accountId,\n                conversationId: inboxConversation.id,\n                data: {\n                  status: 'pending',\n                },\n              });\n            }\n          } else {\n            inboxConversation = contactConversations.payload.find(\n              (conversation) =>\n                conversation && conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id,\n            );\n            this.logger.verbose(`Found conversation: ${JSON.stringify(inboxConversation)}`);\n          }\n\n          if (inboxConversation) {\n            this.logger.verbose(`Returning existing conversation ID: ${inboxConversation.id}`);\n            this.cache.set(cacheKey, inboxConversation.id, 1800);\n            return inboxConversation.id;\n          }\n        }\n\n        const data = {\n          contact_id: contactId.toString(),\n          inbox_id: filterInbox.id.toString(),\n        };\n\n        if (this.provider.conversationPending) {\n          data['status'] = 'pending';\n        }\n\n        const conversation = await client.conversations.create({\n          accountId: this.provider.accountId,\n          data,\n        });\n\n        if (!conversation) {\n          this.logger.warn(`Conversation not created or found`);\n          return null;\n        }\n\n        this.logger.verbose(`New conversation created of ${remoteJid} with ID: ${conversation.id}`);\n        this.cache.set(cacheKey, conversation.id, 1800);\n        return conversation.id;\n      } finally {\n        await this.cache.delete(lockKey);\n        this.logger.verbose(`Block released for: ${lockKey}`);\n      }\n    } catch (error) {\n      this.logger.error(`Error in createConversation: ${error}`);\n      return null;\n    }\n  }\n\n  public async getInbox(instance: InstanceDto): Promise<inbox | null> {\n    const cacheKey = `${instance.instanceName}:getInbox`;\n    if (await this.cache.has(cacheKey)) {\n      return (await this.cache.get(cacheKey)) as inbox;\n    }\n\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const inbox = (await client.inboxes.list({\n      accountId: this.provider.accountId,\n    })) as any;\n\n    if (!inbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const findByName = inbox.payload.find((inbox) => inbox.name === this.getClientCwConfig().nameInbox);\n\n    if (!findByName) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    this.cache.set(cacheKey, findByName);\n    return findByName;\n  }\n\n  public async createMessage(\n    instance: InstanceDto,\n    conversationId: number,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    privateMessage?: boolean,\n    attachments?: {\n      content: unknown;\n      encoding: string;\n      filename: string;\n    }[],\n    messageBody?: any,\n    sourceId?: string,\n    quotedMsg?: MessageModel,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const replyToIds = await this.getReplyToIds(messageBody, instance);\n\n    const sourceReplyId = quotedMsg?.chatwootMessageId || null;\n\n    const message = await client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversationId,\n      data: {\n        content: content,\n        message_type: messageType,\n        attachments: attachments,\n        private: privateMessage || false,\n        source_id: sourceId,\n        content_attributes: {\n          ...replyToIds,\n        },\n        source_reply_id: sourceReplyId ? sourceReplyId.toString() : null,\n      },\n    });\n\n    if (!message) {\n      this.logger.warn('message not found');\n      return null;\n    }\n\n    return message;\n  }\n\n  public async getOpenConversationByContact(\n    instance: InstanceDto,\n    inbox: inbox,\n    contact: generic_id & contact,\n  ): Promise<conversation> {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const conversations = (await client.contacts.listConversations({\n      accountId: this.provider.accountId,\n      id: contact.id,\n    })) as any;\n\n    return (\n      conversations.payload.find(\n        (conversation) => conversation.inbox_id === inbox.id && conversation.status === 'open',\n      ) || undefined\n    );\n  }\n\n  public async createBotMessage(\n    instance: InstanceDto,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    attachments?: {\n      content: unknown;\n      encoding: string;\n      filename: string;\n    }[],\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const contact = await this.findContact(instance, '123456');\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const filterInbox = await this.getInbox(instance);\n\n    if (!filterInbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const conversation = await this.getOpenConversationByContact(instance, filterInbox, contact);\n\n    if (!conversation) {\n      this.logger.warn('conversation not found');\n      return;\n    }\n\n    const message = await client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversation.id,\n      data: {\n        content: content,\n        message_type: messageType,\n        attachments: attachments,\n      },\n    });\n\n    if (!message) {\n      this.logger.warn('message not found');\n      return null;\n    }\n\n    return message;\n  }\n\n  private async sendData(\n    conversationId: number,\n    fileStream: Readable,\n    fileName: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    content?: string,\n    instance?: InstanceDto,\n    messageBody?: any,\n    sourceId?: string,\n    quotedMsg?: MessageModel,\n  ) {\n    if (sourceId && this.isImportHistoryAvailable()) {\n      const messageAlreadySaved = await chatwootImport.getExistingSourceIds([sourceId], conversationId);\n      if (messageAlreadySaved) {\n        if (messageAlreadySaved.size > 0) {\n          this.logger.warn('Message already saved on chatwoot');\n          return null;\n        }\n      }\n    }\n    const data = new FormData();\n\n    if (content) {\n      data.append('content', content);\n    }\n\n    data.append('message_type', messageType);\n\n    data.append('attachments[]', fileStream, { filename: fileName });\n\n    const sourceReplyId = quotedMsg?.chatwootMessageId || null;\n\n    if (messageBody && instance) {\n      const replyToIds = await this.getReplyToIds(messageBody, instance);\n\n      if (replyToIds.in_reply_to || replyToIds.in_reply_to_external_id) {\n        const content = JSON.stringify({\n          ...replyToIds,\n        });\n        data.append('content_attributes', content);\n      }\n    }\n\n    if (sourceReplyId) {\n      data.append('source_reply_id', sourceReplyId.toString());\n    }\n\n    if (sourceId) {\n      data.append('source_id', sourceId);\n    }\n\n    const config = {\n      method: 'post',\n      maxBodyLength: Infinity,\n      url: `${this.provider.url}/api/v1/accounts/${this.provider.accountId}/conversations/${conversationId}/messages`,\n      headers: {\n        api_access_token: this.provider.token,\n        ...data.getHeaders(),\n      },\n      data: data,\n    };\n\n    try {\n      const { data } = await axios.request(config);\n\n      return data;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public async createBotQr(\n    instance: InstanceDto,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    fileStream?: Readable,\n    fileName?: string,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT) {\n      this.logger.log('Chatwoot bot contact is disabled');\n\n      return true;\n    }\n\n    const contact = await this.findContact(instance, '123456');\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const filterInbox = await this.getInbox(instance);\n\n    if (!filterInbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const conversation = await this.getOpenConversationByContact(instance, filterInbox, contact);\n\n    if (!conversation) {\n      this.logger.warn('conversation not found');\n      return;\n    }\n\n    const data = new FormData();\n\n    if (content) {\n      data.append('content', content);\n    }\n\n    data.append('message_type', messageType);\n\n    if (fileStream && fileName) {\n      data.append('attachments[]', fileStream, { filename: fileName });\n    }\n\n    const config = {\n      method: 'post',\n      maxBodyLength: Infinity,\n      url: `${this.provider.url}/api/v1/accounts/${this.provider.accountId}/conversations/${conversation.id}/messages`,\n      headers: {\n        api_access_token: this.provider.token,\n        ...data.getHeaders(),\n      },\n      data: data,\n    };\n\n    try {\n      const { data } = await axios.request(config);\n\n      return data;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public async sendAttachment(waInstance: any, number: string, media: any, caption?: string, options?: Options) {\n    try {\n      const parsedMedia = path.parse(decodeURIComponent(media));\n      let mimeType = mimeTypes.lookup(parsedMedia?.ext) || '';\n      let fileName = parsedMedia?.name + parsedMedia?.ext;\n\n      if (!mimeType) {\n        const parts = media.split('/');\n        fileName = decodeURIComponent(parts[parts.length - 1]);\n\n        const response = await axios.get(media, {\n          responseType: 'arraybuffer',\n        });\n        mimeType = response.headers['content-type'];\n      }\n\n      let type = 'document';\n\n      switch (mimeType.split('/')[0]) {\n        case 'image':\n          type = 'image';\n          break;\n        case 'video':\n          type = 'video';\n          break;\n        case 'audio':\n          type = 'audio';\n          break;\n        default:\n          type = 'document';\n          break;\n      }\n\n      if (type === 'audio') {\n        const data: SendAudioDto = {\n          number: number,\n          audio: media,\n          delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n          quoted: options?.quoted,\n        };\n\n        sendTelemetry('/message/sendWhatsAppAudio');\n\n        const messageSent = await waInstance?.audioWhatsapp(data, null, true);\n\n        return messageSent;\n      }\n\n      const documentExtensions = ['.gif', '.svg', '.tiff', '.tif', '.dxf', '.dwg'];\n      if (type === 'image' && parsedMedia && documentExtensions.includes(parsedMedia?.ext)) {\n        type = 'document';\n      }\n\n      const data: SendMediaDto = {\n        number: number,\n        mediatype: type as any,\n        fileName: fileName,\n        media: media,\n        delay: 1200,\n        quoted: options?.quoted,\n      };\n\n      sendTelemetry('/message/sendMedia');\n\n      if (caption) {\n        data.caption = caption;\n      }\n\n      const messageSent = await waInstance?.mediaMessage(data, null, true);\n\n      return messageSent;\n    } catch (error) {\n      this.logger.error(error);\n      throw error; // Re-throw para que o erro seja tratado pelo caller\n    }\n  }\n\n  public async onSendMessageError(instance: InstanceDto, conversation: number, error?: any) {\n    this.logger.verbose(`onSendMessageError ${JSON.stringify(error)}`);\n\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      return;\n    }\n\n    if (error && error?.status === 400 && error?.message[0]?.exists === false) {\n      client.messages.create({\n        accountId: this.provider.accountId,\n        conversationId: conversation,\n        data: {\n          content: `${i18next.t('cw.message.numbernotinwhatsapp')}`,\n          message_type: 'outgoing',\n          private: true,\n        },\n      });\n\n      return;\n    }\n\n    client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversation,\n      data: {\n        content: i18next.t('cw.message.notsent', {\n          error: error ? `_${error.toString()}_` : '',\n        }),\n        message_type: 'outgoing',\n        private: true,\n      },\n    });\n  }\n\n  public async receiveWebhook(instance: InstanceDto, body: any) {\n    try {\n      await new Promise((resolve) => setTimeout(resolve, 500));\n\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      if (\n        this.provider.reopenConversation === false &&\n        body.event === 'conversation_status_changed' &&\n        body.status === 'resolved' &&\n        body.meta?.sender?.identifier\n      ) {\n        const keyToDelete = `${instance.instanceName}:createConversation-${body.meta.sender.identifier}`;\n        this.cache.delete(keyToDelete);\n      }\n\n      if (\n        !body?.conversation ||\n        body.private ||\n        (body.event === 'message_updated' && !body.content_attributes?.deleted)\n      ) {\n        return { message: 'bot' };\n      }\n\n      const chatId =\n        body.conversation.meta.sender?.identifier || body.conversation.meta.sender?.phone_number.replace('+', '');\n      // Chatwoot to Whatsapp\n      const messageReceived = body.content\n        ? body.content\n            .replaceAll(/(?<!\\*)\\*((?!\\s)([^\\n*]+?)(?<!\\s))\\*(?!\\*)/g, '_$1_') // Substitui * por _\n            .replaceAll(/\\*{2}((?!\\s)([^\\n*]+?)(?<!\\s))\\*{2}/g, '*$1*') // Substitui ** por *\n            .replaceAll(/~{2}((?!\\s)([^\\n*]+?)(?<!\\s))~{2}/g, '~$1~') // Substitui ~~ por ~\n            .replaceAll(/(?<!`)`((?!\\s)([^`*]+?)(?<!\\s))`(?!`)/g, '```$1```') // Substitui ` por ```\n        : body.content;\n\n      const senderName = body?.conversation?.messages[0]?.sender?.available_name || body?.sender?.name;\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n      instance.instanceId = waInstance.instanceId;\n\n      if (body.event === 'message_updated' && body.content_attributes?.deleted) {\n        const message = await this.prismaRepository.message.findFirst({\n          where: {\n            chatwootMessageId: body.id,\n            instanceId: instance.instanceId,\n          },\n        });\n\n        if (message) {\n          const key = message.key as WAMessageKey;\n\n          await waInstance?.client.sendMessage(key.remoteJid, { delete: key });\n\n          await this.prismaRepository.message.deleteMany({\n            where: {\n              instanceId: instance.instanceId,\n              chatwootMessageId: body.id,\n            },\n          });\n        }\n        return { message: 'bot' };\n      }\n\n      const cwBotContact = this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT;\n\n      if (chatId === '123456' && body.message_type === 'outgoing') {\n        const command = messageReceived.replace('/', '');\n\n        if (cwBotContact && (command.includes('init') || command.includes('iniciar'))) {\n          const state = waInstance?.connectionStatus?.state;\n\n          if (state !== 'open') {\n            const number = command.split(':')[1];\n            await waInstance.connectToWhatsapp(number);\n          } else {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.alreadyConnected', {\n                inboxName: body.inbox.name,\n              }),\n              'incoming',\n            );\n          }\n        }\n\n        if (command === 'clearcache') {\n          waInstance.clearCacheChatwoot();\n          await this.createBotMessage(\n            instance,\n            i18next.t('cw.inbox.clearCache', {\n              inboxName: body.inbox.name,\n            }),\n            'incoming',\n          );\n        }\n\n        if (command === 'status') {\n          const state = waInstance?.connectionStatus?.state;\n\n          if (!state) {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.notFound', {\n                inboxName: body.inbox.name,\n              }),\n              'incoming',\n            );\n          }\n\n          if (state) {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.status', {\n                inboxName: body.inbox.name,\n                state: state,\n              }),\n              'incoming',\n            );\n          }\n        }\n\n        if (cwBotContact && (command === 'disconnect' || command === 'desconectar')) {\n          const msgLogout = i18next.t('cw.inbox.disconnect', {\n            inboxName: body.inbox.name,\n          });\n\n          await this.createBotMessage(instance, msgLogout, 'incoming');\n\n          await waInstance?.client?.logout('Log out instance: ' + instance.instanceName);\n          await waInstance?.client?.ws?.close();\n        }\n      }\n\n      if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') {\n        if (body?.conversation?.messages[0]?.source_id?.substring(0, 5) === 'WAID:') {\n          return { message: 'bot' };\n        }\n\n        if (!waInstance && body.conversation?.id) {\n          this.onSendMessageError(instance, body.conversation?.id, 'Instance not found');\n          return { message: 'bot' };\n        }\n\n        let formatText: string;\n        if (senderName === null || senderName === undefined) {\n          formatText = messageReceived;\n        } else {\n          const formattedDelimiter = this.provider.signDelimiter\n            ? this.provider.signDelimiter.replaceAll('\\\\n', '\\n')\n            : '\\n';\n          const textToConcat = this.provider.signMsg ? [`*${senderName}:*`] : [];\n          textToConcat.push(messageReceived);\n\n          formatText = textToConcat.join(formattedDelimiter);\n        }\n\n        for (const message of body.conversation.messages) {\n          if (message.attachments && message.attachments.length > 0) {\n            for (const attachment of message.attachments) {\n              if (!messageReceived) {\n                formatText = null;\n              }\n\n              const options: Options = {\n                quoted: await this.getQuotedMessage(body, instance),\n              };\n\n              const messageSent = await this.sendAttachment(\n                waInstance,\n                chatId,\n                attachment.data_url,\n                formatText,\n                options,\n              );\n              if (!messageSent && body.conversation?.id) {\n                this.onSendMessageError(instance, body.conversation?.id);\n              }\n\n              await this.updateChatwootMessageId(\n                {\n                  ...messageSent,\n                },\n                {\n                  messageId: body.id,\n                  inboxId: body.inbox?.id,\n                  conversationId: body.conversation?.id,\n                  contactInboxSourceId: body.conversation?.contact_inbox?.source_id,\n                },\n                instance,\n              );\n            }\n          } else {\n            const data: SendTextDto = {\n              number: chatId,\n              text: formatText,\n              delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n              quoted: await this.getQuotedMessage(body, instance),\n            };\n\n            sendTelemetry('/message/sendText');\n\n            let messageSent: any;\n            try {\n              messageSent = await waInstance?.textMessage(data, true);\n              if (!messageSent) {\n                throw new Error('Message not sent');\n              }\n\n              if (Long.isLong(messageSent?.messageTimestamp)) {\n                messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();\n              }\n\n              await this.updateChatwootMessageId(\n                {\n                  ...messageSent,\n                },\n                {\n                  messageId: body.id,\n                  inboxId: body.inbox?.id,\n                  conversationId: body.conversation?.id,\n                  contactInboxSourceId: body.conversation?.contact_inbox?.source_id,\n                },\n                instance,\n              );\n            } catch (error) {\n              if (!messageSent && body.conversation?.id) {\n                this.onSendMessageError(instance, body.conversation?.id, error);\n              }\n              throw error;\n            }\n          }\n        }\n\n        const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;\n        if (chatwootRead) {\n          const lastMessage = await this.prismaRepository.message.findFirst({\n            where: {\n              key: {\n                path: ['fromMe'],\n                equals: false,\n              },\n              instanceId: instance.instanceId,\n            },\n          });\n          if (lastMessage && !lastMessage.chatwootIsRead) {\n            const key = lastMessage.key as WAMessageKey;\n\n            waInstance?.markMessageAsRead({\n              readMessages: [\n                {\n                  id: key.id,\n                  fromMe: key.fromMe,\n                  remoteJid: key.remoteJid,\n                },\n              ],\n            });\n            const updateMessage = {\n              chatwootMessageId: lastMessage.chatwootMessageId,\n              chatwootConversationId: lastMessage.chatwootConversationId,\n              chatwootInboxId: lastMessage.chatwootInboxId,\n              chatwootContactInboxSourceId: lastMessage.chatwootContactInboxSourceId,\n              chatwootIsRead: true,\n            };\n\n            await this.prismaRepository.message.updateMany({\n              where: {\n                instanceId: instance.instanceId,\n                key: {\n                  path: ['id'],\n                  equals: key.id,\n                },\n              },\n              data: updateMessage,\n            });\n          }\n        }\n      }\n\n      if (body.message_type === 'template' && body.event === 'message_created') {\n        const data: SendTextDto = {\n          number: chatId,\n          text: body.content.replace(/\\\\\\r\\n|\\\\\\n|\\n/g, '\\n'),\n          delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n        };\n\n        sendTelemetry('/message/sendText');\n\n        await waInstance?.textMessage(data);\n      }\n\n      return { message: 'bot' };\n    } catch (error) {\n      this.logger.error(error);\n\n      return { message: 'bot' };\n    }\n  }\n\n  private async updateChatwootMessageId(\n    message: MessageModel,\n    chatwootMessageIds: ChatwootMessage,\n    instance: InstanceDto,\n  ) {\n    const key = message.key as WAMessageKey;\n\n    if (!chatwootMessageIds.messageId || !key?.id) {\n      return;\n    }\n\n    // Use raw SQL to avoid JSON path issues\n    const result = await this.prismaRepository.$executeRaw`\n      UPDATE \"Message\" \n      SET \n        \"chatwootMessageId\" = ${chatwootMessageIds.messageId},\n        \"chatwootConversationId\" = ${chatwootMessageIds.conversationId},\n        \"chatwootInboxId\" = ${chatwootMessageIds.inboxId},\n        \"chatwootContactInboxSourceId\" = ${chatwootMessageIds.contactInboxSourceId},\n        \"chatwootIsRead\" = ${chatwootMessageIds.isRead || false}\n      WHERE \"instanceId\" = ${instance.instanceId} \n      AND \"key\"->>'id' = ${key.id}\n    `;\n\n    this.logger.verbose(`Update result: ${result} rows affected`);\n\n    if (this.isImportHistoryAvailable()) {\n      try {\n        await chatwootImport.updateMessageSourceID(chatwootMessageIds.messageId, key.id);\n      } catch (error) {\n        this.logger.error(`Error updating Chatwoot message source ID: ${error}`);\n      }\n    }\n  }\n\n  private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> {\n    // Use raw SQL query to avoid JSON path issues with Prisma\n    const messages = await this.prismaRepository.$queryRaw`\n      SELECT * FROM \"Message\" \n      WHERE \"instanceId\" = ${instance.instanceId} \n      AND \"key\"->>'id' = ${keyId}\n      LIMIT 1\n    `;\n\n    return (messages as MessageModel[])[0] || null;\n  }\n\n  private async getReplyToIds(\n    msg: any,\n    instance: InstanceDto,\n  ): Promise<{ in_reply_to: string; in_reply_to_external_id: string }> {\n    let inReplyTo = null;\n    let inReplyToExternalId = null;\n\n    if (msg) {\n      inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId ?? msg.contextInfo?.stanzaId;\n      if (inReplyToExternalId) {\n        const message = await this.getMessageByKeyId(instance, inReplyToExternalId);\n        if (message?.chatwootMessageId) {\n          inReplyTo = message.chatwootMessageId;\n        }\n      }\n    }\n\n    return {\n      in_reply_to: inReplyTo,\n      in_reply_to_external_id: inReplyToExternalId,\n    };\n  }\n\n  private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {\n    if (msg?.content_attributes?.in_reply_to) {\n      const message = await this.prismaRepository.message.findFirst({\n        where: {\n          chatwootMessageId: msg?.content_attributes?.in_reply_to,\n          instanceId: instance.instanceId,\n        },\n      });\n\n      const key = message?.key as WAMessageKey;\n      const messageContent = message?.message as WAMessageContent;\n\n      if (messageContent && key?.id) {\n        return {\n          key: key,\n          message: messageContent,\n        };\n      }\n    }\n\n    return null;\n  }\n\n  private isMediaMessage(message: any) {\n    const media = [\n      'imageMessage',\n      'documentMessage',\n      'documentWithCaptionMessage',\n      'audioMessage',\n      'videoMessage',\n      'stickerMessage',\n      'viewOnceMessageV2',\n    ];\n\n    const messageKeys = Object.keys(message);\n\n    const result = messageKeys.some((key) => media.includes(key));\n\n    return result;\n  }\n\n  private isInteractiveButtonMessage(messageType: string, message: any) {\n    return messageType === 'interactiveMessage' && message.interactiveMessage?.nativeFlowMessage?.buttons?.length > 0;\n  }\n\n  private getAdsMessage(msg: any) {\n    interface AdsMessage {\n      title: string;\n      body: string;\n      thumbnailUrl: string;\n      sourceUrl: string;\n    }\n\n    const adsMessage: AdsMessage | undefined = {\n      title: msg.extendedTextMessage?.contextInfo?.externalAdReply?.title || msg.contextInfo?.externalAdReply?.title,\n      body: msg.extendedTextMessage?.contextInfo?.externalAdReply?.body || msg.contextInfo?.externalAdReply?.body,\n      thumbnailUrl:\n        msg.extendedTextMessage?.contextInfo?.externalAdReply?.thumbnailUrl ||\n        msg.contextInfo?.externalAdReply?.thumbnailUrl,\n      sourceUrl:\n        msg.extendedTextMessage?.contextInfo?.externalAdReply?.sourceUrl || msg.contextInfo?.externalAdReply?.sourceUrl,\n    };\n\n    return adsMessage;\n  }\n\n  private getReactionMessage(msg: any) {\n    interface ReactionMessage {\n      key: {\n        id: string;\n        fromMe: boolean;\n        remoteJid: string;\n        participant?: string;\n      };\n      text: string;\n    }\n    const reactionMessage: ReactionMessage | undefined = msg?.reactionMessage;\n\n    return reactionMessage;\n  }\n\n  private getTypeMessage(msg: any) {\n    const types = {\n      conversation: msg.conversation,\n      imageMessage: msg.imageMessage?.caption,\n      videoMessage: msg.videoMessage?.caption,\n      extendedTextMessage: msg.extendedTextMessage?.text,\n      messageContextInfo: msg.messageContextInfo?.stanzaId,\n      stickerMessage: undefined,\n      documentMessage: msg.documentMessage?.caption,\n      documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption,\n      audioMessage: msg.audioMessage ? (msg.audioMessage.caption ?? '') : undefined,\n      contactMessage: msg.contactMessage?.vcard,\n      contactsArrayMessage: msg.contactsArrayMessage,\n      locationMessage: msg.locationMessage,\n      liveLocationMessage: msg.liveLocationMessage,\n      listMessage: msg.listMessage,\n      listResponseMessage: msg.listResponseMessage,\n      viewOnceMessageV2:\n        msg?.message?.viewOnceMessageV2?.message?.imageMessage?.url ||\n        msg?.message?.viewOnceMessageV2?.message?.videoMessage?.url ||\n        msg?.message?.viewOnceMessageV2?.message?.audioMessage?.url,\n    };\n\n    return types;\n  }\n\n  private getMessageContent(types: any) {\n    const typeKey = Object.keys(types).find((key) => types[key] !== undefined);\n\n    let result = typeKey ? types[typeKey] : undefined;\n\n    // Remove externalAdReplyBody| in Chatwoot (Already Have)\n    if (result && typeof result === 'string' && result.includes('externalAdReplyBody|')) {\n      result = result.split('externalAdReplyBody|').filter(Boolean).join('');\n    }\n\n    if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') {\n      const latitude = result.degreesLatitude;\n      const longitude = result.degreesLongitude;\n\n      const locationName = result?.name;\n      const locationAddress = result?.address;\n\n      const formattedLocation =\n        `*${i18next.t('cw.locationMessage.location')}:*\\n\\n` +\n        `_${i18next.t('cw.locationMessage.latitude')}:_ ${latitude} \\n` +\n        `_${i18next.t('cw.locationMessage.longitude')}:_ ${longitude} \\n` +\n        (locationName ? `_${i18next.t('cw.locationMessage.locationName')}:_ ${locationName}\\n` : '') +\n        (locationAddress ? `_${i18next.t('cw.locationMessage.locationAddress')}:_ ${locationAddress} \\n` : '') +\n        `_${i18next.t('cw.locationMessage.locationUrl')}:_ ` +\n        `https://www.google.com/maps/search/?api=1&query=${latitude},${longitude}`;\n\n      return formattedLocation;\n    }\n\n    if (typeKey === 'contactMessage') {\n      const vCardData = result.split('\\n');\n      const contactInfo = {};\n\n      vCardData.forEach((line) => {\n        const [key, value] = line.split(':');\n        if (key && value) {\n          contactInfo[key] = value;\n        }\n      });\n\n      let formattedContact =\n        `*${i18next.t('cw.contactMessage.contact')}:*\\n\\n` +\n        `_${i18next.t('cw.contactMessage.name')}:_ ${contactInfo['FN']}`;\n\n      let numberCount = 1;\n      Object.keys(contactInfo).forEach((key) => {\n        if (key.startsWith('item') && key.includes('TEL')) {\n          const phoneNumber = contactInfo[key];\n          formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n          numberCount++;\n        } else if (key.includes('TEL')) {\n          const phoneNumber = contactInfo[key];\n          formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n          numberCount++;\n        }\n      });\n\n      return formattedContact;\n    }\n\n    if (typeKey === 'contactsArrayMessage') {\n      const formattedContacts = result.contacts.map((contact) => {\n        const vCardData = contact.vcard.split('\\n');\n        const contactInfo = {};\n\n        vCardData.forEach((line) => {\n          const [key, value] = line.split(':');\n          if (key && value) {\n            contactInfo[key] = value;\n          }\n        });\n\n        let formattedContact = `*${i18next.t('cw.contactMessage.contact')}:*\\n\\n_${i18next.t(\n          'cw.contactMessage.name',\n        )}:_ ${contact.displayName}`;\n\n        let numberCount = 1;\n        Object.keys(contactInfo).forEach((key) => {\n          if (key.startsWith('item') && key.includes('TEL')) {\n            const phoneNumber = contactInfo[key];\n            formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n            numberCount++;\n          } else if (key.includes('TEL')) {\n            const phoneNumber = contactInfo[key];\n            formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n            numberCount++;\n          }\n        });\n\n        return formattedContact;\n      });\n\n      const formattedContactsArray = formattedContacts.join('\\n\\n');\n\n      return formattedContactsArray;\n    }\n\n    if (typeKey === 'listMessage') {\n      const listTitle = result?.title || 'Unknown';\n      const listDescription = result?.description || 'Unknown';\n      const listFooter = result?.footerText || 'Unknown';\n\n      let formattedList =\n        '*List Menu:*\\n\\n' +\n        '_Title_: ' +\n        listTitle +\n        '\\n' +\n        '_Description_: ' +\n        listDescription +\n        '\\n' +\n        '_Footer_: ' +\n        listFooter;\n\n      if (result.sections && result.sections.length > 0) {\n        result.sections.forEach((section, sectionIndex) => {\n          formattedList += '\\n\\n*Section ' + (sectionIndex + 1) + ':* ' + section.title || 'Unknown\\n';\n\n          if (section.rows && section.rows.length > 0) {\n            section.rows.forEach((row, rowIndex) => {\n              formattedList += '\\n*Line ' + (rowIndex + 1) + ':*\\n';\n              formattedList += '_▪️ Title:_ ' + (row.title || 'Unknown') + '\\n';\n              formattedList += '_▪️ Description:_ ' + (row.description || 'Unknown') + '\\n';\n              formattedList += '_▪️ ID:_ ' + (row.rowId || 'Unknown') + '\\n';\n            });\n          } else {\n            formattedList += '\\nNo lines found in this section.\\n';\n          }\n        });\n      } else {\n        formattedList += '\\nNo sections found.\\n';\n      }\n\n      return formattedList;\n    }\n\n    if (typeKey === 'listResponseMessage') {\n      const responseTitle = result?.title || 'Unknown';\n      const responseDescription = result?.description || 'Unknown';\n      const responseRowId = result?.singleSelectReply?.selectedRowId || 'Unknown';\n\n      const formattedResponseList =\n        '*List Response:*\\n\\n' +\n        '_Title_: ' +\n        responseTitle +\n        '\\n' +\n        '_Description_: ' +\n        responseDescription +\n        '\\n' +\n        '_ID_: ' +\n        responseRowId;\n      return formattedResponseList;\n    }\n\n    return result;\n  }\n\n  public getConversationMessage(msg: any) {\n    const types = this.getTypeMessage(msg);\n\n    const messageContent = this.getMessageContent(types);\n\n    return messageContent;\n  }\n\n  public async eventWhatsapp(event: string, instance: InstanceDto, body: any) {\n    try {\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n\n      if (!waInstance) {\n        this.logger.warn('wa instance not found');\n        return null;\n      }\n\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      if (this.provider?.ignoreJids && this.provider?.ignoreJids.length > 0) {\n        const ignoreJids: any = this.provider?.ignoreJids;\n\n        let ignoreGroups = false;\n        let ignoreContacts = false;\n\n        if (ignoreJids.includes('@g.us')) {\n          ignoreGroups = true;\n        }\n\n        if (ignoreJids.includes('@s.whatsapp.net')) {\n          ignoreContacts = true;\n        }\n\n        if (ignoreGroups && body?.key?.remoteJid.endsWith('@g.us')) {\n          this.logger.warn('Ignoring message from group: ' + body?.key?.remoteJid);\n          return;\n        }\n\n        if (ignoreContacts && body?.key?.remoteJid.endsWith('@s.whatsapp.net')) {\n          this.logger.warn('Ignoring message from contact: ' + body?.key?.remoteJid);\n          return;\n        }\n\n        if (ignoreJids.includes(body?.key?.remoteJid)) {\n          this.logger.warn('Ignoring message from jid: ' + body?.key?.remoteJid);\n          return;\n        }\n      }\n\n      if (event === 'messages.upsert' || event === 'send.message') {\n        this.logger.info(`[${event}] New message received - Instance: ${JSON.stringify(body, null, 2)}`);\n        if (body.key.remoteJid === 'status@broadcast') {\n          return;\n        }\n\n        if (body.message?.ephemeralMessage?.message) {\n          body.message = {\n            ...body.message?.ephemeralMessage?.message,\n          };\n        }\n\n        const originalMessage = await this.getConversationMessage(body.message);\n        const bodyMessage = originalMessage\n          ? originalMessage\n              .replaceAll(/\\*((?!\\s)([^\\n*]+?)(?<!\\s))\\*/g, '**$1**')\n              .replaceAll(/_((?!\\s)([^\\n_]+?)(?<!\\s))_/g, '*$1*')\n              .replaceAll(/~((?!\\s)([^\\n~]+?)(?<!\\s))~/g, '~~$1~~')\n          : originalMessage;\n\n        if (bodyMessage && bodyMessage.includes('/survey/responses/') && bodyMessage.includes('http')) {\n          return;\n        }\n\n        const quotedId = body.contextInfo?.stanzaId || body.message?.contextInfo?.stanzaId;\n\n        let quotedMsg = null;\n\n        if (quotedId)\n          quotedMsg = await this.prismaRepository.message.findFirst({\n            where: {\n              key: {\n                path: ['id'],\n                equals: quotedId,\n              },\n              chatwootMessageId: {\n                not: null,\n              },\n            },\n          });\n\n        const isMedia = this.isMediaMessage(body.message);\n\n        const adsMessage = this.getAdsMessage(body);\n\n        const reactionMessage = this.getReactionMessage(body.message);\n        const isInteractiveButtonMessage = this.isInteractiveButtonMessage(body.messageType, body.message);\n\n        if (!bodyMessage && !isMedia && !reactionMessage && !isInteractiveButtonMessage) {\n          this.logger.warn('no body message found');\n          return;\n        }\n\n        const getConversation = await this.createConversation(instance, body);\n\n        if (!getConversation) {\n          this.logger.warn('conversation not found');\n          return;\n        }\n\n        const messageType = body.key.fromMe ? 'outgoing' : 'incoming';\n\n        if (isMedia) {\n          const downloadBase64 = await waInstance?.getBase64FromMediaMessage({\n            message: {\n              ...body,\n            },\n          });\n\n          let nameFile: string;\n          const messageBody = body?.message[body?.messageType];\n          const originalFilename =\n            messageBody?.fileName || messageBody?.filename || messageBody?.message?.documentMessage?.fileName;\n          if (originalFilename) {\n            const parsedFile = path.parse(originalFilename);\n            if (parsedFile.name && parsedFile.ext) {\n              nameFile = `${parsedFile.name}-${Math.floor(Math.random() * (99 - 10 + 1) + 10)}${parsedFile.ext}`;\n            }\n          }\n\n          if (!nameFile) {\n            nameFile = `${Math.random().toString(36).substring(7)}.${mimeTypes.extension(downloadBase64.mimetype) || ''}`;\n          }\n\n          const fileData = Buffer.from(downloadBase64.base64, 'base64');\n\n          const fileStream = new Readable();\n          fileStream._read = () => {};\n          fileStream.push(fileData);\n          fileStream.push(null);\n\n          if (body.key.remoteJid.includes('@g.us')) {\n            const participantName = body.pushName;\n            const rawPhoneNumber =\n              body.key.addressingMode === 'lid' && !body.key.fromMe && body.key.participantAlt\n                ? body.key.participantAlt.split('@')[0].split(':')[0]\n                : body.key.participant.split('@')[0].split(':')[0];\n            const formattedPhoneNumber = parsePhoneNumberFromString(`+${rawPhoneNumber}`).formatInternational();\n\n            let content: string;\n\n            if (!body.key.fromMe) {\n              content = bodyMessage\n                ? `**${formattedPhoneNumber} - ${participantName}:**\\n\\n${bodyMessage}`\n                : `**${formattedPhoneNumber} - ${participantName}:**`;\n            } else {\n              content = bodyMessage || '';\n            }\n\n            const send = await this.sendData(\n              getConversation,\n              fileStream,\n              nameFile,\n              messageType,\n              content,\n              instance,\n              body,\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n\n            return send;\n          } else {\n            const send = await this.sendData(\n              getConversation,\n              fileStream,\n              nameFile,\n              messageType,\n              bodyMessage,\n              instance,\n              body,\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n\n            return send;\n          }\n        }\n\n        if (reactionMessage) {\n          if (reactionMessage.text) {\n            const send = await this.createMessage(\n              instance,\n              getConversation,\n              reactionMessage.text,\n              messageType,\n              false,\n              [],\n              {\n                message: { extendedTextMessage: { contextInfo: { stanzaId: reactionMessage.key.id } } },\n              },\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n          }\n\n          return;\n        }\n\n        if (isInteractiveButtonMessage) {\n          const buttons = body.message.interactiveMessage.nativeFlowMessage.buttons;\n          this.logger.info('is Interactive Button Message: ' + JSON.stringify(buttons));\n\n          for (const button of buttons) {\n            const buttonParams = JSON.parse(button.buttonParamsJson);\n            const paymentSettings = buttonParams.payment_settings;\n\n            if (button.name === 'payment_info' && paymentSettings[0].type === 'pix_static_code') {\n              const pixSettings = paymentSettings[0].pix_static_code;\n              const pixKeyType = (() => {\n                switch (pixSettings.key_type) {\n                  case 'EVP':\n                    return 'Chave Aleatória';\n                  case 'EMAIL':\n                    return 'E-mail';\n                  case 'PHONE':\n                    return 'Telefone';\n                  default:\n                    return pixSettings.key_type;\n                }\n              })();\n              const pixKey = pixSettings.key_type === 'PHONE' ? pixSettings.key.replace('+55', '') : pixSettings.key;\n              const content = `*${pixSettings.merchant_name}*\\nChave PIX: ${pixKey} (${pixKeyType})`;\n\n              const send = await this.createMessage(\n                instance,\n                getConversation,\n                content,\n                messageType,\n                false,\n                [],\n                body,\n                'WAID:' + body.key.id,\n                quotedMsg,\n              );\n              if (!send) this.logger.warn('message not sent');\n            } else {\n              this.logger.warn('Interactive Button Message not mapped');\n            }\n          }\n          return;\n        }\n\n        const isAdsMessage = (adsMessage && adsMessage.title) || adsMessage.body || adsMessage.thumbnailUrl;\n        if (isAdsMessage) {\n          const imgBuffer = await axios.get(adsMessage.thumbnailUrl, { responseType: 'arraybuffer' });\n\n          const extension = mimeTypes.extension(imgBuffer.headers['content-type']);\n          const mimeType = extension && mimeTypes.lookup(extension);\n\n          if (!mimeType) {\n            this.logger.warn('mimetype of Ads message not found');\n            return;\n          }\n\n          const random = Math.random().toString(36).substring(7);\n          const nameFile = `${random}.${mimeTypes.extension(mimeType)}`;\n          const fileData = Buffer.from(imgBuffer.data, 'binary');\n\n          const img = await Jimp.read(fileData);\n          await img.cover({\n            w: 320,\n            h: 180,\n          });\n          const processedBuffer = await img.getBuffer(JimpMime.png);\n\n          const fileStream = new Readable();\n          fileStream._read = () => {}; // _read is required but you can noop it\n          fileStream.push(processedBuffer);\n          fileStream.push(null);\n\n          const truncStr = (str: string, len: number) => {\n            if (!str) return '';\n\n            return str.length > len ? str.substring(0, len) + '...' : str;\n          };\n\n          const title = truncStr(adsMessage.title, 40);\n          const description = truncStr(adsMessage?.body, 75);\n\n          const send = await this.sendData(\n            getConversation,\n            fileStream,\n            nameFile,\n            messageType,\n            `${bodyMessage}\\n\\n\\n**${title}**\\n${description}\\n${adsMessage.sourceUrl}`,\n            instance,\n            body,\n            'WAID:' + body.key.id,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        }\n\n        if (body.key.remoteJid.includes('@g.us')) {\n          const participantName = body.pushName;\n          const rawPhoneNumber =\n            body.key.addressingMode === 'lid' && !body.key.fromMe && body.key.participantAlt\n              ? body.key.participantAlt.split('@')[0].split(':')[0]\n              : body.key.participant.split('@')[0].split(':')[0];\n          const formattedPhoneNumber = parsePhoneNumberFromString(`+${rawPhoneNumber}`).formatInternational();\n\n          let content: string;\n\n          if (!body.key.fromMe) {\n            content = `**${formattedPhoneNumber} - ${participantName}:**\\n\\n${bodyMessage}`;\n          } else {\n            content = `${bodyMessage}`;\n          }\n\n          const send = await this.createMessage(\n            instance,\n            getConversation,\n            content,\n            messageType,\n            false,\n            [],\n            body,\n            'WAID:' + body.key.id,\n            quotedMsg,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        } else {\n          const send = await this.createMessage(\n            instance,\n            getConversation,\n            bodyMessage,\n            messageType,\n            false,\n            [],\n            body,\n            'WAID:' + body.key.id,\n            quotedMsg,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        }\n      }\n\n      if (event === Events.MESSAGES_DELETE) {\n        const chatwootDelete = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_DELETE;\n\n        if (chatwootDelete === true) {\n          if (!body?.key?.id) {\n            this.logger.warn('message id not found');\n            return;\n          }\n\n          const message = await this.getMessageByKeyId(instance, body.key.id);\n\n          if (message?.chatwootMessageId && message?.chatwootConversationId) {\n            await this.prismaRepository.message.deleteMany({\n              where: {\n                key: {\n                  path: ['id'],\n                  equals: body.key.id,\n                },\n                instanceId: instance.instanceId,\n              },\n            });\n\n            return await client.messages.delete({\n              accountId: this.provider.accountId,\n              conversationId: message.chatwootConversationId,\n              messageId: message.chatwootMessageId,\n            });\n          }\n        }\n      }\n\n      if (event === 'messages.edit' || event === 'send.message.update') {\n        const editedMessageContentRaw =\n          body?.editedMessage?.conversation ??\n          body?.editedMessage?.extendedTextMessage?.text ??\n          body?.editedMessage?.imageMessage?.caption ??\n          body?.editedMessage?.videoMessage?.caption ??\n          body?.editedMessage?.documentMessage?.caption ??\n          (typeof body?.text === 'string' ? body.text : undefined);\n\n        const editedMessageContent = (editedMessageContentRaw ?? '').trim();\n\n        if (!editedMessageContent) {\n          this.logger.info('[CW.EDIT] Conteúdo vazio — ignorando (DELETE tratará se for revoke).');\n          return;\n        }\n\n        const message = await this.getMessageByKeyId(instance, body?.key?.id);\n\n        if (!message) {\n          this.logger.warn('Message not found for edit event');\n          return;\n        }\n\n        const key = message.key as WAMessageKey;\n\n        const messageType = key?.fromMe ? 'outgoing' : 'incoming';\n\n        if (message && message.chatwootConversationId && message.chatwootMessageId) {\n          // Criar nova mensagem com formato: \"Mensagem editada:\\n\\nteste1\"\n          const editedText = `\\n\\n\\`${i18next.t('cw.message.edited')}:\\`\\n\\n${editedMessageContent}`;\n\n          const send = await this.createMessage(\n            instance,\n            message.chatwootConversationId,\n            editedText,\n            messageType,\n            false,\n            [],\n            {\n              message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } },\n            },\n            'WAID:' + body.key.id,\n            null,\n          );\n          if (!send) {\n            this.logger.warn('edited message not sent');\n            return;\n          }\n        }\n        return;\n      }\n\n      if (event === 'messages.read') {\n        if (!body?.key?.id || !body?.key?.remoteJid) {\n          this.logger.warn('message id not found');\n          return;\n        }\n\n        const message = await this.getMessageByKeyId(instance, body.key.id);\n        const conversationId = message?.chatwootConversationId;\n        const contactInboxSourceId = message?.chatwootContactInboxSourceId;\n\n        if (conversationId) {\n          let sourceId = contactInboxSourceId;\n          const inbox = (await this.getInbox(instance)) as inbox & {\n            inbox_identifier?: string;\n          };\n\n          if (!sourceId && inbox) {\n            const conversation = (await client.conversations.get({\n              accountId: this.provider.accountId,\n              conversationId: conversationId,\n            })) as conversation_show & {\n              last_non_activity_message: { conversation: { contact_inbox: contact_inboxes } };\n            };\n            sourceId = conversation.last_non_activity_message?.conversation?.contact_inbox?.source_id;\n          }\n\n          if (sourceId && inbox?.inbox_identifier) {\n            const url =\n              `/public/api/v1/inboxes/${inbox.inbox_identifier}/contacts/${sourceId}` +\n              `/conversations/${conversationId}/update_last_seen`;\n            await chatwootRequest(this.getClientCwConfig(), {\n              method: 'POST',\n              url: url,\n            });\n          }\n        }\n        return;\n      }\n\n      if (event === 'status.instance') {\n        const data = body;\n        const inbox = await this.getInbox(instance);\n\n        if (!inbox) {\n          this.logger.warn('inbox not found');\n          return;\n        }\n\n        const msgStatus = i18next.t('cw.inbox.status', {\n          inboxName: inbox.name,\n          state: data.status,\n        });\n\n        await this.createBotMessage(instance, msgStatus, 'incoming');\n      }\n\n      if (event === 'connection.update' && body.status === 'open') {\n        const waInstance = this.waMonitor.waInstances[instance.instanceName];\n        if (!waInstance) return;\n\n        const now = Date.now();\n        const timeSinceLastNotification = now - (waInstance.lastConnectionNotification || 0);\n\n        // Se a conexão foi estabelecida via QR code, notifica imediatamente.\n        if (waInstance.qrCode && waInstance.qrCode.count > 0) {\n          const msgConnection = i18next.t('cw.inbox.connected');\n          await this.createBotMessage(instance, msgConnection, 'incoming');\n          waInstance.qrCode.count = 0;\n          waInstance.lastConnectionNotification = now;\n          chatwootImport.clearAll(instance);\n        }\n        // Se não foi via QR code, verifica o throttling.\n        else if (timeSinceLastNotification >= 30000) {\n          const msgConnection = i18next.t('cw.inbox.connected');\n          await this.createBotMessage(instance, msgConnection, 'incoming');\n          waInstance.lastConnectionNotification = now;\n        } else {\n          this.logger.warn(\n            `Connection notification skipped for ${instance.instanceName} - too frequent (${timeSinceLastNotification}ms since last)`,\n          );\n        }\n      }\n\n      if (event === 'qrcode.updated') {\n        if (body.statusCode === 500) {\n          const erroQRcode = `🚨 ${i18next.t('qrlimitreached')}`;\n          return await this.createBotMessage(instance, erroQRcode, 'incoming');\n        } else {\n          const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64');\n\n          const fileStream = new Readable();\n          fileStream._read = () => {};\n          fileStream.push(fileData);\n          fileStream.push(null);\n\n          await this.createBotQr(\n            instance,\n            i18next.t('qrgeneratedsuccesfully'),\n            'incoming',\n            fileStream,\n            `${instance.instanceName}.png`,\n          );\n\n          let msgQrCode = `⚡️${i18next.t('qrgeneratedsuccesfully')}\\n\\n${i18next.t('scanqr')}`;\n\n          if (body?.qrcode?.pairingCode) {\n            msgQrCode =\n              msgQrCode +\n              `\\n\\n*Pairing Code:* ${body.qrcode.pairingCode.substring(0, 4)}-${body.qrcode.pairingCode.substring(\n                4,\n                8,\n              )}`;\n          }\n\n          await this.createBotMessage(instance, msgQrCode, 'incoming');\n        }\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public normalizeJidIdentifier(remoteJid: string) {\n    if (!remoteJid) {\n      return '';\n    }\n    if (remoteJid.includes('@lid')) {\n      return remoteJid;\n    }\n    return remoteJid.replace(/:\\d+/, '').split('@')[0];\n  }\n\n  public startImportHistoryMessages(instance: InstanceDto) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    this.createBotMessage(instance, i18next.t('cw.import.startImport'), 'incoming');\n  }\n\n  public isImportHistoryAvailable() {\n    const uri = this.configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n    return uri && uri !== 'postgres://user:password@hostname:port/dbname';\n  }\n\n  public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageModel[]) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    chatwootImport.addHistoryMessages(instance, messagesRaw);\n  }\n\n  public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactModel[]) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    return chatwootImport.addHistoryContacts(instance, contactsRaw);\n  }\n\n  public async importHistoryMessages(instance: InstanceDto) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    this.createBotMessage(instance, i18next.t('cw.import.importingMessages'), 'incoming');\n\n    const totalMessagesImported = await chatwootImport.importHistoryMessages(\n      instance,\n      this,\n      await this.getInbox(instance),\n      this.provider,\n    );\n    this.updateContactAvatarInRecentConversations(instance);\n\n    const msg = Number.isInteger(totalMessagesImported)\n      ? i18next.t('cw.import.messagesImported', { totalMessagesImported })\n      : i18next.t('cw.import.messagesException');\n\n    this.createBotMessage(instance, msg, 'incoming');\n\n    return totalMessagesImported;\n  }\n\n  public async updateContactAvatarInRecentConversations(instance: InstanceDto, limitContacts = 100) {\n    try {\n      if (!this.isImportHistoryAvailable()) {\n        return;\n      }\n\n      const client = await this.clientCw(instance);\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      const inbox = await this.getInbox(instance);\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      const recentContacts = await chatwootImport.getContactsOrderByRecentConversations(\n        inbox,\n        this.provider,\n        limitContacts,\n      );\n\n      const contactIdentifiers = recentContacts\n        .map((contact) => contact.identifier)\n        .filter((identifier) => identifier !== null);\n\n      const contactsWithProfilePicture = (\n        await this.prismaRepository.contact.findMany({\n          where: {\n            instanceId: instance.instanceId,\n            id: {\n              in: contactIdentifiers,\n            },\n            profilePicUrl: {\n              not: null,\n            },\n          },\n        })\n      ).reduce((acc: Map<string, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());\n\n      recentContacts.forEach(async (contact) => {\n        if (contactsWithProfilePicture.has(contact.identifier)) {\n          client.contacts.update({\n            accountId: this.provider.accountId,\n            id: contact.id,\n            data: {\n              avatar_url: contactsWithProfilePicture.get(contact.identifier).profilePictureUrl || null,\n            },\n          });\n        }\n      });\n    } catch (error) {\n      this.logger.error(`Error on update avatar in recent conversations: ${error.toString()}`);\n    }\n  }\n\n  public async syncLostMessages(\n    instance: InstanceDto,\n    chatwootConfig: ChatwootDto,\n    prepareMessage: (message: any) => any,\n  ) {\n    try {\n      if (!this.isImportHistoryAvailable()) {\n        return;\n      }\n      if (!this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) {\n        return;\n      }\n\n      const inbox = await this.getInbox(instance);\n\n      const sqlMessages = `select * from messages m\n      where account_id = ${chatwootConfig.accountId}\n      and inbox_id = ${inbox.id}\n      and created_at >= now() - interval '6h'\n      order by created_at desc`;\n\n      const messagesData = (await this.pgClient.query(sqlMessages))?.rows;\n      const ids: string[] = messagesData\n        .filter((message) => !!message.source_id)\n        .map((message) => message.source_id.replace('WAID:', ''));\n\n      const savedMessages = await this.prismaRepository.message.findMany({\n        where: {\n          Instance: { name: instance.instanceName },\n          messageTimestamp: { gte: Number(dayjs().subtract(6, 'hours').unix()) },\n          AND: ids.map((id) => ({ key: { path: ['id'], not: id } })),\n        },\n      });\n\n      const filteredMessages = savedMessages.filter(\n        (msg: any) => !chatwootImport.isIgnorePhoneNumber(msg.key?.remoteJid),\n      );\n      const messagesRaw: any[] = [];\n      for (const m of filteredMessages) {\n        if (!m.message || !m.key || !m.messageTimestamp) {\n          continue;\n        }\n\n        if (Long.isLong(m?.messageTimestamp)) {\n          m.messageTimestamp = m.messageTimestamp?.toNumber();\n        }\n\n        messagesRaw.push(prepareMessage(m as any));\n      }\n\n      this.addHistoryMessages(\n        instance,\n        messagesRaw.filter((msg) => !chatwootImport.isIgnorePhoneNumber(msg.key?.remoteJid)),\n      );\n\n      await chatwootImport.importHistoryMessages(instance, this, inbox, this.provider);\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n      waInstance.clearCacheChatwoot();\n    } catch {\n      return;\n    }\n  }\n}\n","import { ConfigService, Language } from '@config/env.config';\nimport fs from 'fs';\nimport i18next from 'i18next';\nimport path from 'path';\n\nconst languages = ['en', 'pt-BR', 'es'];\nconst translationsPath = path.join(__dirname, 'translations');\nconst configService: ConfigService = new ConfigService();\n\nconst resources: any = {};\n\nlanguages.forEach((language) => {\n  const languagePath = path.join(translationsPath, `${language}.json`);\n  if (fs.existsSync(languagePath)) {\n    const translationContent = fs.readFileSync(languagePath, 'utf8');\n    resources[language] = {\n      translation: JSON.parse(translationContent),\n    };\n  }\n});\n\ni18next.init({\n  resources,\n  fallbackLng: 'en',\n  lng: configService.get<Language>('LANGUAGE'),\n  debug: false,\n\n  interpolation: {\n    escapeValue: false,\n  },\n});\nexport default i18next;\n","import { configService, Telemetry } from '@config/env.config';\nimport axios from 'axios';\nimport fs from 'fs';\n\nconst packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));\n\nexport interface TelemetryData {\n  route: string;\n  apiVersion: string;\n  timestamp: Date;\n}\n\nexport const sendTelemetry = async (route: string): Promise<void> => {\n  const telemetryConfig = configService.get<Telemetry>('TELEMETRY');\n\n  if (!telemetryConfig.ENABLED) {\n    return;\n  }\n\n  if (route === '/') {\n    return;\n  }\n\n  const telemetry: TelemetryData = {\n    route,\n    apiVersion: `${packageJson.version}`,\n    timestamp: new Date(),\n  };\n\n  const url =\n    telemetryConfig.URL && telemetryConfig.URL !== '' ? telemetryConfig.URL : 'https://log.evolution-api.com/telemetry';\n\n  axios\n    .post(url, telemetry)\n    .then(() => {})\n    .catch(() => {});\n};\n"],"mappings":"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","names":["isBooleanString","dotenv","ConfigService","key","configService","dayjs","fs","packageJson","fs","formatDateLog","timestamp","dayjs","Color","Level","Type","Background","Logger","context","configService","value","type","types","level","typeValue","Color","packageJson","formatDateLog","postgresql","Pool","Postgres","Logger","connectionString","e","uri","configService","postgresClient","ChatwootImport","Logger","instance","repositoryMessagesCache","messagesRaw","actualValue","contactsRaw","provider","pgClient","postgresClient","totalContactsImported","contacts","contactsChunk","labelSql","labelId","sqlLabel","sqlInsert","bindInsert","contact","isGroup","contactName","bindName","bindPhoneNumber","bindIdentifier","sqlTags","tagId","sqlTag","sqlInsertLabel","bindTaggableId","error","sourceIds","conversationId","existingSourceIdsSet","formattedSourceIds","sourceId","params","query","result","row","chatwootService","inbox","chatwootUser","totalMessagesImported","messagesOrdered","a","b","aKey","bKey","aMessageTimestamp","bMessageTimestamp","allMessagesMappedByPhoneNumber","phoneNumbersWithTimestamp","messages","phoneNumber","existingSourceIds","message","batchSize","messagesChunk","messagesByPhoneNumber","fksByNumber","sqlInsertMsg","bindInsertMsg","fksChatwoot","contentMessage","bindContent","bindConversationId","bindMessageType","bindSenderType","bindSenderId","bindSourceId","bindmessageTimestamp","providerData","event","bindValues","sqlFromChatwoot","phoneNumberTimestamp","bindStr","fksFromChatwoot","item","acc","key","phoneNumberPlus","limit","msg","configService","types","doc","fileName","caption","template","arr","chunkSize","remoteJid","messageId","chatwootImport","ChatwootClient","chatwootRequest","fs","i18next","path","languages","translationsPath","configService","ConfigService","resources","language","languagePath","translationContent","i18n_default","axios","fs","packageJson","sendTelemetry","route","telemetryConfig","configService","telemetry","url","axios","dayjs","FormData","Jimp","JimpMime","parsePhoneNumberFromString","Long","mimeTypes","path","Readable","ChatwootService","waMonitor","configService","prismaRepository","cache","Logger","postgresClient","instance","cacheKey","provider","ChatwootClient","data","urlServer","id","client","contact","inboxName","webhookUrl","qrcode","number","organization","logo","findInbox","checkDuplicate","inbox","inboxId","contactId","conversation","contentMsg","phoneNumber","isGroup","name","avatar_url","jid","error","existingContact","nameInbox","tagData","tagId","taggingsCount","identifier","contactByAttr","query","chatwootRequest","baseId","mergeId","contacts","phoneNumbers","searchableFields","phone","savedNumber","contact_with9","field","numbers","withoutNine","withNine","filterPayload","fieldsToSearch","index1","index2","queryOperator","body","isLid","remoteJid","lockKey","maxWaitTime","baseContact","conversationId","conversationExists","start","res","chatId","nameContact","filterInbox","group","participantJid","picture_url","findParticipant","waProfilePictureFile","chatwootProfilePictureFile","pictureNeedsUpdate","nameNeedsUpdate","contactConversations","inboxConversation","findByName","content","messageType","privateMessage","attachments","messageBody","sourceId","quotedMsg","replyToIds","sourceReplyId","message","fileStream","fileName","messageAlreadySaved","chatwootImport","config","waInstance","media","caption","options","parsedMedia","mimeType","parts","type","sendTelemetry","i18n_default","resolve","keyToDelete","messageReceived","senderName","key","cwBotContact","command","state","msgLogout","formatText","formattedDelimiter","textToConcat","attachment","messageSent","lastMessage","updateMessage","chatwootMessageIds","result","keyId","msg","inReplyTo","inReplyToExternalId","messageContent","types","typeKey","latitude","longitude","locationName","locationAddress","vCardData","contactInfo","line","value","formattedContact","numberCount","listTitle","listDescription","listFooter","formattedList","section","sectionIndex","row","rowIndex","responseTitle","responseDescription","responseRowId","event","ignoreJids","ignoreGroups","ignoreContacts","originalMessage","bodyMessage","quotedId","isMedia","adsMessage","reactionMessage","isInteractiveButtonMessage","getConversation","downloadBase64","nameFile","originalFilename","parsedFile","fileData","participantName","rawPhoneNumber","formattedPhoneNumber","send","buttons","button","paymentSettings","pixSettings","pixKeyType","pixKey","imgBuffer","extension","img","processedBuffer","truncStr","str","len","title","description","editedMessageContent","editedText","contactInboxSourceId","url","msgStatus","now","timeSinceLastNotification","msgConnection","erroQRcode","msgQrCode","uri","messagesRaw","contactsRaw","totalMessagesImported","limitContacts","recentContacts","contactIdentifiers","contactsWithProfilePicture","acc","chatwootConfig","prepareMessage","sqlMessages","ids","filteredMessages","m"]}