{"version":3,"sources":["../../../../../../src/api/types/wa.types.ts","../../../../../../src/config/env.config.ts","../../../../../../src/utils/sendTelemetry.ts","../../../../../../src/api/integrations/chatbot/openai/services/openai.service.ts","../../../../../../src/config/logger.config.ts","../../../../../../src/api/integrations/chatbot/base-chatbot.service.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\nimport { JsonValue } from '@prisma/client/runtime/library';\nimport { AuthenticationState, WAConnectionState } from 'baileys';\n\nexport enum Events {\n  APPLICATION_STARTUP = 'application.startup',\n  INSTANCE_CREATE = 'instance.create',\n  INSTANCE_DELETE = 'instance.delete',\n  QRCODE_UPDATED = 'qrcode.updated',\n  CONNECTION_UPDATE = 'connection.update',\n  STATUS_INSTANCE = 'status.instance',\n  MESSAGES_SET = 'messages.set',\n  MESSAGES_UPSERT = 'messages.upsert',\n  MESSAGES_EDITED = 'messages.edited',\n  MESSAGES_UPDATE = 'messages.update',\n  MESSAGES_DELETE = 'messages.delete',\n  SEND_MESSAGE = 'send.message',\n  SEND_MESSAGE_UPDATE = 'send.message.update',\n  CONTACTS_SET = 'contacts.set',\n  CONTACTS_UPSERT = 'contacts.upsert',\n  CONTACTS_UPDATE = 'contacts.update',\n  PRESENCE_UPDATE = 'presence.update',\n  CHATS_SET = 'chats.set',\n  CHATS_UPDATE = 'chats.update',\n  CHATS_UPSERT = 'chats.upsert',\n  CHATS_DELETE = 'chats.delete',\n  GROUPS_UPSERT = 'groups.upsert',\n  GROUPS_UPDATE = 'groups.update',\n  GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',\n  CALL = 'call',\n  TYPEBOT_START = 'typebot.start',\n  TYPEBOT_CHANGE_STATUS = 'typebot.change-status',\n  LABELS_EDIT = 'labels.edit',\n  LABELS_ASSOCIATION = 'labels.association',\n  CREDS_UPDATE = 'creds.update',\n  MESSAGING_HISTORY_SET = 'messaging-history.set',\n  REMOVE_INSTANCE = 'remove.instance',\n  LOGOUT_INSTANCE = 'logout.instance',\n}\n\nexport declare namespace wa {\n  export type QrCode = {\n    count?: number;\n    pairingCode?: string;\n    base64?: string;\n    code?: string;\n  };\n\n  export type Instance = {\n    id?: string;\n    qrcode?: QrCode;\n    pairingCode?: string;\n    authState?: { state: AuthenticationState; saveCreds: () => void };\n    name?: string;\n    ownerJid?: string;\n    wuid?: string;\n    profileName?: string;\n    profilePictureUrl?: string;\n    token?: string;\n    number?: string;\n    integration?: string;\n    businessId?: string;\n  };\n\n  export type LocalChatwoot = {\n    enabled?: boolean;\n    accountId?: string;\n    token?: string;\n    url?: string;\n    nameInbox?: string;\n    signMsg?: boolean;\n    signDelimiter?: string;\n    number?: string;\n    reopenConversation?: boolean;\n    conversationPending?: boolean;\n    mergeBrazilContacts?: boolean;\n    importContacts?: boolean;\n    importMessages?: boolean;\n    daysLimitImportMessages?: number;\n  };\n\n  export type LocalSettings = {\n    rejectCall?: boolean;\n    msgCall?: string;\n    groupsIgnore?: boolean;\n    alwaysOnline?: boolean;\n    readMessages?: boolean;\n    readStatus?: boolean;\n    syncFullHistory?: boolean;\n    wavoipToken?: string;\n  };\n\n  export type LocalEvent = {\n    enabled?: boolean;\n    events?: JsonValue;\n  };\n\n  export type LocalWebHook = LocalEvent & {\n    url?: string;\n    headers?: JsonValue;\n    webhookByEvents?: boolean;\n    webhookBase64?: boolean;\n  };\n\n  export type LocalPusher = LocalEvent & {\n    appId?: string;\n    key?: string;\n    secret?: string;\n    cluster?: string;\n    useTLS?: boolean;\n  };\n\n  type Session = {\n    remoteJid?: string;\n    sessionId?: string;\n    createdAt?: number;\n  };\n\n  export type LocalProxy = {\n    enabled?: boolean;\n    host?: string;\n    port?: string;\n    protocol?: string;\n    username?: string;\n    password?: string;\n  };\n\n  export type StateConnection = {\n    instance?: string;\n    state?: WAConnectionState | 'refused';\n    statusReason?: number;\n  };\n\n  export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED';\n}\n\nexport const TypeMediaMessage = [\n  'imageMessage',\n  'documentMessage',\n  'audioMessage',\n  'videoMessage',\n  'stickerMessage',\n  'ptvMessage',\n];\n\nexport const MessageSubtype = [\n  'ephemeralMessage',\n  'documentWithCaptionMessage',\n  'viewOnceMessage',\n  'viewOnceMessageV2',\n];\n\nexport const Integration = {\n  WHATSAPP_BUSINESS: 'WHATSAPP-BUSINESS',\n  WHATSAPP_BAILEYS: 'WHATSAPP-BAILEYS',\n  EVOLUTION: 'EVOLUTION',\n};\n","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 { 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","import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, Language, Openai as OpenaiConfig } from '@config/env.config';\nimport { IntegrationSession, OpenaiBot, OpenaiSetting } from '@prisma/client';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { downloadMediaMessage } from 'baileys';\nimport { isURL } from 'class-validator';\nimport FormData from 'form-data';\nimport OpenAI from 'openai';\nimport P from 'pino';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\n\n/**\n * OpenAI service that extends the common BaseChatbotService\n * Handles both Assistant API and ChatCompletion API\n */\nexport class OpenaiService extends BaseChatbotService<OpenaiBot, OpenaiSetting> {\n  protected client: OpenAI;\n\n  constructor(waMonitor: WAMonitoringService, prismaRepository: PrismaRepository, configService: ConfigService) {\n    super(waMonitor, prismaRepository, 'OpenaiService', configService);\n  }\n\n  /**\n   * Return the bot type for OpenAI\n   */\n  protected getBotType(): string {\n    return 'openai';\n  }\n\n  /**\n   * Initialize the OpenAI client with the provided API key\n   */\n  protected initClient(apiKey: string) {\n    this.client = new OpenAI({ apiKey });\n    return this.client;\n  }\n\n  /**\n   * Process a message based on the bot type (assistant or chat completion)\n   */\n  public async process(\n    instance: any,\n    remoteJid: string,\n    openaiBot: OpenaiBot,\n    session: IntegrationSession,\n    settings: OpenaiSetting,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      this.logger.log(`Starting process for remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);\n\n      // Handle audio message transcription\n      if (content.startsWith('audioMessage|') && msg) {\n        this.logger.log('Detected audio message, attempting to transcribe');\n\n        // Get OpenAI credentials for transcription\n        const creds = await this.prismaRepository.openaiCreds.findUnique({\n          where: { id: openaiBot.openaiCredsId },\n        });\n\n        if (!creds) {\n          this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n          return;\n        }\n\n        // Initialize OpenAI client for transcription\n        this.initClient(creds.apiKey);\n\n        // Transcribe the audio\n        const transcription = await this.speechToText(msg, instance);\n\n        if (transcription) {\n          this.logger.log(`Audio transcribed: ${transcription}`);\n          // Replace the audio message identifier with the transcription\n          content = transcription;\n        } else {\n          this.logger.error('Failed to transcribe audio');\n          await this.sendMessageWhatsApp(\n            instance,\n            remoteJid,\n            \"Sorry, I couldn't transcribe your audio message. Could you please type your message instead?\",\n            settings,\n            true,\n          );\n          return;\n        }\n      } else {\n        // Get the OpenAI credentials\n        const creds = await this.prismaRepository.openaiCreds.findUnique({\n          where: { id: openaiBot.openaiCredsId },\n        });\n\n        if (!creds) {\n          this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n          return;\n        }\n\n        // Initialize OpenAI client\n        this.initClient(creds.apiKey);\n      }\n\n      // Handle keyword finish\n      const keywordFinish = settings?.keywordFinish || '';\n      const normalizedContent = content.toLowerCase().trim();\n      if (keywordFinish.length > 0 && normalizedContent === keywordFinish.toLowerCase()) {\n        if (settings?.keepOpen) {\n          await this.prismaRepository.integrationSession.update({\n            where: {\n              id: session.id,\n            },\n            data: {\n              status: 'closed',\n            },\n          });\n        } else {\n          await this.prismaRepository.integrationSession.delete({\n            where: {\n              id: session.id,\n            },\n          });\n        }\n\n        await sendTelemetry('/openai/session/finish');\n        return;\n      }\n\n      // If session is new or doesn't exist\n      if (!session) {\n        const data = {\n          remoteJid,\n          pushName,\n          botId: openaiBot.id,\n        };\n\n        const createSession = await this.createNewSession(\n          { instanceName: instance.instanceName, instanceId: instance.instanceId },\n          data,\n          this.getBotType(),\n        );\n\n        await this.initNewSession(\n          instance,\n          remoteJid,\n          openaiBot,\n          settings,\n          createSession.session,\n          content,\n          pushName,\n          msg,\n        );\n\n        await sendTelemetry('/openai/session/start');\n        return;\n      }\n\n      // If session exists but is paused\n      if (session.status === 'paused') {\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'opened',\n            awaitUser: true,\n          },\n        });\n\n        return;\n      }\n\n      // Process with the appropriate API based on bot type\n      await this.sendMessageToBot(instance, session, settings, openaiBot, remoteJid, pushName || '', content, msg);\n    } catch (error) {\n      this.logger.error(`Error in process: ${error.message || JSON.stringify(error)}`);\n      return;\n    }\n  }\n\n  /**\n   * Send message to OpenAI - this handles both Assistant API and ChatCompletion API\n   */\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: OpenaiSetting,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    this.logger.log(`Sending message to bot for remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);\n\n    if (!this.client) {\n      this.logger.log('Client not initialized, initializing now');\n      const creds = await this.prismaRepository.openaiCreds.findUnique({\n        where: { id: openaiBot.openaiCredsId },\n      });\n\n      if (!creds) {\n        this.logger.error(`OpenAI credentials not found in sendMessageToBot. CredsId: ${openaiBot.openaiCredsId}`);\n        return;\n      }\n\n      this.initClient(creds.apiKey);\n    }\n\n    try {\n      let message: string;\n\n      // Handle different bot types\n      if (openaiBot.botType === 'assistant') {\n        this.logger.log('Processing with Assistant API');\n        message = await this.processAssistantMessage(\n          instance,\n          session,\n          openaiBot,\n          remoteJid,\n          pushName,\n          false, // Not fromMe\n          content,\n          msg,\n        );\n      } else {\n        this.logger.log('Processing with ChatCompletion API');\n        message = await this.processChatCompletionMessage(instance, openaiBot, remoteJid, content, msg);\n      }\n\n      this.logger.log(`Got response from OpenAI: ${message?.substring(0, 50)}${message?.length > 50 ? '...' : ''}`);\n\n      // Send the response\n      if (message) {\n        this.logger.log('Sending message to WhatsApp');\n        await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n      } else {\n        this.logger.error('No message to send to WhatsApp');\n      }\n\n      // Update session status\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          status: 'opened',\n          awaitUser: true,\n        },\n      });\n    } catch (error) {\n      this.logger.error(`Error in sendMessageToBot: ${error.message || JSON.stringify(error)}`);\n      if (error.response) {\n        this.logger.error(`API Response data: ${JSON.stringify(error.response.data || {})}`);\n      }\n      return;\n    }\n  }\n\n  /**\n   * Process message using the OpenAI Assistant API\n   */\n  private async processAssistantMessage(\n    instance: any,\n    session: IntegrationSession,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    pushName: string,\n    fromMe: boolean,\n    content: string,\n    msg?: any,\n  ): Promise<string> {\n    const messageData: any = {\n      role: fromMe ? 'assistant' : 'user',\n      content: [{ type: 'text', text: content }],\n    };\n\n    // Handle image messages\n    if (this.isImageMessage(content)) {\n      const media = content.split('|');\n\n      if (msg.message.mediaUrl || msg.message.base64) {\n        let mediaBase64 = msg.message.base64 || null;\n\n        if (msg.message.mediaUrl && isURL(msg.message.mediaUrl)) {\n          const result = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' });\n          mediaBase64 = Buffer.from(result.data).toString('base64');\n        }\n\n        if (mediaBase64) {\n          messageData.content = [\n            { type: 'text', text: media[2] || content },\n            { type: 'image_url', image_url: { url: mediaBase64 } },\n          ];\n        }\n      } else {\n        const url = media[1].split('?')[0];\n\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          {\n            type: 'image_url',\n            image_url: {\n              url: url,\n            },\n          },\n        ];\n      }\n    }\n\n    // Get thread ID from session or create new thread\n    let threadId = session.sessionId;\n\n    // Create a new thread if one doesn't exist or invalid format\n    if (!threadId || threadId === remoteJid) {\n      const newThread = await this.client.beta.threads.create();\n      threadId = newThread.id;\n\n      // Save the new thread ID to the session\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          sessionId: threadId,\n        },\n      });\n      this.logger.log(`Created new thread ID: ${threadId} for session: ${session.id}`);\n    }\n\n    // Add message to thread\n    await this.client.beta.threads.messages.create(threadId, messageData);\n\n    if (fromMe) {\n      sendTelemetry('/message/sendText');\n      return '';\n    }\n\n    // Run the assistant\n    const runAssistant = await this.client.beta.threads.runs.create(threadId, {\n      assistant_id: openaiBot.assistantId,\n    });\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    // Wait for the assistant to complete\n    const response = await this.getAIResponse(threadId, runAssistant.id, openaiBot.functionUrl, remoteJid, pushName);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.sendPresenceUpdate('paused', remoteJid);\n    }\n\n    // Extract the response text safely with type checking\n    let responseText = \"I couldn't generate a proper response. Please try again.\";\n    try {\n      const messages = response?.data || [];\n      if (messages.length > 0) {\n        const messageContent = messages[0]?.content || [];\n        if (messageContent.length > 0) {\n          const textContent = messageContent[0];\n          if (textContent && 'text' in textContent && textContent.text && 'value' in textContent.text) {\n            responseText = textContent.text.value;\n          }\n        }\n      }\n    } catch (error) {\n      this.logger.error(`Error extracting response text: ${error}`);\n    }\n\n    // Update session with the thread ID to ensure continuity\n    await this.prismaRepository.integrationSession.update({\n      where: {\n        id: session.id,\n      },\n      data: {\n        status: 'opened',\n        awaitUser: true,\n        sessionId: threadId, // Ensure thread ID is saved consistently\n      },\n    });\n\n    // Return fallback message if unable to extract text\n    return responseText;\n  }\n\n  /**\n   * Process message using the OpenAI ChatCompletion API\n   */\n  private async processChatCompletionMessage(\n    instance: any,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    content: string,\n    msg?: any,\n  ): Promise<string> {\n    this.logger.log('Starting processChatCompletionMessage');\n\n    // Check if client is initialized\n    if (!this.client) {\n      this.logger.log('Client not initialized in processChatCompletionMessage, initializing now');\n      const creds = await this.prismaRepository.openaiCreds.findUnique({\n        where: { id: openaiBot.openaiCredsId },\n      });\n\n      if (!creds) {\n        this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n        return 'Error: OpenAI credentials not found';\n      }\n\n      this.initClient(creds.apiKey);\n    }\n\n    // Check if model is defined\n    if (!openaiBot.model) {\n      this.logger.error('OpenAI model not defined');\n      return 'Error: OpenAI model not configured';\n    }\n\n    this.logger.log(`Using model: ${openaiBot.model}, max tokens: ${openaiBot.maxTokens || 500}`);\n\n    // Get existing conversation history from the session\n    const session = await this.prismaRepository.integrationSession.findFirst({\n      where: {\n        remoteJid,\n        botId: openaiBot.id,\n        status: 'opened',\n      },\n    });\n\n    let conversationHistory = [];\n\n    if (session && session.context) {\n      try {\n        const sessionData =\n          typeof session.context === 'string' ? JSON.parse(session.context as string) : session.context;\n\n        conversationHistory = sessionData.history || [];\n        this.logger.log(`Retrieved conversation history from session, ${conversationHistory.length} messages`);\n      } catch (error) {\n        this.logger.error(`Error parsing session context: ${error.message}`);\n        // Continue with empty history if we can't parse the session data\n        conversationHistory = [];\n      }\n    }\n\n    // Log bot data\n    this.logger.log(`Bot data - systemMessages: ${JSON.stringify(openaiBot.systemMessages || [])}`);\n    this.logger.log(`Bot data - assistantMessages: ${JSON.stringify(openaiBot.assistantMessages || [])}`);\n    this.logger.log(`Bot data - userMessages: ${JSON.stringify(openaiBot.userMessages || [])}`);\n\n    // Prepare system messages\n    const systemMessages: any = openaiBot.systemMessages || [];\n    const messagesSystem: any[] = systemMessages.map((message) => {\n      return {\n        role: 'system',\n        content: message,\n      };\n    });\n\n    // Prepare assistant messages\n    const assistantMessages: any = openaiBot.assistantMessages || [];\n    const messagesAssistant: any[] = assistantMessages.map((message) => {\n      return {\n        role: 'assistant',\n        content: message,\n      };\n    });\n\n    // Prepare user messages\n    const userMessages: any = openaiBot.userMessages || [];\n    const messagesUser: any[] = userMessages.map((message) => {\n      return {\n        role: 'user',\n        content: message,\n      };\n    });\n\n    // Prepare current message\n    const messageData: any = {\n      role: 'user',\n      content: [{ type: 'text', text: content }],\n    };\n\n    // Handle image messages\n    if (this.isImageMessage(content)) {\n      this.logger.log('Found image message');\n      const media = content.split('|');\n\n      if (msg.message.mediaUrl || msg.message.base64) {\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          { type: 'image_url', image_url: { url: msg.message.base64 || msg.message.mediaUrl } },\n        ];\n      } else {\n        const url = media[1].split('?')[0];\n\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          {\n            type: 'image_url',\n            image_url: {\n              url: url,\n            },\n          },\n        ];\n      }\n    }\n\n    // Combine all messages: system messages, pre-defined messages, conversation history, and current message\n    const messages: any[] = [\n      ...messagesSystem,\n      ...messagesAssistant,\n      ...messagesUser,\n      ...conversationHistory,\n      messageData,\n    ];\n\n    this.logger.log(`Final messages payload: ${JSON.stringify(messages)}`);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      this.logger.log('Setting typing indicator');\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    // Send the request to OpenAI\n    try {\n      this.logger.log('Sending request to OpenAI API');\n      const completions = await this.client.chat.completions.create({\n        model: openaiBot.model,\n        messages: messages,\n        max_tokens: openaiBot.maxTokens || 500, // Add default if maxTokens is missing\n      });\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n        await instance.client.sendPresenceUpdate('paused', remoteJid);\n      }\n\n      const responseContent = completions.choices[0].message.content;\n      this.logger.log(`Received response from OpenAI: ${JSON.stringify(completions.choices[0])}`);\n\n      // Add the current exchange to the conversation history and update the session\n      conversationHistory.push(messageData);\n      conversationHistory.push({\n        role: 'assistant',\n        content: responseContent,\n      });\n\n      // Limit history length to avoid token limits (keep last 10 messages)\n      if (conversationHistory.length > 10) {\n        conversationHistory = conversationHistory.slice(conversationHistory.length - 10);\n      }\n\n      // Save the updated conversation history to the session\n      if (session) {\n        await this.prismaRepository.integrationSession.update({\n          where: { id: session.id },\n          data: {\n            context: JSON.stringify({\n              history: conversationHistory,\n            }),\n          },\n        });\n        this.logger.log(`Updated session with conversation history, now ${conversationHistory.length} messages`);\n      }\n\n      return responseContent;\n    } catch (error) {\n      this.logger.error(`Error calling OpenAI: ${error.message || JSON.stringify(error)}`);\n      if (error.response) {\n        this.logger.error(`API Response status: ${error.response.status}`);\n        this.logger.error(`API Response data: ${JSON.stringify(error.response.data || {})}`);\n      }\n      return `Sorry, there was an error: ${error.message || 'Unknown error'}`;\n    }\n  }\n\n  /**\n   * Wait for and retrieve the AI response\n   */\n  private async getAIResponse(\n    threadId: string,\n    runId: string,\n    functionUrl: string | null,\n    remoteJid: string,\n    pushName: string,\n  ) {\n    let status = await this.client.beta.threads.runs.retrieve(threadId, runId);\n\n    let maxRetries = 60; // 1 minute with 1s intervals\n    const checkInterval = 1000; // 1 second\n\n    while (\n      status.status !== 'completed' &&\n      status.status !== 'failed' &&\n      status.status !== 'cancelled' &&\n      status.status !== 'expired' &&\n      maxRetries > 0\n    ) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n      status = await this.client.beta.threads.runs.retrieve(threadId, runId);\n\n      // Handle tool calls\n      if (status.status === 'requires_action' && status.required_action?.type === 'submit_tool_outputs') {\n        const toolCalls = status.required_action.submit_tool_outputs.tool_calls;\n        const toolOutputs = [];\n\n        for (const toolCall of toolCalls) {\n          if (functionUrl) {\n            try {\n              const payloadData = JSON.parse(toolCall.function.arguments);\n\n              // Add context\n              payloadData.remoteJid = remoteJid;\n              payloadData.pushName = pushName;\n\n              const response = await axios.post(functionUrl, {\n                functionName: toolCall.function.name,\n                functionArguments: payloadData,\n              });\n\n              toolOutputs.push({\n                tool_call_id: toolCall.id,\n                output: JSON.stringify(response.data),\n              });\n            } catch (error) {\n              this.logger.error(`Error calling function: ${error}`);\n              toolOutputs.push({\n                tool_call_id: toolCall.id,\n                output: JSON.stringify({ error: 'Function call failed' }),\n              });\n            }\n          } else {\n            toolOutputs.push({\n              tool_call_id: toolCall.id,\n              output: JSON.stringify({ error: 'No function URL configured' }),\n            });\n          }\n        }\n\n        await this.client.beta.threads.runs.submitToolOutputs(threadId, runId, {\n          tool_outputs: toolOutputs,\n        });\n      }\n\n      maxRetries--;\n    }\n\n    if (status.status === 'completed') {\n      const messages = await this.client.beta.threads.messages.list(threadId);\n      return messages;\n    } else {\n      this.logger.error(`Assistant run failed with status: ${status.status}`);\n      return { data: [{ content: [{ text: { value: 'Failed to get a response from the assistant.' } }] }] };\n    }\n  }\n\n  protected isImageMessage(content: string): boolean {\n    return content.includes('imageMessage');\n  }\n\n  /**\n   * Implementation of speech-to-text transcription for audio messages\n   */\n  public async speechToText(msg: any, instance: any): Promise<string | null> {\n    const settings = await this.prismaRepository.openaiSetting.findFirst({\n      where: {\n        instanceId: instance.instanceId,\n      },\n    });\n\n    if (!settings) {\n      this.logger.error(`OpenAI settings not found. InstanceId: ${instance.instanceId}`);\n      return null;\n    }\n\n    const creds = await this.prismaRepository.openaiCreds.findUnique({\n      where: { id: settings.openaiCredsId },\n    });\n\n    if (!creds) {\n      this.logger.error(`OpenAI credentials not found. CredsId: ${settings.openaiCredsId}`);\n      return null;\n    }\n\n    let audio: Buffer;\n\n    if (msg.message.mediaUrl) {\n      audio = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' }).then((response) => {\n        return Buffer.from(response.data, 'binary');\n      });\n    } else if (msg.message.base64) {\n      audio = Buffer.from(msg.message.base64, 'base64');\n    } else {\n      // Fallback for raw WhatsApp audio messages that need downloadMediaMessage\n      audio = await downloadMediaMessage(\n        { key: msg.key, message: msg?.message },\n        'buffer',\n        {},\n        {\n          logger: P({ level: 'error' }) as any,\n          reuploadRequest: instance,\n        },\n      );\n    }\n\n    const lang = this.configService.get<Language>('LANGUAGE').includes('pt')\n      ? 'pt'\n      : this.configService.get<Language>('LANGUAGE');\n\n    const formData = new FormData();\n    formData.append('file', audio, 'audio.ogg');\n    formData.append('model', 'whisper-1');\n    formData.append('language', lang);\n\n    const apiKey = creds?.apiKey || this.configService.get<OpenaiConfig>('OPENAI').API_KEY_GLOBAL;\n\n    const response = await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, {\n      headers: {\n        'Content-Type': 'multipart/form-data',\n        Authorization: `Bearer ${apiKey}`,\n      },\n    });\n\n    return response?.data?.text;\n  }\n}\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 { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { IntegrationSession } from '@prisma/client';\n\n/**\n * Base class for all chatbot service implementations\n * Contains common methods shared across different chatbot integrations\n */\nexport abstract class BaseChatbotService<BotType = any, SettingsType = any> {\n  protected readonly logger: Logger;\n  protected readonly waMonitor: WAMonitoringService;\n  protected readonly prismaRepository: PrismaRepository;\n  protected readonly configService?: ConfigService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    loggerName: string,\n    configService?: ConfigService,\n  ) {\n    this.waMonitor = waMonitor;\n    this.prismaRepository = prismaRepository;\n    this.logger = new Logger(loggerName);\n    this.configService = configService;\n  }\n\n  /**\n   * Check if a message contains an image\n   */\n  protected isImageMessage(content: string): boolean {\n    return content.includes('imageMessage');\n  }\n\n  /**\n   * Check if a message contains audio\n   */\n  protected isAudioMessage(content: string): boolean {\n    return content.includes('audioMessage');\n  }\n\n  /**\n   * Check if a string is valid JSON\n   */\n  protected isJSON(str: string): boolean {\n    try {\n      JSON.parse(str);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * Determine the media type from a URL based on its extension\n   */\n  protected getMediaType(url: string): string | null {\n    const extension = url.split('.').pop()?.toLowerCase();\n    const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];\n    const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];\n    const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];\n    const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];\n\n    if (imageExtensions.includes(extension || '')) return 'image';\n    if (audioExtensions.includes(extension || '')) return 'audio';\n    if (videoExtensions.includes(extension || '')) return 'video';\n    if (documentExtensions.includes(extension || '')) return 'document';\n    return null;\n  }\n\n  /**\n   * Create a new chatbot session\n   */\n  public async createNewSession(instance: InstanceDto | any, data: any, type: string) {\n    try {\n      // Extract pushName safely - if data.pushName is an object with a pushName property, use that\n      const pushNameValue =\n        typeof data.pushName === 'object' && data.pushName?.pushName\n          ? data.pushName.pushName\n          : typeof data.pushName === 'string'\n            ? data.pushName\n            : null;\n\n      // Extract remoteJid safely\n      const remoteJidValue =\n        typeof data.remoteJid === 'object' && data.remoteJid?.remoteJid ? data.remoteJid.remoteJid : data.remoteJid;\n\n      const session = await this.prismaRepository.integrationSession.create({\n        data: {\n          remoteJid: remoteJidValue,\n          pushName: pushNameValue,\n          sessionId: remoteJidValue,\n          status: 'opened',\n          awaitUser: false,\n          botId: data.botId,\n          instanceId: instance.instanceId,\n          type: type,\n        },\n      });\n\n      return { session };\n    } catch (error) {\n      this.logger.error(error);\n      return;\n    }\n  }\n\n  /**\n   * Standard implementation for processing incoming messages\n   * This handles the common workflow across all chatbot types:\n   * 1. Check for existing session or create new one\n   * 2. Handle message based on session state\n   */\n  public async process(\n    instance: any,\n    remoteJid: string,\n    bot: BotType,\n    session: IntegrationSession,\n    settings: SettingsType,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      // For new sessions or sessions awaiting initialization\n      if (!session) {\n        await this.initNewSession(instance, remoteJid, bot, settings, session, content, pushName, msg);\n        return;\n      }\n\n      // If session is paused, ignore the message\n      if (session.status === 'paused') {\n        return;\n      }\n\n      // For existing sessions, keywords might indicate the conversation should end\n      const keywordFinish = (settings as any)?.keywordFinish || '';\n      const normalizedContent = content.toLowerCase().trim();\n      if (keywordFinish.length > 0 && normalizedContent === keywordFinish.toLowerCase()) {\n        // Update session to closed and return\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'closed',\n          },\n        });\n        return;\n      }\n\n      // Forward the message to the chatbot API\n      await this.sendMessageToBot(instance, session, settings, bot, remoteJid, pushName || '', content, msg);\n\n      // Update session to indicate we're waiting for user response\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          status: 'opened',\n          awaitUser: true,\n        },\n      });\n    } catch (error) {\n      this.logger.error(`Error in process: ${error}`);\n      return;\n    }\n  }\n\n  /**\n   * Standard implementation for sending messages to WhatsApp\n   * This handles common patterns like markdown links and formatting\n   */\n  protected async sendMessageWhatsApp(\n    instance: any,\n    remoteJid: string,\n    message: string,\n    settings: SettingsType,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    if (!message) return;\n\n    const linkRegex = /!?\\[(.*?)\\]\\((.*?)\\)/g;\n    let textBuffer = '';\n    let lastIndex = 0;\n    let match: RegExpExecArray | null;\n\n    const splitMessages = (settings as any)?.splitMessages ?? false;\n\n    while ((match = linkRegex.exec(message)) !== null) {\n      const [fullMatch, altText, url] = match;\n      const mediaType = this.getMediaType(url);\n      const beforeText = message.slice(lastIndex, match.index);\n\n      if (beforeText) {\n        textBuffer += beforeText;\n      }\n\n      if (mediaType) {\n        // Send accumulated text before sending media\n        if (textBuffer.trim()) {\n          await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);\n          textBuffer = '';\n        }\n\n        // Handle sending the media\n        try {\n          if (mediaType === 'audio') {\n            await instance.audioWhatsapp({\n              number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n              delay: (settings as any)?.delayMessage || 1000,\n              audio: url,\n              caption: altText,\n            });\n          } else {\n            await instance.mediaMessage(\n              {\n                number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n                delay: (settings as any)?.delayMessage || 1000,\n                mediatype: mediaType,\n                media: url,\n                caption: altText,\n                fileName: mediaType === 'document' ? altText || 'document' : undefined,\n              },\n              null,\n              false,\n            );\n          }\n        } catch (error) {\n          this.logger.error(`Error sending media: ${error}`);\n          // If media fails, at least send the alt text and URL\n          textBuffer += `${altText}: ${url}`;\n        }\n      } else {\n        // It's a regular link, keep it in the text\n        textBuffer += fullMatch;\n      }\n\n      lastIndex = linkRegex.lastIndex;\n    }\n\n    // Add any remaining text after the last match\n    if (lastIndex < message.length) {\n      const remainingText = message.slice(lastIndex);\n      if (remainingText.trim()) {\n        textBuffer += remainingText;\n      }\n    }\n\n    // Send any remaining text\n    if (textBuffer.trim()) {\n      await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);\n    }\n  }\n\n  /**\n   * Split message by double line breaks and return array of message parts\n   */\n  private splitMessageByDoubleLineBreaks(message: string): string[] {\n    return message.split('\\n\\n').filter((part) => part.trim().length > 0);\n  }\n\n  /**\n   * Send a single message with proper typing indicators and delays\n   */\n  private async sendSingleMessage(\n    instance: any,\n    remoteJid: string,\n    message: string,\n    settings: any,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    const timePerChar = settings?.timePerChar ?? 0;\n    const minDelay = 1000;\n    const maxDelay = 20000;\n    const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);\n\n    this.logger.debug(`[BaseChatbot] Sending single message with linkPreview: ${linkPreview}`);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    await new Promise<void>((resolve) => {\n      setTimeout(async () => {\n        await instance.textMessage(\n          {\n            number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n            delay: settings?.delayMessage || 1000,\n            text: message,\n            linkPreview,\n          },\n          false,\n        );\n        resolve();\n      }, delay);\n    });\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.sendPresenceUpdate('paused', remoteJid);\n    }\n  }\n\n  /**\n   * Helper method to send formatted text with proper typing indicators and delays\n   */\n  private async sendFormattedText(\n    instance: any,\n    remoteJid: string,\n    text: string,\n    settings: any,\n    splitMessages: boolean,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    if (splitMessages) {\n      const messageParts = this.splitMessageByDoubleLineBreaks(text);\n\n      this.logger.debug(`[BaseChatbot] Splitting message into ${messageParts.length} parts`);\n\n      for (let index = 0; index < messageParts.length; index++) {\n        const message = messageParts[index];\n\n        this.logger.debug(`[BaseChatbot] Sending message part ${index + 1}/${messageParts.length}`);\n        await this.sendSingleMessage(instance, remoteJid, message, settings, linkPreview);\n      }\n\n      this.logger.debug(`[BaseChatbot] All message parts sent successfully`);\n    } else {\n      this.logger.debug(`[BaseChatbot] Sending single message`);\n      await this.sendSingleMessage(instance, remoteJid, text, settings, linkPreview);\n    }\n  }\n\n  /**\n   * Standard implementation for initializing a new session\n   * This method should be overridden if a subclass needs specific initialization\n   */\n  protected async initNewSession(\n    instance: any,\n    remoteJid: string,\n    bot: BotType,\n    settings: SettingsType,\n    session: IntegrationSession,\n    content: string,\n    pushName?: string | any,\n    msg?: any,\n  ): Promise<void> {\n    // Create a session if none exists\n    if (!session) {\n      // Extract pushName properly - if it's an object with pushName property, use that\n      const pushNameValue =\n        typeof pushName === 'object' && pushName?.pushName\n          ? pushName.pushName\n          : typeof pushName === 'string'\n            ? pushName\n            : null;\n\n      const sessionResult = await this.createNewSession(\n        {\n          instanceName: instance.instanceName,\n          instanceId: instance.instanceId,\n        },\n        {\n          remoteJid,\n          pushName: pushNameValue,\n          botId: (bot as any).id,\n        },\n        this.getBotType(),\n      );\n\n      if (!sessionResult || !sessionResult.session) {\n        this.logger.error('Failed to create new session');\n        return;\n      }\n\n      session = sessionResult.session;\n    }\n\n    // Update session status to opened\n    await this.prismaRepository.integrationSession.update({\n      where: {\n        id: session.id,\n      },\n      data: {\n        status: 'opened',\n        awaitUser: false,\n      },\n    });\n\n    // Forward the message to the chatbot\n    await this.sendMessageToBot(instance, session, settings, bot, remoteJid, pushName || '', content, msg);\n  }\n\n  /**\n   * Get the bot type identifier (e.g., 'dify', 'n8n', 'evoai')\n   * This should match the type field used in the IntegrationSession\n   */\n  protected abstract getBotType(): string;\n\n  /**\n   * Send a message to the chatbot API\n   * This is specific to each chatbot integration\n   */\n  protected abstract sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: SettingsType,\n    bot: BotType,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void>;\n}\n"],"mappings":"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","names":["Integration","isBooleanString","dotenv","ConfigService","key","configService","axios","fs","packageJson","sendTelemetry","route","telemetryConfig","configService","telemetry","url","axios","downloadMediaMessage","isURL","FormData","OpenAI","P","dayjs","fs","packageJson","fs","formatDateLog","timestamp","dayjs","Color","Level","Type","Background","Logger","context","configService","value","type","types","level","typeValue","Color","packageJson","formatDateLog","BaseChatbotService","waMonitor","prismaRepository","loggerName","configService","Logger","content","str","url","extension","imageExtensions","audioExtensions","videoExtensions","documentExtensions","instance","data","type","pushNameValue","remoteJidValue","error","remoteJid","bot","session","settings","pushName","msg","keywordFinish","normalizedContent","message","linkPreview","linkRegex","textBuffer","lastIndex","match","splitMessages","fullMatch","altText","mediaType","beforeText","remainingText","part","timePerChar","delay","Integration","resolve","text","messageParts","index","sessionResult","OpenaiService","BaseChatbotService","waMonitor","prismaRepository","configService","apiKey","OpenAI","instance","remoteJid","openaiBot","session","settings","content","pushName","msg","creds","transcription","keywordFinish","normalizedContent","sendTelemetry","data","createSession","error","message","fromMe","messageData","media","mediaBase64","isURL","result","axios","url","threadId","runAssistant","Integration","response","responseText","messages","messageContent","textContent","conversationHistory","messagesSystem","messagesAssistant","messagesUser","completions","responseContent","runId","functionUrl","status","maxRetries","checkInterval","resolve","toolCalls","toolOutputs","toolCall","payloadData","audio","downloadMediaMessage","P","lang","formData","FormData"]}