From 763e30bd1d4f4c4547ec65ba61018e89bc39e156 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 09:34:39 -0300 Subject: [PATCH 001/177] fix: fix in update settings that needed to restart after updated --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/whatsapp/services/whatsapp.service.ts | 19 ++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d70a8685..384a28af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.3.2 (homolog) + +### Fixed + +* Fix in update settings that needed to restart after updated + # 1.3.1 (2023-07-20 07:48) ### Fixed diff --git a/package.json b/package.json index b56b045d..7bc6f476 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.3.1", + "version": "1.3.2", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 65cb40bb..6fead74a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2364,6 +2364,9 @@ export class WAStartupService { public async fetchMessages(query: MessageQuery) { this.logger.verbose('Fetching messages'); if (query?.where) { + if (query.where?.key?.remoteJid) { + query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); + } query.where.owner = this.instance.name; } else { query = { @@ -2379,6 +2382,9 @@ export class WAStartupService { public async fetchStatusMessage(query: MessageUpQuery) { this.logger.verbose('Fetching status messages'); if (query?.where) { + if (query.where?.remoteJid) { + query.where.remoteJid = this.createJid(query.where.remoteJid); + } query.where.owner = this.instance.name; } else { query = { @@ -2423,8 +2429,19 @@ export class WAStartupService { this.logger.verbose('Groups add privacy updated'); // reinicia a instancia + this.client?.ws?.close(); - return { update: 'success', data: await this.client.fetchPrivacySettings() }; + return { + update: 'success', + data: { + readreceipts: settings.privacySettings.readreceipts, + profile: settings.privacySettings.profile, + status: settings.privacySettings.status, + online: settings.privacySettings.online, + last: settings.privacySettings.last, + groupadd: settings.privacySettings.groupadd, + }, + }; } catch (error) { throw new InternalServerErrorException( 'Error updating privacy settings', From 796287a776cc900e5b3d9fcaaf8363419e3f8f21 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 11:38:36 -0300 Subject: [PATCH 002/177] fix: Adjustments to search endpoint for contacts, chats, messages and Status messages --- CHANGELOG.md | 2 ++ src/whatsapp/repository/auth.repository.ts | 2 +- src/whatsapp/services/monitor.service.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 23 ++++++++++++++++++++-- src/whatsapp/types/wa.types.ts | 1 + 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 384a28af..875d7ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### Fixed * Fix in update settings that needed to restart after updated +* Correction in the use of the api with mongodb +* Adjustments to search endpoint for contacts, chats, messages and Status messages # 1.3.1 (2023-07-20 07:48) diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index c795737c..0d7e177f 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { Auth, ConfigService } from '../../config/env.config'; +import { Auth, ConfigService, Database } from '../../config/env.config'; import { IInsert, Repository } from '../abstract/abstract.repository'; import { IAuthModel, AuthRaw } from '../models'; import { readFileSync } from 'fs'; diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 8b347c21..8fdac88a 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -90,7 +90,7 @@ export class WAMonitoringService { const findChatwoot = await this.waInstances[key].findChatwoot(); - if (findChatwoot.enabled) { + if (findChatwoot && findChatwoot.enabled) { chatwoot = { ...findChatwoot, webhook_url: `${urlServer}/chatwoot/webhook/${key}`, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6fead74a..8035bbfb 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -328,7 +328,7 @@ export class WAStartupService { if (!data) { this.logger.verbose('Chatwoot not found'); - throw new NotFoundException('Chatwoot not found'); + return null; } this.logger.verbose(`Chatwoot account id: ${data.account_id}`); @@ -351,7 +351,7 @@ export class WAStartupService { const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); - const instanceApikey = tokenStore.apikey || 'Apikey not found'; + const instanceApikey = tokenStore?.apikey || 'Apikey not found'; const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; @@ -1190,6 +1190,22 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + + const message: MessageUpdateRaw = { + ...key, + status: 'DELETED', + datetime: Date.now(), + owner: this.instance.name, + }; + + this.logger.verbose(message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); return; } @@ -2351,6 +2367,9 @@ export class WAStartupService { this.logger.verbose('Fetching contacts'); if (query?.where) { query.where.owner = this.instance.name; + if (query.where?.id) { + query.where.id = this.createJid(query.where.id); + } } else { query = { where: { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 169df515..6869545f 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -63,6 +63,7 @@ export declare namespace wa { | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' + | 'DELETED' | 'PLAYED'; } From 04a6f7c95435ff3a3f25d16227ea778c89896b18 Mon Sep 17 00:00:00 2001 From: Helio Elias Date: Fri, 21 Jul 2023 15:02:09 +0000 Subject: [PATCH 003/177] fix docker and create docker-compose with all services --- .../docker-compose.yaml | 12 +- Docker/evolution-api-all-services/.env | 109 ++++++++++++++++++ .../docker-compose.yaml | 91 +++++++++++++++ 3 files changed, 204 insertions(+), 8 deletions(-) rename docker-compose.yaml => Docker/docker-compose.yaml (73%) create mode 100644 Docker/evolution-api-all-services/.env create mode 100644 Docker/evolution-api-all-services/docker-compose.yaml diff --git a/docker-compose.yaml b/Docker/docker-compose.yaml similarity index 73% rename from docker-compose.yaml rename to Docker/docker-compose.yaml index c6d1bc73..cbc55c12 100644 --- a/docker-compose.yaml +++ b/Docker/docker-compose.yaml @@ -1,9 +1,10 @@ version: '3.3' services: + api: container_name: evolution_api - image: evolution/api:local + image: davidsongomes/evolution-api restart: always ports: - 8080:8080 @@ -11,16 +12,11 @@ services: - evolution_instances:/evolution/instances - evolution_store:/evolution/store env_file: - - ./Docker/.env + - .env command: ['node', './dist/src/main.js'] expose: - 8080 volumes: evolution_instances: - evolution_store: - -networks: - evolution-net: - external: true - \ No newline at end of file + evolution_store: \ No newline at end of file diff --git a/Docker/evolution-api-all-services/.env b/Docker/evolution-api-all-services/.env new file mode 100644 index 00000000..555ba7bc --- /dev/null +++ b/Docker/evolution-api-all-services/.env @@ -0,0 +1,109 @@ +# Server URL - Set your application url +SERVER_URL='http://localhost:8080' + +# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com' +CORS_ORIGIN='*' +CORS_METHODS='POST,GET,PUT,DELETE' +CORS_CREDENTIALS=true + +# Determine the logs to be displayed +LOG_LEVEL='ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS' +LOG_COLOR=true +# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace" +LOG_BAILEYS=error + +# Determine how long the instance should be deleted from memory in case of no connection. +# Default time: 5 minutes +# If you don't even want an expiration, enter the value false +DEL_INSTANCE=false + +# Temporary data storage +STORE_MESSAGES=true +STORE_MESSAGE_UP=true +STORE_CONTACTS=true +STORE_CHATS=true + +# Set Store Interval in Seconds (7200 = 2h) +CLEAN_STORE_CLEANING_INTERVAL=7200 +CLEAN_STORE_MESSAGES=true +CLEAN_STORE_MESSAGE_UP=true +CLEAN_STORE_CONTACTS=true +CLEAN_STORE_CHATS=true + +# Permanent data storage +DATABASE_ENABLED=true +DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true +DATABASE_CONNECTION_DB_PREFIX_NAME=evolution + +# Choose the data you want to save in the application's database or store +DATABASE_SAVE_DATA_INSTANCE=false +DATABASE_SAVE_DATA_NEW_MESSAGE=false +DATABASE_SAVE_MESSAGE_UPDATE=false +DATABASE_SAVE_DATA_CONTACTS=false +DATABASE_SAVE_DATA_CHATS=false + +REDIS_ENABLED=true +REDIS_URI=redis://redis:6379 +REDIS_PREFIX_KEY=evolution + +# Global Webhook Settings +# Each instance's Webhook URL and events will be requested at the time it is created +## Define a global webhook that will listen for enabled events from all instances +WEBHOOK_GLOBAL_URL='' +WEBHOOK_GLOBAL_ENABLED=false +# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event +WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false +## Set the events you want to hear +WEBHOOK_EVENTS_APPLICATION_STARTUP=false +WEBHOOK_EVENTS_QRCODE_UPDATED=true +WEBHOOK_EVENTS_MESSAGES_SET=true +WEBHOOK_EVENTS_MESSAGES_UPSERT=true +WEBHOOK_EVENTS_MESSAGES_UPDATE=true +WEBHOOK_EVENTS_MESSAGES_DELETE=true +WEBHOOK_EVENTS_SEND_MESSAGE=true +WEBHOOK_EVENTS_CONTACTS_SET=true +WEBHOOK_EVENTS_CONTACTS_UPSERT=true +WEBHOOK_EVENTS_CONTACTS_UPDATE=true +WEBHOOK_EVENTS_PRESENCE_UPDATE=true +WEBHOOK_EVENTS_CHATS_SET=true +WEBHOOK_EVENTS_CHATS_UPSERT=true +WEBHOOK_EVENTS_CHATS_UPDATE=true +WEBHOOK_EVENTS_CHATS_DELETE=true +WEBHOOK_EVENTS_GROUPS_UPSERT=true +WEBHOOK_EVENTS_GROUPS_UPDATE=true +WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true +WEBHOOK_EVENTS_CONNECTION_UPDATE=true +# This event fires every time a new token is requested via the refresh route +WEBHOOK_EVENTS_NEW_JWT_TOKEN=false + +# Name that will be displayed on smartphone connection +CONFIG_SESSION_PHONE_CLIENT='Evolution API' +# Browser Name = chrome | firefox | edge | opera | safari +CONFIG_SESSION_PHONE_NAME=chrome + +# Set qrcode display limit +QRCODE_LIMIT=30 + +# Defines an authentication type for the api +# We recommend using the apikey because it will allow you to use a custom token, +# if you use jwt, a random token will be generated and may be expired and you will have to generate a new token +# jwt or 'apikey' +AUTHENTICATION_TYPE='apikey' +## Define a global apikey to access all instances. +### OBS: This key must be inserted in the request header to create an instance. +AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976' +AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true +## Set the secret key to encrypt and decrypt your token and its expiration time +# seconds - 3600s ===1h | zero (0) - never expires +AUTHENTICATION_JWT_EXPIRIN_IN=0 +AUTHENTICATION_JWT_SECRET='L0YWtjb2w554WFqPG' +# Set the instance name and webhook url to create an instance in init the application +# With this option activated, you work with a url per webhook event, respecting the local url and the name of each event +# container or server +AUTHENTICATION_INSTANCE_MODE=server +# if you are using container mode, set the container name and the webhook url to default instance +AUTHENTICATION_INSTANCE_NAME=evolution +AUTHENTICATION_INSTANCE_WEBHOOK_URL='' +AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 +AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 +AUTHENTICATION_INSTANCE_CHATWOOT_URL='' \ No newline at end of file diff --git a/Docker/evolution-api-all-services/docker-compose.yaml b/Docker/evolution-api-all-services/docker-compose.yaml new file mode 100644 index 00000000..1fe01975 --- /dev/null +++ b/Docker/evolution-api-all-services/docker-compose.yaml @@ -0,0 +1,91 @@ +version: '3.3' + +services: + + mongodb: + container_name: mongodb + image: mongo + restart: on-failure + ports: + - 27017:27017 + environment: + - MONGO_INITDB_ROOT_USERNAME=root + - MONGO_INITDB_ROOT_PASSWORD=root + - PUID=1000 + - PGID=1000 + volumes: + - evolution_mongodb_data:/data/db + - evolution_mongodb_configdb:/data/configdb + expose: + - 27017 + + mongo-express: + container_name: mongodb-express + image: mongo-express + restart: on-failure + ports: + - 8081:8081 + depends_on: + - mongodb + environment: + ME_CONFIG_BASICAUTH_USERNAME: root + ME_CONFIG_BASICAUTH_PASSWORD: root + ME_CONFIG_MONGODB_SERVER: mongodb + ME_CONFIG_MONGODB_ADMINUSERNAME: root + ME_CONFIG_MONGODB_ADMINPASSWORD: root + links: + - mongodb + + redis: + container_name: redis + image: redis:latest + restart: on-failure + ports: + - 6379:6379 + command: > + redis-server + --port 6379 + --appendonly yes + volumes: + - evolution_redis:/data + + rebrow: + container_name: rebrow + image: marian/rebrow + restart: on-failure + depends_on: + - redis + ports: + - 5001:5001 + links: + - redis + + api: + container_name: evolution_api + image: davidsongomes/evolution-api + restart: always + depends_on: + - mongodb + - redis + ports: + - 8080:8080 + volumes: + - evolution_instances:/evolution/instances + - evolution_store:/evolution/store + env_file: + - .env + command: ['node', './dist/src/main.js'] + expose: + - 8080 + +volumes: + evolution_mongodb_data: + evolution_mongodb_configdb: + evolution_redis: + evolution_instances: + evolution_store: + +networks: + evolution-net: + external: true + \ No newline at end of file From 897f8164b90af48202e4b9d696429afef2855a97 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 12:13:03 -0300 Subject: [PATCH 004/177] fix: Now when deleting the instance, the data referring to it in mongodb is also deleted --- CHANGELOG.md | 1 + src/whatsapp/services/monitor.service.ts | 31 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 875d7ac4..2311edac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fix in update settings that needed to restart after updated * Correction in the use of the api with mongodb * Adjustments to search endpoint for contacts, chats, messages and Status messages +* Now when deleting the instance, the data referring to it in mongodb is also deleted # 1.3.1 (2023-07-20 07:48) diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 8fdac88a..6aa43b70 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -18,6 +18,16 @@ import { Db } from 'mongodb'; import { initInstance } from '../whatsapp.module'; import { RedisCache } from '../../db/redis.client'; import { execSync } from 'child_process'; +import { dbserver } from '../../db/db.connect'; +import mongoose from 'mongoose'; +import { + AuthModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + WebhookModel, +} from '../models'; export class WAMonitoringService { constructor( @@ -45,6 +55,8 @@ export class WAMonitoringService { private dbInstance: Db; + private dbStore = dbserver; + private readonly logger = new Logger(WAMonitoringService.name); public readonly waInstances: Record = {}; @@ -218,11 +230,8 @@ export class WAMonitoringService { } public async cleaningStoreFiles(instanceName: string) { - this.logger.verbose('cleaning store files instance: ' + instanceName); - if (!this.db.ENABLED) { - const instance = this.waInstances[instanceName]; - + this.logger.verbose('cleaning store files instance: ' + instanceName); rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); @@ -233,7 +242,21 @@ export class WAMonitoringService { execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); + + return; } + + this.logger.verbose('cleaning store database instance: ' + instanceName); + + await AuthModel.deleteMany({ owner: instanceName }); + await ContactModel.deleteMany({ owner: instanceName }); + await MessageModel.deleteMany({ owner: instanceName }); + await MessageUpModel.deleteMany({ owner: instanceName }); + await AuthModel.deleteMany({ _id: instanceName }); + await WebhookModel.deleteMany({ _id: instanceName }); + await ChatwootModel.deleteMany({ _id: instanceName }); + + return; } public async loadInstance() { From d7f264c1c2265d145b0ca0542cd1984600974080 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 12:26:43 -0300 Subject: [PATCH 005/177] fix: It is now validated if the instance name contains uppercase and special characters --- CHANGELOG.md | 1 + src/whatsapp/controllers/instance.controller.ts | 6 ++++++ src/whatsapp/services/whatsapp.service.ts | 2 -- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2311edac..d9b5ac6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Correction in the use of the api with mongodb * Adjustments to search endpoint for contacts, chats, messages and Status messages * Now when deleting the instance, the data referring to it in mongodb is also deleted +* It is now validated if the instance name contains uppercase and special characters # 1.3.1 (2023-07-20 07:48) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index f0adb3a3..ef0c00aa 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -42,6 +42,12 @@ export class InstanceController { }: InstanceDto) { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException( + 'The instance name must be lowercase and without special characters', + ); + } + const mode = this.configService.get('AUTHENTICATION').INSTANCE.MODE; if (mode === 'container') { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 8035bbfb..549dd7d6 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1412,8 +1412,6 @@ export class WAStartupService { } if (Number(countryCode) === 52 || Number(countryCode) === 54) { - console.log('numero mexicano'); - const formattedMXARNumber = this.formatMXOrARNumber(number); if (formattedMXARNumber !== number) { From 091b920a222821b20290ad76650c49b7cbd62f99 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 12:40:58 -0300 Subject: [PATCH 006/177] fix: It is now validated if the instance name contains uppercase and special characters --- src/whatsapp/repository/repository.manager.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index aa0fbd65..6c2a3091 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -55,7 +55,6 @@ export class RepositoryBroker { const chatwootDir = join(storePath, 'chatwoot'); const tempDir = join(storePath, 'temp'); - // Check if directories exist, create them if not if (!fs.existsSync(authDir)) { this.logger.verbose('creating auth dir: ' + authDir); fs.mkdirSync(authDir, { recursive: true }); @@ -91,6 +90,21 @@ export class RepositoryBroker { } catch (error) { this.logger.error(error); } + } else { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + try { + } catch (error) { + this.logger.error(error); + } } } } From 19039aa281a3a192f833572f8b2355877f88cf73 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 13:12:55 -0300 Subject: [PATCH 007/177] fix: For compatibility reasons, container mode has been removed --- CHANGELOG.md | 1 + Docker/.env.example | 10 - src/config/env.config.ts | 19 +- src/dev-env.yml | 12 +- .../controllers/instance.controller.ts | 375 ++++++------------ src/whatsapp/services/monitor.service.ts | 4 - src/whatsapp/services/whatsapp.service.ts | 11 +- src/whatsapp/whatsapp.module.ts | 107 ----- 8 files changed, 121 insertions(+), 418 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9b5ac6b..2a864fe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Adjustments to search endpoint for contacts, chats, messages and Status messages * Now when deleting the instance, the data referring to it in mongodb is also deleted * It is now validated if the instance name contains uppercase and special characters +* For compatibility reasons, container mode has been removed # 1.3.1 (2023-07-20 07:48) diff --git a/Docker/.env.example b/Docker/.env.example index 81eee8ca..a3782d4e 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -97,13 +97,3 @@ AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true # seconds - 3600s ===1h | zero (0) - never expires AUTHENTICATION_JWT_EXPIRIN_IN=0 AUTHENTICATION_JWT_SECRET='L0YWtjb2w554WFqPG' -# Set the instance name and webhook url to create an instance in init the application -# With this option activated, you work with a url per webhook event, respecting the local url and the name of each event -# container or server -AUTHENTICATION_INSTANCE_MODE=server -# if you are using container mode, set the container name and the webhook url to default instance -AUTHENTICATION_INSTANCE_NAME=evolution -AUTHENTICATION_INSTANCE_WEBHOOK_URL='' -AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 -AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 -AUTHENTICATION_INSTANCE_CHATWOOT_URL='' diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 7221f474..88b718de 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -94,20 +94,12 @@ export type EventsWebhook = { export type ApiKey = { KEY: string }; export type Jwt = { EXPIRIN_IN: number; SECRET: string }; -export type Instance = { - NAME: string; - WEBHOOK_URL: string; - MODE: string; - CHATWOOT_ACCOUNT_ID: string; - CHATWOOT_TOKEN: string; - CHATWOOT_URL: string; -}; + export type Auth = { API_KEY: ApiKey; EXPOSE_IN_FETCH_INSTANCES: boolean; JWT: Jwt; TYPE: 'jwt' | 'apikey'; - INSTANCE: Instance; }; export type DelInstance = number | boolean; @@ -276,15 +268,6 @@ export class ConfigService { : 3600, SECRET: process.env.AUTHENTICATION_JWT_SECRET, }, - INSTANCE: { - NAME: process.env.AUTHENTICATION_INSTANCE_NAME, - WEBHOOK_URL: process.env.AUTHENTICATION_INSTANCE_WEBHOOK_URL, - MODE: process.env.AUTHENTICATION_INSTANCE_MODE, - CHATWOOT_ACCOUNT_ID: - process.env.AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID || '', - CHATWOOT_TOKEN: process.env.AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN || '', - CHATWOOT_URL: process.env.AUTHENTICATION_INSTANCE_CHATWOOT_URL || '', - }, }, }; } diff --git a/src/dev-env.yml b/src/dev-env.yml index c0f907fc..41368ea4 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -136,14 +136,4 @@ AUTHENTICATION: # Set the secret key to encrypt and decrypt your token and its expiration time. JWT: EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires - SECRET: L=0YWt]b2w[WF>#>:&E` - # Set the instance name and webhook url to create an instance in init the application - INSTANCE: - # With this option activated, you work with a url per webhook event, respecting the local url and the name of each event - MODE: server # container or server - # if you are using container mode, set the container name and the webhook url to default instance - NAME: evolution - WEBHOOK_URL: - CHATWOOT_ACCOUNT_ID: 1 - CHATWOOT_TOKEN: 123456 - CHATWOOT_URL: + SECRET: L=0YWt]b2w[WF>#>:&E` \ No newline at end of file diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index ef0c00aa..75911848 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -48,273 +48,80 @@ export class InstanceController { ); } - const mode = this.configService.get('AUTHENTICATION').INSTANCE.MODE; + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); - if (mode === 'container') { - this.logger.verbose('container mode'); + this.logger.verbose('creating instance'); + const instance = new WAStartupService( + this.configService, + this.eventEmitter, + this.repository, + this.cache, + ); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); - if (Object.keys(this.waMonitor.waInstances).length > 0) { - throw new BadRequestException([ - 'Instance already created', - 'Only one instance can be created', - ]); + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + let getEvents: string[]; + + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); } - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); - - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } - - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - this.logger.verbose('instance created'); - this.logger.verbose({ - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - events: getEvents, - }); - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - events: getEvents, - }; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - + this.logger.verbose('creating webhook'); try { - this.chatwootService.create(instance, { + this.webhookService.create(instance, { enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, + url: webhook, + events, + webhook_by_events, }); - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - ); + getEvents = (await this.webhookService.find(instance)).events; } catch (error) { this.logger.log(error); } + } - return { + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(); + await delay(2000); + getQrcode = instance.qrCode; + } + + this.logger.verbose('instance created'); + this.logger.verbose({ instance: { instanceName: instance.instanceName, status: 'created', }, hash, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; - } else { - this.logger.verbose('server mode'); - - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } - - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); - - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } - - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(); - await delay(2000); - getQrcode = instance.qrCode; - } - - this.logger.verbose('instance created'); - this.logger.verbose({ - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - qrcode: getQrcode, - }); - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - qrcode: getQrcode, - }; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - ); - } catch (error) { - this.logger.log(error); - } + webhook, + webhook_by_events, + events: getEvents, + qrcode: getQrcode, + }); return { instance: { @@ -325,17 +132,67 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, + qrcode: getQrcode, }; } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + }); + + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + ); + } catch (error) { + this.logger.log(error); + } + + return { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, + }; } public async connectToWhatsapp({ instanceName }: InstanceDto) { diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 6aa43b70..6c31ad58 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -15,7 +15,6 @@ import { import { RepositoryBroker } from '../repository/repository.manager'; import { NotFoundException } from '../../exceptions'; import { Db } from 'mongodb'; -import { initInstance } from '../whatsapp.module'; import { RedisCache } from '../../db/redis.client'; import { execSync } from 'child_process'; import { dbserver } from '../../db/db.connect'; @@ -287,7 +286,6 @@ export class WAMonitoringService { keys.forEach(async (k) => await set(k.split(':')[1])); } else { this.logger.verbose('no instance keys found'); - initInstance(); } return; } @@ -303,7 +301,6 @@ export class WAMonitoringService { ); } else { this.logger.verbose('no collections found'); - initInstance(); } return; } @@ -324,7 +321,6 @@ export class WAMonitoringService { await set(dirent.name); } else { this.logger.verbose('no instance files found'); - initInstance(); } } } catch (error) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 549dd7d6..3851f067 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -346,7 +346,6 @@ export class WAStartupService { const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[\.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - const instance = this.configService.get('AUTHENTICATION').INSTANCE; const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; @@ -355,7 +354,7 @@ export class WAStartupService { const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - if (local && instance.MODE !== 'container') { + if (local) { if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { this.logger.verbose('Sending data to webhook local'); let baseURL; @@ -432,13 +431,7 @@ export class WAStartupService { globalURL = globalWebhook.URL; } - let localUrl; - - if (instance.MODE === 'container') { - localUrl = instance.WEBHOOK_URL; - } else { - localUrl = this.localWebhook.url; - } + const localUrl = this.localWebhook.url; if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { const logData = { diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index dbc80427..c91ee9c4 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -91,111 +91,4 @@ export const sendMessageController = new SendMessageController(waMonitor); export const chatController = new ChatController(waMonitor); export const groupController = new GroupController(waMonitor); -export async function initInstance() { - const instance = new WAStartupService(configService, eventEmitter, repository, cache); - - const mode = configService.get('AUTHENTICATION').INSTANCE.MODE; - - logger.verbose('Sending data webhook for event: ' + Events.APPLICATION_STARTUP); - instance.sendDataWebhook( - Events.APPLICATION_STARTUP, - { - message: 'Application startup', - mode, - }, - false, - ); - - if (mode === 'container') { - logger.verbose('Application startup in container mode'); - - const instanceName = configService.get('AUTHENTICATION').INSTANCE.NAME; - logger.verbose('Instance name: ' + instanceName); - - const instanceWebhook = - configService.get('AUTHENTICATION').INSTANCE.WEBHOOK_URL; - logger.verbose('Instance webhook: ' + instanceWebhook); - - // const chatwootAccountId = - // configService.get('AUTHENTICATION').INSTANCE.CHATWOOT_ACCOUNT_ID; - // logger.verbose('Chatwoot account id: ' + chatwootAccountId); - - // const chatwootToken = - // configService.get('AUTHENTICATION').INSTANCE.CHATWOOT_TOKEN; - // logger.verbose('Chatwoot token: ' + chatwootToken); - - // const chatwootUrl = configService.get('AUTHENTICATION').INSTANCE.CHATWOOT_URL; - // logger.verbose('Chatwoot url: ' + chatwootUrl); - - instance.instanceName = instanceName; - - waMonitor.waInstances[instance.instanceName] = instance; - waMonitor.delInstanceTime(instance.instanceName); - - const hash = await authService.generateHash({ - instanceName: instance.instanceName, - token: configService.get('AUTHENTICATION').API_KEY.KEY, - }); - logger.verbose('Hash generated: ' + hash); - - if (instanceWebhook) { - logger.verbose('Creating webhook for instance: ' + instanceName); - try { - webhookService.create(instance, { enabled: true, url: instanceWebhook }); - logger.verbose('Webhook created'); - } catch (error) { - logger.log(error); - } - } - - // if (chatwootUrl && chatwootToken && chatwootAccountId) { - // logger.verbose('Creating chatwoot for instance: ' + instanceName); - // try { - // chatwootService.create(instance, { - // enabled: true, - // url: chatwootUrl, - // token: chatwootToken, - // account_id: chatwootAccountId, - // sign_msg: false, - // }); - // logger.verbose('Chatwoot created'); - // } catch (error) { - // logger.log(error); - // } - // } - - try { - const state = instance.connectionStatus?.state; - - switch (state) { - case 'close': - await instance.connectToWhatsapp(); - await delay(2000); - return instance.qrCode; - case 'connecting': - return instance.qrCode; - default: - return await this.connectionState({ instanceName }); - } - } catch (error) { - logger.log(error); - } - - const result = { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook: instanceWebhook, - }; - - logger.info(result); - - return result; - } - - return null; -} - logger.info('Module - ON'); From f847f38812fe4d5de3be8681557ebf2196bd6d25 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 15:13:49 -0300 Subject: [PATCH 008/177] fix: added docker-compose files example --- Docker/.env.example | 24 ++--- Dockerfile | 4 +- ...ompose.yaml => docker-compose.yaml.example | 2 + docker-compose.yaml.example.complete | 88 +++++++++++++++++++ 4 files changed, 104 insertions(+), 14 deletions(-) rename docker-compose.yaml => docker-compose.yaml.example (92%) create mode 100644 docker-compose.yaml.example.complete diff --git a/Docker/.env.example b/Docker/.env.example index a3782d4e..c3dbe505 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -1,13 +1,13 @@ # Server URL - Set your application url -SERVER_URL='http://localhost:8080' +SERVER_URL=http://localhost:8080 # Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com' -CORS_ORIGIN='*' -CORS_METHODS='POST,GET,PUT,DELETE' +CORS_ORIGIN=* +CORS_METHODS=POST,GET,PUT,DELETE CORS_CREDENTIALS=true # Determine the logs to be displayed -LOG_LEVEL='ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS' +LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS LOG_COLOR=true # Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace" LOG_BAILEYS=error @@ -31,9 +31,9 @@ CLEAN_STORE_CONTACTS=true CLEAN_STORE_CHATS=true # Permanent data storage -DATABASE_ENABLED=false +DATABASE_ENABLED=true DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true -DATABASE_CONNECTION_DB_PREFIX_NAME=evolution +DATABASE_CONNECTION_DB_PREFIX_NAME=evdocker # Choose the data you want to save in the application's database or store DATABASE_SAVE_DATA_INSTANCE=false @@ -42,9 +42,9 @@ DATABASE_SAVE_MESSAGE_UPDATE=false DATABASE_SAVE_DATA_CONTACTS=false DATABASE_SAVE_DATA_CHATS=false -REDIS_ENABLED=false +REDIS_ENABLED=true REDIS_URI=redis://redis:6379 -REDIS_PREFIX_KEY=evolution +REDIS_PREFIX_KEY=evdocker # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created @@ -77,7 +77,7 @@ WEBHOOK_EVENTS_CONNECTION_UPDATE=true WEBHOOK_EVENTS_NEW_JWT_TOKEN=false # Name that will be displayed on smartphone connection -CONFIG_SESSION_PHONE_CLIENT='Evolution API' +CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI # Browser Name = chrome | firefox | edge | opera | safari CONFIG_SESSION_PHONE_NAME=chrome @@ -88,12 +88,12 @@ QRCODE_LIMIT=30 # We recommend using the apikey because it will allow you to use a custom token, # if you use jwt, a random token will be generated and may be expired and you will have to generate a new token # jwt or 'apikey' -AUTHENTICATION_TYPE='apikey' +AUTHENTICATION_TYPE=apikey ## Define a global apikey to access all instances. ### OBS: This key must be inserted in the request header to create an instance. -AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976' +AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976 AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true ## Set the secret key to encrypt and decrypt your token and its expiration time # seconds - 3600s ===1h | zero (0) - never expires AUTHENTICATION_JWT_EXPIRIN_IN=0 -AUTHENTICATION_JWT_SECRET='L0YWtjb2w554WFqPG' +AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`' diff --git a/Dockerfile b/Dockerfile index 088f6fa1..93fa60c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ COPY ./package.json . ENV DOCKER_ENV=true -ENV SERVER_URL='http://localhost:8080' +ENV SERVER_URL=http://localhost:8080 ENV CORS_ORIGIN=* ENV CORS_METHODS=POST,GET,PUT,DELETE @@ -77,7 +77,7 @@ ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false -ENV CONFIG_SESSION_PHONE_CLIENT='Evolution API' +ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI ENV CONFIG_SESSION_PHONE_NAME=chrome ENV QRCODE_LIMIT=30 diff --git a/docker-compose.yaml b/docker-compose.yaml.example similarity index 92% rename from docker-compose.yaml rename to docker-compose.yaml.example index c6d1bc73..93e04cc0 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml.example @@ -10,6 +10,8 @@ services: volumes: - evolution_instances:/evolution/instances - evolution_store:/evolution/store + networks: + - evolution-net env_file: - ./Docker/.env command: ['node', './dist/src/main.js'] diff --git a/docker-compose.yaml.example.complete b/docker-compose.yaml.example.complete new file mode 100644 index 00000000..23f316c8 --- /dev/null +++ b/docker-compose.yaml.example.complete @@ -0,0 +1,88 @@ +version: '3.3' + +services: + api: + container_name: evolution_api + image: evolution/api:local + restart: always + ports: + - 8080:8080 + volumes: + - evolution_instances:/evolution/instances + - evolution_store:/evolution/store + networks: + - evolution-net + env_file: + - ./Docker/.env + command: ['node', './dist/src/main.js'] + expose: + - 8080 + + mongodb: + container_name: mongodb + image: mongo + restart: always + ports: + - 27017:27017 + environment: + - MONGO_INITDB_ROOT_USERNAME=root + - MONGO_INITDB_ROOT_PASSWORD=root + - PUID=1000 + - PGID=1000 + volumes: + - evolution_mongodb_data:/data/db + - evolution_mongodb_configdb:/data/configdb + networks: + - evolution-net + expose: + - 27017 + + mongo-express: + image: mongo-express + networks: + - evolution-net + environment: + ME_CONFIG_BASICAUTH_USERNAME: root + ME_CONFIG_BASICAUTH_PASSWORD: root + ME_CONFIG_MONGODB_SERVER: mongodb + ME_CONFIG_MONGODB_ADMINUSERNAME: root + ME_CONFIG_MONGODB_ADMINPASSWORD: root + ports: + - 8081:8081 + links: + - mongodb + + redis: + image: redis:latest + container_name: redis + command: > + redis-server + --port 6379 + --appendonly yes + volumes: + - evolution_redis:/data + networks: + - evolution-net + ports: + - 6379:6379 + + rebrow: + image: marian/rebrow + networks: + - evolution-net + ports: + - 5001:5001 + links: + - redis + +volumes: + evolution_instances: + evolution_store: + evolution_mongodb_data: + evolution_mongodb_configdb: + evolution_redis: + +networks: + evolution-net: + external: true + \ No newline at end of file From b2ccf965bb75e6933df5e870c7fd3e3d2b38f60a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 15:14:46 -0300 Subject: [PATCH 009/177] fix: added docker-compose files example --- .gitignore | 2 ++ CHANGELOG.md | 1 + 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e707b33e..69d60b7a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ lerna-debug.log* /docker-compose-data /docker-data +docker-compose.yaml + # Package /yarn.lock /package-lock.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a864fe5..5da5cdb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Now when deleting the instance, the data referring to it in mongodb is also deleted * It is now validated if the instance name contains uppercase and special characters * For compatibility reasons, container mode has been removed +* Added docker-compose files example # 1.3.1 (2023-07-20 07:48) From 683fe4c3db06c6899cdb0b6bad235d91ea07612b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 16:00:58 -0300 Subject: [PATCH 010/177] fix: added docker-compose files example --- Docker/redis/docker-compose.yaml | 7 ------- docker-compose.yaml.example.complete | 9 --------- 2 files changed, 16 deletions(-) diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index 6409b851..b0bb5985 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -12,13 +12,6 @@ services: - evolution_redis:/data ports: - 6379:6379 - - rebrow: - image: marian/rebrow - ports: - - 5001:5001 - links: - - redis volumes: evolution_redis: diff --git a/docker-compose.yaml.example.complete b/docker-compose.yaml.example.complete index 23f316c8..4e453b51 100644 --- a/docker-compose.yaml.example.complete +++ b/docker-compose.yaml.example.complete @@ -66,15 +66,6 @@ services: ports: - 6379:6379 - rebrow: - image: marian/rebrow - networks: - - evolution-net - ports: - - 5001:5001 - links: - - redis - volumes: evolution_instances: evolution_store: From d0fa3b92f8eac6e76131ab96b23206e7b3bcc61a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 17:19:59 -0300 Subject: [PATCH 011/177] version: 1.3.2 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da5cdb6..0c1be220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.3.2 (homolog) +# 1.3.2 (2023-07-21 17:19) ### Fixed From 8f4d44a21212cf3d075b93c3cb2fae5a6acdaf88 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 20:37:58 -0300 Subject: [PATCH 012/177] Added connection functionality via pairing code --- CHANGELOG.md | 6 +++++ package.json | 2 +- src/validate/validate.schema.ts | 1 + .../controllers/instance.controller.ts | 22 +++++++++++++++++-- src/whatsapp/dto/instance.dto.ts | 1 + src/whatsapp/routers/instance.router.ts | 3 ++- src/whatsapp/services/whatsapp.service.ts | 5 +++++ src/whatsapp/types/wa.types.ts | 6 ++++- 8 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c1be220..8d56ec43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.0 (homolog) + +### Features + +* Added connection functionality via pairing code + # 1.3.2 (2023-07-21 17:19) ### Fixed diff --git a/package.json b/package.json index 7bc6f476..92745ead 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.3.2", + "version": "1.4.0", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 2b9ce19a..ed7ab2e0 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -58,6 +58,7 @@ export const instanceNameSchema: JSONSchema7 = { }, }, qrcode: { type: 'boolean', enum: [true, false] }, + number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, token: { type: 'string' }, }, ...isNotEmpty('instanceName'), diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 75911848..b54858b2 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -34,6 +34,7 @@ export class InstanceController { webhook_by_events, events, qrcode, + number, token, chatwoot_account_id, chatwoot_token, @@ -102,10 +103,16 @@ export class InstanceController { if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; + let getParingCode: string; if (qrcode) { this.logger.verbose('creating qrcode'); await instance.connectToWhatsapp(); + if (number) { + this.logger.verbose('creating number'); + await delay(5000); + getParingCode = await instance.client.requestPairingCode(number); + } await delay(2000); getQrcode = instance.qrCode; } @@ -120,6 +127,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + pairingCode: getParingCode, qrcode: getQrcode, }); @@ -132,6 +140,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + pairingCode: getParingCode, qrcode: getQrcode, }; } @@ -195,7 +204,7 @@ export class InstanceController { }; } - public async connectToWhatsapp({ instanceName }: InstanceDto) { + public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { try { this.logger.verbose( 'requested connectToWhatsapp from ' + instanceName + ' instance', @@ -210,8 +219,17 @@ export class InstanceController { case 'close': this.logger.verbose('connecting'); await instance.connectToWhatsapp(); + let pairingCode = null; + if (number) { + this.logger.verbose('creating pairing code'); + await delay(5000); + pairingCode = await instance.client.requestPairingCode(number); + } await delay(2000); - return instance.qrCode; + return { + pairingCode, + ...instance.qrCode, + }; case 'connecting': return instance.qrCode; default: diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index ce282e03..9e8a7ec3 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -4,6 +4,7 @@ export class InstanceDto { webhook_by_events?: boolean; events?: string[]; qrcode?: boolean; + number?: string; token?: string; chatwoot_account_id?: string; chatwoot_token?: string; diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 850ffebd..a984a89c 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -60,7 +60,8 @@ export class InstanceRouter extends RouterBroker { request: req, schema: instanceNameSchema, ClassRef: InstanceDto, - execute: (instance) => instanceController.connectToWhatsapp(instance), + execute: (instance, data) => + instanceController.connectToWhatsapp(instance, data), }); return res.status(HttpStatus.OK).json(response); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3851f067..ab94d691 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -545,6 +545,11 @@ export class WAStartupService { return this.eventEmitter.emit('no.connection', this.instance.name); } + // pairing code + // await delay(5000); + // const code = await this.client.requestPairingCode('557499879409'); + // console.log(`Pairing code: ${code}`); + this.logger.verbose('Incrementing QR code count'); this.instance.qrcode.count++; diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 6869545f..fc71de31 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -25,7 +25,11 @@ export enum Events { } export declare namespace wa { - export type QrCode = { count?: number; base64?: string; code?: string }; + export type QrCode = { + count?: number; + base64?: string; + code?: string; + }; export type Instance = { qrcode?: QrCode; authState?: { state: AuthenticationState; saveCreds: () => void }; From b681e339444859ba94f6d3d9432642873bb54a07 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 20:38:10 -0300 Subject: [PATCH 013/177] Added connection functionality via pairing code --- src/whatsapp/routers/instance.router.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index a984a89c..850ffebd 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -60,8 +60,7 @@ export class InstanceRouter extends RouterBroker { request: req, schema: instanceNameSchema, ClassRef: InstanceDto, - execute: (instance, data) => - instanceController.connectToWhatsapp(instance, data), + execute: (instance) => instanceController.connectToWhatsapp(instance), }); return res.status(HttpStatus.OK).json(response); From 16ed5821e277a4128026bcf8137448dfbc5db9da Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 21 Jul 2023 20:58:37 -0300 Subject: [PATCH 014/177] Added connection functionality via pairing code --- .../controllers/instance.controller.ts | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index b54858b2..9b938ab0 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -103,7 +103,7 @@ export class InstanceController { if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; - let getParingCode: string; + let getPairingCode: string; if (qrcode) { this.logger.verbose('creating qrcode'); @@ -111,14 +111,13 @@ export class InstanceController { if (number) { this.logger.verbose('creating number'); await delay(5000); - getParingCode = await instance.client.requestPairingCode(number); + getPairingCode = await instance.client.requestPairingCode(number); } await delay(2000); getQrcode = instance.qrCode; } - this.logger.verbose('instance created'); - this.logger.verbose({ + const result = { instance: { instanceName: instance.instanceName, status: 'created', @@ -127,22 +126,18 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, - pairingCode: getParingCode, - qrcode: getQrcode, - }); - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - pairingCode: getParingCode, - qrcode: getQrcode, }; + + if (getPairingCode) { + result['pairingCode'] = getPairingCode; + } else { + result['qrcode'] = getQrcode; + } + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; } if (!chatwoot_account_id) { @@ -225,11 +220,15 @@ export class InstanceController { await delay(5000); pairingCode = await instance.client.requestPairingCode(number); } + + if (pairingCode) { + return { + pairingCode, + }; + } + await delay(2000); - return { - pairingCode, - ...instance.qrCode, - }; + return instance.qrCode; case 'connecting': return instance.qrCode; default: From 90048afa9d1bb700380c3b28497241a8a386607a Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Sun, 23 Jul 2023 11:24:16 -0300 Subject: [PATCH 015/177] Add LinkPreview Option --- src/whatsapp/dto/sendMessage.dto.ts | 1 + src/whatsapp/services/whatsapp.service.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 51a55cec..0a20674c 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -15,6 +15,7 @@ export class Options { presence?: WAPresence; quoted?: Quoted; mentions?: Mentions; + linkPreview?: boolean; } class OptionsMessage { options: Options; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3851f067..dd8fa3a5 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1480,6 +1480,8 @@ export class WAStartupService { this.logger.verbose('Sending presence update: paused'); } + let linkPreview = (options?.linkPreview != false) ? undefined : false; + let quoted: WAMessage; if (options?.quoted) { @@ -1573,6 +1575,7 @@ export class WAStartupService { { text: message['conversation'], mentions, + linkPreview: linkPreview, } as unknown as AnyMessageContent, option as unknown as MiscMessageGenerationOptions, ); From 76d77ad76f54283fe47aa0376b89897055f73220 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 23 Jul 2023 22:05:21 -0300 Subject: [PATCH 016/177] =?UTF-8?q?Revert=20"Adi=C3=A7=C3=A3o=20de=20Fetch?= =?UTF-8?q?Profile"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/validate/validate.schema.ts | 11 --- src/whatsapp/controllers/chat.controller.ts | 5 -- src/whatsapp/dto/chat.dto.ts | 13 --- src/whatsapp/routers/chat.router.ts | 18 ---- src/whatsapp/services/whatsapp.service.ts | 98 +++------------------ 5 files changed, 11 insertions(+), 134 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 2533e4d7..2b9ce19a 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -587,17 +587,6 @@ export const profilePictureSchema: JSONSchema7 = { }, }; -export const profileSchema: JSONSchema7 = { - type: 'object', - properties: { - wuid: { type: 'string' }, - name: { type: 'string' }, - picture: { type: 'string' }, - status: { type: 'string' }, - isBusiness: { type: 'boolean' }, - }, -}; - export const messageValidateSchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index 2b500ad1..0a176059 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -47,11 +47,6 @@ export class ChatController { logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); } - - public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { - logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number); - } public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 5af66a5e..07757194 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -26,19 +26,6 @@ export class NumberDto { number: string; } -export class NumberBusiness { - wid?: string; - jid?: string; - exists?: boolean; - isBusiness: boolean; - name?: string; - message?: string; - description?: string; - email?: string; - website?: string[]; - address?: string; -} - export class ProfileNameDto { name: string; } diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index 68ecd97e..50ead521 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -8,7 +8,6 @@ import { privacySettingsSchema, profileNameSchema, profilePictureSchema, - profileSchema, profileStatusSchema, readMessageSchema, whatsappNumberSchema, @@ -130,23 +129,6 @@ export class ChatRouter extends RouterBroker { return res.status(HttpStatus.OK).json(response); }) - .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { - logger.verbose('request received in fetchProfile'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - - const response = await this.dataValidate({ - request: req, - schema: profileSchema, - ClassRef: NumberDto, - execute: (instance, data) => chatController.fetchProfile(instance, data), - }); - - return res.status(HttpStatus.OK).json(response); - }) .post(this.routerPath('findContacts'), ...guards, async (req, res) => { logger.verbose('request received in findContacts'); logger.verbose('request body: '); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1cd9035a..3851f067 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -85,7 +85,6 @@ import { ArchiveChatDto, DeleteMessage, OnWhatsAppDto, - NumberBusiness, PrivacySettingDto, ReadMessageDto, WhatsAppNumberDto, @@ -1444,79 +1443,6 @@ export class WAStartupService { }; } } - - public async getStatus(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile status with jid:' + jid); - try { - this.logger.verbose('Getting status'); - return { - wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, - }; - } catch (error) { - this.logger.verbose('Status not found'); - return { - wuid: jid, - status: null, - }; - } - } - - public async fetchProfile(instanceName: string, number?: string) { - const jid = (number) - ? this.createJid(number) - : this.client?.user?.id; - this.logger.verbose('Getting profile with jid: ' + jid); - try { - this.logger.verbose('Getting profile info'); - const business = await this.fetchBusinessProfile(jid); - - if (number) { - const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); - const picture = await this.profilePicture(jid); - const status = await this.getStatus(jid); - - return { - wuid: jid, - name: info?.name, - numberExists: info?.exists, - picture: picture?.profilePictureUrl, - status: status?.status, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } else { - const info = await waMonitor.instanceInfo(instanceName); - - return { - wuid: jid, - name: info?.instance?.profileName, - numberExists: true, - picture: info?.instance?.profilePictureUrl, - status: info?.instance?.profileStatus, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } - - } catch (error) { - this.logger.verbose('Profile not found'); - return { - wuid: jid, - name: null, - picture: null, - status: null, - os: null, - isBusiness: false, - }; - } - } private async sendMessageWithTyping( number: string, @@ -2534,31 +2460,29 @@ export class WAStartupService { } } - public async fetchBusinessProfile(number: string) : Promise { + public async fetchBusinessProfile(number: string) { this.logger.verbose('Fetching business profile'); try { - const jid = (number) - ? this.createJid(number) - : this.instance.wuid; + let jid; + + if (!number) { + jid = this.instance.wuid; + } else { + jid = this.createJid(number); + } const profile = await this.client.getBusinessProfile(jid); this.logger.verbose('Trying to get business profile'); if (!profile) { - const info = await this.whatsappNumber({ numbers: [jid] }); - return { - isBusiness: false, - message: 'Not is business profile', - ...info?.shift() + exists: false, + message: 'Business profile not found', }; } this.logger.verbose('Business profile fetched'); - return { - isBusiness: true, - ...profile - }; + return profile; } catch (error) { throw new InternalServerErrorException( 'Error updating profile name', From 798eb90bed2873be514135512b75d14869777b09 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 23 Jul 2023 22:24:21 -0300 Subject: [PATCH 017/177] feat: Added fetch profile endpoint in chat controller and link preview option in send text message --- CHANGELOG.md | 5 + src/validate/validate.schema.ts | 11 +++ src/whatsapp/controllers/chat.controller.ts | 8 ++ .../controllers/instance.controller.ts | 57 ++++++----- src/whatsapp/dto/chat.dto.ts | 13 +++ src/whatsapp/routers/chat.router.ts | 18 ++++ src/whatsapp/services/whatsapp.service.ts | 99 ++++++++++++++++--- 7 files changed, 176 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d56ec43..cd9ec53d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ ### Features * Added connection functionality via pairing code +* Added fetch profile endpoint in chat controller + +### Fixed + +* Added link preview option in send text message # 1.3.2 (2023-07-21 17:19) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index ed7ab2e0..30763fcd 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -588,6 +588,17 @@ export const profilePictureSchema: JSONSchema7 = { }, }; +export const profileSchema: JSONSchema7 = { + type: 'object', + properties: { + wuid: { type: 'string' }, + name: { type: 'string' }, + picture: { type: 'string' }, + status: { type: 'string' }, + isBusiness: { type: 'boolean' }, + }, +}; + export const messageValidateSchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index 0a176059..454ddabf 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -48,6 +48,14 @@ export class ChatController { return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); } + public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { + logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchProfile( + instanceName, + data.number, + ); + } + public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].fetchContacts(query); diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 9b938ab0..e7827f15 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -210,30 +210,41 @@ export class InstanceController { this.logger.verbose('state: ' + state); - switch (state) { - case 'close': - this.logger.verbose('connecting'); - await instance.connectToWhatsapp(); - let pairingCode = null; - if (number) { - this.logger.verbose('creating pairing code'); - await delay(5000); - pairingCode = await instance.client.requestPairingCode(number); - } - - if (pairingCode) { - return { - pairingCode, - }; - } - - await delay(2000); - return instance.qrCode; - case 'connecting': - return instance.qrCode; - default: - return await this.connectionState({ instanceName }); + if (state == 'open') { + return await this.connectionState({ instanceName }); } + + if (state == 'connecting') { + return instance.qrCode; + } + + if (state == 'close') { + this.logger.verbose('connecting'); + await instance.connectToWhatsapp(); + let pairingCode = null; + if (number) { + this.logger.verbose('creating pairing code'); + await delay(5000); + pairingCode = await instance.client.requestPairingCode(number); + } + + if (pairingCode) { + return { + pairingCode, + }; + } + + await delay(2000); + return instance.qrCode; + } + + return { + instance: { + instanceName: instanceName, + status: state, + }, + qrcode: instance?.qrCode, + }; } catch (error) { this.logger.error(error); } diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 07757194..5af66a5e 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -26,6 +26,19 @@ export class NumberDto { number: string; } +export class NumberBusiness { + wid?: string; + jid?: string; + exists?: boolean; + isBusiness: boolean; + name?: string; + message?: string; + description?: string; + email?: string; + website?: string[]; + address?: string; +} + export class ProfileNameDto { name: string; } diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index 50ead521..49e64117 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -8,6 +8,7 @@ import { privacySettingsSchema, profileNameSchema, profilePictureSchema, + profileSchema, profileStatusSchema, readMessageSchema, whatsappNumberSchema, @@ -129,6 +130,23 @@ export class ChatRouter extends RouterBroker { return res.status(HttpStatus.OK).json(response); }) + .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { + logger.verbose('request received in fetchProfile'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + + const response = await this.dataValidate({ + request: req, + schema: profileSchema, + ClassRef: NumberDto, + execute: (instance, data) => chatController.fetchProfile(instance, data), + }); + + return res.status(HttpStatus.OK).json(response); + }) .post(this.routerPath('findContacts'), ...guards, async (req, res) => { logger.verbose('request received in findContacts'); logger.verbose('request body: '); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3f720dff..128183da 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -84,6 +84,7 @@ import { arrayUnique, isBase64, isURL } from 'class-validator'; import { ArchiveChatDto, DeleteMessage, + NumberBusiness, OnWhatsAppDto, PrivacySettingDto, ReadMessageDto, @@ -1449,6 +1450,78 @@ export class WAStartupService { } } + public async getStatus(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile status with jid:' + jid); + try { + this.logger.verbose('Getting status'); + return { + wuid: jid, + status: (await this.client.fetchStatus(jid))?.status, + }; + } catch (error) { + this.logger.verbose('Status not found'); + return { + wuid: jid, + status: null, + }; + } + } + + public async fetchProfile(instanceName: string, number?: string) { + const jid = number ? this.createJid(number) : this.client?.user?.id; + + this.logger.verbose('Getting profile with jid: ' + jid); + try { + this.logger.verbose('Getting profile info'); + const info = await waMonitor.instanceInfo(instanceName); + const business = await this.fetchBusinessProfile(jid); + + if (number) { + const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); + const picture = await this.profilePicture(jid); + const status = await this.getStatus(jid); + + return { + wuid: jid, + name: info?.name, + numberExists: info?.exists, + picture: picture?.profilePictureUrl, + status: status?.status, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } else { + const info = await waMonitor.instanceInfo(instanceName); + + return { + wuid: jid, + name: info?.instance?.profileName, + numberExists: true, + picture: info?.instance?.profilePictureUrl, + status: info?.instance?.profileStatus, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } + } catch (error) { + this.logger.verbose('Profile not found'); + return { + wuid: jid, + name: null, + picture: null, + status: null, + os: null, + isBusiness: false, + }; + } + } + private async sendMessageWithTyping( number: string, message: T, @@ -1485,7 +1558,9 @@ export class WAStartupService { this.logger.verbose('Sending presence update: paused'); } - let linkPreview = (options?.linkPreview != false) ? undefined : false; + const linkPreview = options?.linkPreview != false ? undefined : false; + + console.log('linkPreview', linkPreview); let quoted: WAMessage; @@ -2468,29 +2543,29 @@ export class WAStartupService { } } - public async fetchBusinessProfile(number: string) { + public async fetchBusinessProfile(number: string): Promise { this.logger.verbose('Fetching business profile'); try { - let jid; - - if (!number) { - jid = this.instance.wuid; - } else { - jid = this.createJid(number); - } + const jid = number ? this.createJid(number) : this.instance.wuid; const profile = await this.client.getBusinessProfile(jid); this.logger.verbose('Trying to get business profile'); if (!profile) { + const info = await this.whatsappNumber({ numbers: [jid] }); + return { - exists: false, - message: 'Business profile not found', + isBusiness: false, + message: 'Not is business profile', + ...info?.shift(), }; } this.logger.verbose('Business profile fetched'); - return profile; + return { + isBusiness: true, + ...profile, + }; } catch (error) { throw new InternalServerErrorException( 'Error updating profile name', From be699d24a1d31b17670293564b1c937d1255fc4b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 23 Jul 2023 22:26:38 -0300 Subject: [PATCH 018/177] feat: Added fetch profile endpoint in chat controller and link preview option in send text message --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd9ec53d..fed20ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ * Added link preview option in send text message +### Integrations + +- Chatwoot: v2.18.0 + # 1.3.2 (2023-07-21 17:19) ### Fixed @@ -21,12 +25,20 @@ * For compatibility reasons, container mode has been removed * Added docker-compose files example +### Integrations + +- Chatwoot: v2.18.0 + # 1.3.1 (2023-07-20 07:48) ### Fixed * Adjust in create store files +### Integrations + +- Chatwoot: v2.18.0 + # 1.3.0 (2023-07-19 11:33) ### Features From 73d9cd62a56d56c070c54ccf39134b6e63f9a6c5 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 09:42:29 -0300 Subject: [PATCH 019/177] feat: Created settings Controller --- CHANGELOG.md | 1 + src/validate/validate.schema.ts | 12 +++ .../controllers/settings.controller.ts | 29 +++++++ src/whatsapp/dto/settings.dto.ts | 5 ++ src/whatsapp/models/index.ts | 1 + src/whatsapp/models/settings.model.ts | 23 ++++++ src/whatsapp/repository/repository.manager.ts | 8 +- .../repository/settings.repository.ts | 75 +++++++++++++++++++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/routers/settings.router.ts | 52 +++++++++++++ src/whatsapp/services/settings.service.ts | 34 +++++++++ src/whatsapp/services/whatsapp.service.ts | 43 +++++++++++ src/whatsapp/types/wa.types.ts | 6 ++ src/whatsapp/whatsapp.module.ts | 10 +++ 14 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 src/whatsapp/controllers/settings.controller.ts create mode 100644 src/whatsapp/dto/settings.dto.ts create mode 100644 src/whatsapp/models/settings.model.ts create mode 100644 src/whatsapp/repository/settings.repository.ts create mode 100644 src/whatsapp/routers/settings.router.ts create mode 100644 src/whatsapp/services/settings.service.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index fed20ae3..ea7401df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Added connection functionality via pairing code * Added fetch profile endpoint in chat controller +* Created settings controller ### Fixed diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 30763fcd..a2a8ef13 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -877,3 +877,15 @@ export const chatwootSchema: JSONSchema7 = { required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), }; + +export const settingsSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + reject_call: { type: 'boolean', enum: [true, false] }, + msg_call: { type: 'string' }, + groups_ignore: { type: 'boolean', enum: [true, false] }, + }, + required: ['reject_call'], + ...isNotEmpty('reject_call'), +}; diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts new file mode 100644 index 00000000..59031634 --- /dev/null +++ b/src/whatsapp/controllers/settings.controller.ts @@ -0,0 +1,29 @@ +import { isURL } from 'class-validator'; +import { BadRequestException } from '../../exceptions'; +import { InstanceDto } from '../dto/instance.dto'; +import { SettingsDto } from '../dto/settings.dto'; +import { SettingsService } from '../services/settings.service'; +import { Logger } from '../../config/logger.config'; + +const logger = new Logger('SettingsController'); + +export class SettingsController { + constructor(private readonly settingsService: SettingsService) {} + + public async createSettings(instance: InstanceDto, data: SettingsDto) { + logger.verbose( + 'requested createSettings from ' + instance.instanceName + ' instance', + ); + + if (data.reject_call && data.msg_call.trim() == '') { + throw new BadRequestException('msg_call is required'); + } + + return this.settingsService.create(instance, data); + } + + public async findSettings(instance: InstanceDto) { + logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); + return this.settingsService.find(instance); + } +} diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts new file mode 100644 index 00000000..20a6cba0 --- /dev/null +++ b/src/whatsapp/dto/settings.dto.ts @@ -0,0 +1,5 @@ +export class SettingsDto { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; +} diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index e0b773f0..e6c6d8b4 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -4,3 +4,4 @@ export * from './message.model'; export * from './auth.model'; export * from './webhook.model'; export * from './chatwoot.model'; +export * from './settings.model'; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts new file mode 100644 index 00000000..b5eb7fe7 --- /dev/null +++ b/src/whatsapp/models/settings.model.ts @@ -0,0 +1,23 @@ +import { Schema } from 'mongoose'; +import { dbserver } from '../../db/db.connect'; + +export class SettingsRaw { + _id?: string; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; +} + +const settingsSchema = new Schema({ + _id: { type: String, _id: true }, + reject_call: { type: Boolean, required: true }, + msg_call: { type: String, required: true }, + groups_ignore: { type: Boolean, required: true }, +}); + +export const SettingsModel = dbserver?.model( + SettingsRaw.name, + settingsSchema, + 'settings', +); +export type ISettingsModel = typeof SettingsModel; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 6c2a3091..dde636c7 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -5,10 +5,10 @@ import { MessageUpRepository } from './messageUp.repository'; import { MongoClient } from 'mongodb'; import { WebhookRepository } from './webhook.repository'; import { ChatwootRepository } from './chatwoot.repository'; +import { SettingsRepository } from './settings.repository'; import { AuthRepository } from './auth.repository'; import { Auth, ConfigService, Database } from '../../config/env.config'; -import { execSync } from 'child_process'; import { join } from 'path'; import fs from 'fs'; import { Logger } from '../../config/logger.config'; @@ -20,6 +20,7 @@ export class RepositoryBroker { public readonly messageUpdate: MessageUpRepository, public readonly webhook: WebhookRepository, public readonly chatwoot: ChatwootRepository, + public readonly settings: SettingsRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -53,6 +54,7 @@ export class RepositoryBroker { const messageUpDir = join(storePath, 'message-up'); const webhookDir = join(storePath, 'webhook'); const chatwootDir = join(storePath, 'chatwoot'); + const settingsDir = join(storePath, 'settings'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -83,6 +85,10 @@ export class RepositoryBroker { this.logger.verbose('creating chatwoot dir: ' + chatwootDir); fs.mkdirSync(chatwootDir, { recursive: true }); } + if (!fs.existsSync(settingsDir)) { + this.logger.verbose('creating settings dir: ' + settingsDir); + fs.mkdirSync(settingsDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/repository/settings.repository.ts b/src/whatsapp/repository/settings.repository.ts new file mode 100644 index 00000000..d253643d --- /dev/null +++ b/src/whatsapp/repository/settings.repository.ts @@ -0,0 +1,75 @@ +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ConfigService } from '../../config/env.config'; +import { join } from 'path'; +import { readFileSync } from 'fs'; +import { ISettingsModel, SettingsRaw } from '../models'; +import { Logger } from '../../config/logger.config'; + +export class SettingsRepository extends Repository { + constructor( + private readonly settingsModel: ISettingsModel, + private readonly configService: ConfigService, + ) { + super(configService); + } + + private readonly logger = new Logger('SettingsRepository'); + + public async create(data: SettingsRaw, instance: string): Promise { + try { + this.logger.verbose('creating settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving settings to db'); + const insert = await this.settingsModel.replaceOne( + { _id: instance }, + { ...data }, + { upsert: true }, + ); + + this.logger.verbose( + 'settings saved to db: ' + insert.modifiedCount + ' settings', + ); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving settings to store'); + + this.writeStore({ + path: join(this.storePath, 'settings'), + fileName: instance, + data, + }); + + this.logger.verbose( + 'settings saved to store in path: ' + + join(this.storePath, 'settings') + + '/' + + instance, + ); + + this.logger.verbose('settings created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding settings in db'); + return await this.settingsModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding settings in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'settings', instance + '.json'), { + encoding: 'utf-8', + }), + ) as SettingsRaw; + } catch (error) { + return {}; + } + } +} diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 5d8a2c05..4cf7befb 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -10,6 +10,7 @@ import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; import { ChatwootRouter } from './chatwoot.router'; import fs from 'fs'; +import { SettingsRouter } from './settings.router'; enum HttpStatus { OK = 200, @@ -44,6 +45,7 @@ router .use('/chat', new ChatRouter(...guards).router) .use('/group', new GroupRouter(...guards).router) .use('/webhook', new WebhookRouter(...guards).router) - .use('/chatwoot', new ChatwootRouter(...guards).router); + .use('/chatwoot', new ChatwootRouter(...guards).router) + .use('/settings', new SettingsRouter(...guards).router); export { router, HttpStatus }; diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts new file mode 100644 index 00000000..3ec3df83 --- /dev/null +++ b/src/whatsapp/routers/settings.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; +import { instanceNameSchema, settingsSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { SettingsDto } from '../dto/settings.dto'; +import { settingsController } from '../whatsapp.module'; +import { SettingsService } from '../services/settings.service'; +import { HttpStatus } from './index.router'; +import { Logger } from '../../config/logger.config'; + +const logger = new Logger('SettingsRouter'); + +export class SettingsRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: settingsSchema, + ClassRef: SettingsDto, + execute: (instance, data) => settingsController.createSettings(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => settingsController.findSettings(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/services/settings.service.ts b/src/whatsapp/services/settings.service.ts new file mode 100644 index 00000000..9a82046a --- /dev/null +++ b/src/whatsapp/services/settings.service.ts @@ -0,0 +1,34 @@ +import { InstanceDto } from '../dto/instance.dto'; +import { SettingsDto } from '../dto/settings.dto'; +import { WAMonitoringService } from './monitor.service'; +import { Logger } from '../../config/logger.config'; + +export class SettingsService { + constructor(private readonly waMonitor: WAMonitoringService) {} + + private readonly logger = new Logger(SettingsService.name); + + public create(instance: InstanceDto, data: SettingsDto) { + this.logger.verbose('create settings: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setSettings(data); + + return { settings: { ...instance, settings: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find settings: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[ + instance.instanceName + ].findSettings(); + + if (Object.keys(result).length === 0) { + throw new Error('Settings not found'); + } + + return result; + } catch (error) { + return { reject_call: false, msg_call: '', groups_ignore: false }; + } + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 128183da..27019883 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -125,6 +125,7 @@ import { Log } from '../../config/env.config'; import ProxyAgent from 'proxy-agent'; import { ChatwootService } from './chatwoot.service'; import { waMonitor } from '../whatsapp.module'; +import { SettingsRaw } from '../models'; export class WAStartupService { constructor( @@ -143,6 +144,7 @@ export class WAStartupService { public client: WASocket; private readonly localWebhook: wa.LocalWebHook = {}; private readonly localChatwoot: wa.LocalChatwoot = {}; + private readonly localSettings: wa.LocalSettings = {}; private stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -341,6 +343,46 @@ export class WAStartupService { return data; } + private async loadSettings() { + this.logger.verbose('Loading settings'); + const data = await this.repository.settings.find(this.instanceName); + this.localSettings.reject_call = data?.reject_call; + this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); + + this.localSettings.msg_call = data?.msg_call; + this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); + + this.localSettings.groups_ignore = data?.groups_ignore; + this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + + this.logger.verbose('Settings loaded'); + } + + public async setSettings(data: SettingsRaw) { + this.logger.verbose('Setting settings'); + await this.repository.settings.create(data, this.instanceName); + this.logger.verbose(`Settings reject_call: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + Object.assign(this.localSettings, data); + this.logger.verbose('Settings set'); + } + + public async findSettings() { + this.logger.verbose('Finding settings'); + const data = await this.repository.settings.find(this.instanceName); + + if (!data) { + this.logger.verbose('Settings not found'); + throw new NotFoundException('Settings not found'); + } + + this.logger.verbose(`Settings url: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; @@ -761,6 +803,7 @@ export class WAStartupService { try { this.loadWebhook(); this.loadChatwoot(); + this.loadSettings(); this.instance.authState = await this.defineAuthState(); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index fc71de31..4b699d7e 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -55,6 +55,12 @@ export declare namespace wa { sign_msg?: boolean; }; + export type LocalSettings = { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index c91ee9c4..9f2fed00 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -25,6 +25,7 @@ import { MessageUpModel, ChatwootModel, WebhookModel, + SettingsModel, } from './models'; import { dbserver } from '../db/db.connect'; import { WebhookRepository } from './repository/webhook.repository'; @@ -34,6 +35,9 @@ import { WAStartupService } from './services/whatsapp.service'; import { delay } from '@whiskeysockets/baileys'; import { Events } from './types/wa.types'; import { RedisCache } from '../db/redis.client'; +import { SettingsRepository } from './repository/settings.repository'; +import { SettingsService } from './services/settings.service'; +import { SettingsController } from './controllers/settings.controller'; const logger = new Logger('WA MODULE'); @@ -43,6 +47,7 @@ const contactRepository = new ContactRepository(ContactModel, configService); const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); const chatwootRepository = new ChatwootRepository(ChatwootModel, configService); +const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); export const repository = new RepositoryBroker( @@ -52,6 +57,7 @@ export const repository = new RepositoryBroker( messageUpdateRepository, webhookRepository, chatwootRepository, + settingsRepository, authRepository, configService, dbserver?.getClient(), @@ -76,6 +82,10 @@ const chatwootService = new ChatwootService(waMonitor, configService); export const chatwootController = new ChatwootController(chatwootService, configService); +const settingsService = new SettingsService(waMonitor); + +export const settingsController = new SettingsController(settingsService); + export const instanceController = new InstanceController( waMonitor, configService, From 1fcbd4f9fd6f6f3024baf8bb7a3f3af7179dc56b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 10:18:16 -0300 Subject: [PATCH 020/177] feat: Added reject call and send text message when receiving a call and Added setting to ignore group messages --- CHANGELOG.md | 4 +- src/whatsapp/services/whatsapp.service.ts | 76 +++++++++++++++++------ 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea7401df..4fc020a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ * Added connection functionality via pairing code * Added fetch profile endpoint in chat controller * Created settings controller +* Added reject call and send text message when receiving a call +* Added setting to ignore group messages ### Fixed @@ -12,7 +14,7 @@ ### Integrations -- Chatwoot: v2.18.0 +- Chatwoot: v2.18.0 - v3.0.0 (Beta) # 1.3.2 (2023-07-21 17:19) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 27019883..d3bed078 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1086,6 +1086,7 @@ export class WAStartupService { type: MessageUpsertType; }, database: Database, + settings: SettingsRaw, ) => { this.logger.verbose('Event received: messages.upsert'); const received = messages[0]; @@ -1103,6 +1104,11 @@ export class WAStartupService { received.messageTimestamp = received.messageTimestamp?.toNumber(); } + if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + const messageRaw: MessageRaw = { key: received.key, pushName: received.pushName, @@ -1194,7 +1200,11 @@ export class WAStartupService { ); }, - 'messages.update': async (args: WAMessageUpdate[], database: Database) => { + 'messages.update': async ( + args: WAMessageUpdate[], + database: Database, + settings: SettingsRaw, + ) => { this.logger.verbose('Event received: messages.update'); const status: Record = { 0: 'ERROR', @@ -1205,6 +1215,10 @@ export class WAStartupService { 5: 'PLAYED', }; for await (const { key, update } of args) { + if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { this.logger.verbose('Message update is valid'); @@ -1304,9 +1318,28 @@ export class WAStartupService { private eventHandler() { this.logger.verbose('Initializing event handler'); - this.client.ev.process((events) => { + this.client.ev.process(async (events) => { if (!this.endSession) { const database = this.configService.get('DATABASE'); + const settings = await this.findSettings(); + + if (events.call) { + this.logger.verbose('Listening event: call'); + console.log('events.call', events.call); + const call = events.call[0]; + + if (settings?.reject_call && call.status == 'offer') { + this.logger.verbose('Rejecting call'); + this.client.rejectCall(call.id, call.from); + } + + if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { + this.logger.verbose('Sending message in call'); + this.client.sendMessage(call.from, { + text: settings.msg_call, + }); + } + } if (events['connection.update']) { this.logger.verbose('Listening event: connection.update'); @@ -1327,37 +1360,44 @@ export class WAStartupService { if (events['messages.upsert']) { this.logger.verbose('Listening event: messages.upsert'); const payload = events['messages.upsert']; - this.messageHandle['messages.upsert'](payload, database); + this.messageHandle['messages.upsert'](payload, database, settings); } if (events['messages.update']) { this.logger.verbose('Listening event: messages.update'); const payload = events['messages.update']; - this.messageHandle['messages.update'](payload, database); + this.messageHandle['messages.update'](payload, database, settings); } if (events['presence.update']) { this.logger.verbose('Listening event: presence.update'); const payload = events['presence.update']; + + if (settings.groups_ignore && payload.id.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); } - if (events['groups.upsert']) { - this.logger.verbose('Listening event: groups.upsert'); - const payload = events['groups.upsert']; - this.groupHandler['groups.upsert'](payload); - } + if (!settings?.groups_ignore) { + if (events['groups.upsert']) { + this.logger.verbose('Listening event: groups.upsert'); + const payload = events['groups.upsert']; + this.groupHandler['groups.upsert'](payload); + } - if (events['groups.update']) { - this.logger.verbose('Listening event: groups.update'); - const payload = events['groups.update']; - this.groupHandler['groups.update'](payload); - } + if (events['groups.update']) { + this.logger.verbose('Listening event: groups.update'); + const payload = events['groups.update']; + this.groupHandler['groups.update'](payload); + } - if (events['group-participants.update']) { - this.logger.verbose('Listening event: group-participants.update'); - const payload = events['group-participants.update']; - this.groupHandler['group-participants.update'](payload); + if (events['group-participants.update']) { + this.logger.verbose('Listening event: group-participants.update'); + const payload = events['group-participants.update']; + this.groupHandler['group-participants.update'](payload); + } } if (events['chats.upsert']) { From fd82aa143c421993f6e372aadc2b9b0fa49ce1f4 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 11:10:32 -0300 Subject: [PATCH 021/177] wip --- src/validate/validate.schema.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 56 +++++++++-------------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 2b9ce19a..f3602582 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -123,7 +123,7 @@ const optionsSchema: JSONSchema7 = { const numberDefinition: JSONSchema7Definition = { type: 'string', - pattern: '^\\d+[\\.@\\w-]+', + // pattern: '^\\d+[\\.@\\w-]+', description: 'Invalid format', }; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3851f067..340cf5a6 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1380,7 +1380,7 @@ export class WAStartupService { private createJid(number: string): string { this.logger.verbose('Creating jid with number: ' + number); - + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); return number; @@ -1390,37 +1390,23 @@ export class WAStartupService { this.logger.verbose('Number already contains @broadcast'); return number; } - - const countryCode = number.substring(0, 2); - - if (Number(countryCode) === 55) { - const formattedBRNumber = this.formatBRNumber(number); - if (formattedBRNumber !== number) { - this.logger.verbose( - 'Jid created is whatsapp in format BR: ' + - `${formattedBRNumber}@s.whatsapp.net`, - ); - return `${formattedBRNumber}@s.whatsapp.net`; - } - } - - if (Number(countryCode) === 52 || Number(countryCode) === 54) { - const formattedMXARNumber = this.formatMXOrARNumber(number); - - if (formattedMXARNumber !== number) { - this.logger.verbose( - 'Jid created is whatsapp in format MXAR: ' + - `${formattedMXARNumber}@s.whatsapp.net`, - ); - return `${formattedMXARNumber}@s.whatsapp.net`; - } - } - - if (number.includes('-')) { + + number = number + ?.split(":")[0] + ?.split("@")[0] + ?.replace(' ', '') + ?.replace('+', '') + ?.replace('(', '') + ?.replace(')', ''); + + if (number.includes('-') && number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - + + number = number.replace(/\D/g, ''); + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); return `${number}@s.whatsapp.net`; } @@ -1451,15 +1437,14 @@ export class WAStartupService { ) { this.logger.verbose('Sending message with typing'); - const jid = this.createJid(number); - const numberWA = await this.whatsappNumber({ numbers: [jid] }); + const numberWA = await this.whatsappNumber({ numbers: [number] }); const isWA = numberWA[0]; if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { throw new BadRequestException(isWA); } - const sender = isJidGroup(jid) ? jid : isWA.jid; + const sender = isWA.jid; try { if (options?.delay) { @@ -1468,7 +1453,7 @@ export class WAStartupService { await this.client.presenceSubscribe(sender); this.logger.verbose('Subscribing to presence'); - await this.client.sendPresenceUpdate(options?.presence ?? 'composing', jid); + await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); this.logger.verbose( 'Sending presence update: ' + options?.presence ?? 'composing', ); @@ -1527,7 +1512,8 @@ export class WAStartupService { mentions = options.mentions.mentioned.map((mention) => { const jid = this.createJid(mention); if (isJidGroup(jid)) { - throw new BadRequestException('Mentions must be a number'); + return null; + // throw new BadRequestException('Mentions must be a number'); } return jid; }); @@ -2171,7 +2157,7 @@ export class WAStartupService { const onWhatsapp: OnWhatsAppDto[] = []; for await (const number of data.numbers) { const jid = this.createJid(number); - // const jid = `${number}@s.whatsapp.net`; + if (isJidGroup(jid)) { const group = await this.findGroup({ groupJid: jid }, 'inner'); From 28c2c7285c2aada7c9a7b344e7737810a153cfb2 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 11:15:58 -0300 Subject: [PATCH 022/177] Gerar Wuid no SendContact --- src/validate/validate.schema.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 2b9ce19a..59cb2bd6 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -398,7 +398,7 @@ export const contactMessageSchema: JSONSchema7 = { email: { type: 'string' }, url: { type: 'string' }, }, - required: ['fullName', 'wuid', 'phoneNumber'], + required: ['fullName', 'phoneNumber'], ...isNotEmpty('fullName'), }, minItems: 1, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3851f067..b8e1eedb 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2125,6 +2125,11 @@ export class WAStartupService { result += `URL:${contact.url}\n`; } + if (!contact.wuid) { + this.logger.verbose('Wuid defined'); + contact.wuid = this.createJid(contact.phoneNumber); + } + result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + From f35b62ed12fdd6a0c184f042eb800e61d8959e83 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 11:18:08 -0300 Subject: [PATCH 023/177] fix: Adjusts in createJid --- src/whatsapp/services/whatsapp.service.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c56cddb1..2db6e9d4 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1469,7 +1469,7 @@ export class WAStartupService { private createJid(number: string): string { this.logger.verbose('Creating jid with number: ' + number); - + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); return number; @@ -1479,23 +1479,23 @@ export class WAStartupService { this.logger.verbose('Number already contains @broadcast'); return number; } - + number = number - ?.split(":")[0] - ?.split("@")[0] + ?.split(':')[0] + ?.split('@')[0] ?.replace(' ', '') ?.replace('+', '') ?.replace('(', '') ?.replace(')', ''); - + if (number.includes('-') && number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - + number = number.replace(/\D/g, ''); - + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); return `${number}@s.whatsapp.net`; } @@ -2323,7 +2323,7 @@ export class WAStartupService { const onWhatsapp: OnWhatsAppDto[] = []; for await (const number of data.numbers) { const jid = this.createJid(number); - + if (isJidGroup(jid)) { const group = await this.findGroup({ groupJid: jid }, 'inner'); From ffe15231702b471588e9fd50bf2aad7efb711b1e Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 11:42:06 -0300 Subject: [PATCH 024/177] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 340cf5a6..4e20fca8 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2156,7 +2156,7 @@ export class WAStartupService { const onWhatsapp: OnWhatsAppDto[] = []; for await (const number of data.numbers) { - const jid = this.createJid(number); + let jid = this.createJid(number); if (isJidGroup(jid)) { const group = await this.findGroup({ groupJid: jid }, 'inner'); @@ -2165,6 +2165,7 @@ export class WAStartupService { onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); } else { + jid = (!jid.startsWith('+')) ? `+${jid}` : jid; const verify = await this.client.onWhatsApp(jid); const result = verify[0]; From 2f3d6f7e63b556d5dfcd2f2c69c57fa78c4a5570 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 11:48:10 -0300 Subject: [PATCH 025/177] fix: Fixed problem with fileSha256 appearing when sending a sticker in chatwoot --- CHANGELOG.md | 1 + src/validate/validate.schema.ts | 2 +- src/whatsapp/services/chatwoot.service.ts | 6 ++++++ src/whatsapp/services/whatsapp.service.ts | 7 ++++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc020a5..d9c76124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Fixed * Added link preview option in send text message +* Fixed problem with fileSha256 appearing when sending a sticker in chatwoot ### Integrations diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index ff95074e..18a070ab 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -446,7 +446,7 @@ export const whatsappNumberSchema: JSONSchema7 = { uniqueItems: true, items: { type: 'string', - pattern: '^\\d+', + // pattern: '^\\d+', description: '"numbers" must be an array of numeric strings', }, }, diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index decb5822..0c022c22 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1173,6 +1173,10 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; + if (typeKey === 'stickerMessage') { + return null; + } + if (typeKey === 'contactMessage') { const vCardData = result.split('\n'); const contactInfo = {}; @@ -1295,6 +1299,8 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const bodyMessage = await this.getConversationMessage(body.message); + console.log('bodyMessage', bodyMessage, body.message); + if (!bodyMessage && !isMedia) { this.logger.warn('no body message found'); return; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 445c9469..12d338a3 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1335,9 +1335,14 @@ export class WAStartupService { if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { this.logger.verbose('Sending message in call'); - this.client.sendMessage(call.from, { + const msg = await this.client.sendMessage(call.from, { text: settings.msg_call, }); + + this.client.ev.emit('messages.upsert', { + messages: [msg], + type: 'notify', + }); } } From 95df402c4cc49adcf6a223520910818fb81958fd Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 11:57:15 -0300 Subject: [PATCH 026/177] wip --- src/validate/validate.schema.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index f3602582..50972dd0 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -445,7 +445,7 @@ export const whatsappNumberSchema: JSONSchema7 = { uniqueItems: true, items: { type: 'string', - pattern: '^\\d+', + // pattern: '^\\d+', description: '"numbers" must be an array of numeric strings', }, }, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4e20fca8..a0914a68 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1392,14 +1392,14 @@ export class WAStartupService { } number = number - ?.split(":")[0] - ?.split("@")[0] - ?.replace(' ', '') - ?.replace('+', '') - ?.replace('(', '') - ?.replace(')', ''); + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(/\:/)[0] + .split('@')[0]; - if (number.includes('-') && number.length >= 18) { + if(number.includes('-') && number.length >= 24){ this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; @@ -1407,6 +1407,12 @@ export class WAStartupService { number = number.replace(/\D/g, ''); + if (number.length >= 18) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); return `${number}@s.whatsapp.net`; } From 1aa837d220e638c7f0a91d97fcee8f490c5d819a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 11:58:52 -0300 Subject: [PATCH 027/177] fix: Adjusts in chatwoot integration --- CHANGELOG.md | 2 ++ src/whatsapp/services/chatwoot.service.ts | 37 ++++++++++++++++------- src/whatsapp/services/whatsapp.service.ts | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c76124..f2d0d4ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ * Added link preview option in send text message * Fixed problem with fileSha256 appearing when sending a sticker in chatwoot +* Fixed issue where it was not possible to open a conversation when sent at first by me on my cell phone in chatwoot +* Now it only updates the contact name if it is the same as the phone number in chatwoot ### Integrations diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 0c022c22..c077a983 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -428,10 +428,12 @@ export class ChatwootService { ); if (findParticipant) { - await this.updateContact(instance, findParticipant.id, { - name: body.pushName, - avatar_url: picture_url.profilePictureUrl || null, - }); + if (!findParticipant.name || findParticipant.name === chatId) { + await this.updateContact(instance, findParticipant.id, { + name: body.pushName, + avatar_url: picture_url.profilePictureUrl || null, + }); + } } else { await this.createContact( instance, @@ -454,13 +456,28 @@ export class ChatwootService { let contact: any; if (body.key.fromMe) { - contact = findContact; + if (findContact) { + contact = findContact; + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } } else { if (findContact) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); + if (!findContact.name || findContact.name === chatId) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = findContact; + } } else { contact = await this.createContact( instance, @@ -1299,8 +1316,6 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const bodyMessage = await this.getConversationMessage(body.message); - console.log('bodyMessage', bodyMessage, body.message); - if (!bodyMessage && !isMedia) { this.logger.warn('no body message found'); return; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 12d338a3..5caaa9d9 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1093,7 +1093,7 @@ export class WAStartupService { if ( type !== 'notify' || - received.message?.protocolMessage || + // received.message?.protocolMessage || received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected'); From c9b24ff612dbdcaa95cead2509fb30ed1ac5c2a6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 12:55:27 -0300 Subject: [PATCH 028/177] fix: adjusts for chatwoot v3 --- src/whatsapp/services/chatwoot.service.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c077a983..b28eed63 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1297,6 +1297,16 @@ export class ChatwootService { return; } + this.logger.verbose('get conversation message'); + const bodyMessage = await this.getConversationMessage(body.message); + + const isMedia = this.isMediaMessage(body.message); + + if (!bodyMessage && !isMedia) { + this.logger.warn('no body message found'); + return; + } + this.logger.verbose('get conversation in chatwoot'); const getConversion = await this.createConversation(instance, body); @@ -1309,18 +1319,8 @@ export class ChatwootService { this.logger.verbose('message type: ' + messageType); - const isMedia = this.isMediaMessage(body.message); - this.logger.verbose('is media: ' + isMedia); - this.logger.verbose('get conversation message'); - const bodyMessage = await this.getConversationMessage(body.message); - - if (!bodyMessage && !isMedia) { - this.logger.warn('no body message found'); - return; - } - this.logger.verbose('check if is media'); if (isMedia) { this.logger.verbose('message is media'); From bcada5d553aa7c79f35fc825ea3dc9be2c4febca Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 13:03:40 -0300 Subject: [PATCH 029/177] fix: Now accepts all chatwoot inbox templates --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d0d4ac..10f6b6bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Fixed problem with fileSha256 appearing when sending a sticker in chatwoot * Fixed issue where it was not possible to open a conversation when sent at first by me on my cell phone in chatwoot * Now it only updates the contact name if it is the same as the phone number in chatwoot +* Now accepts all chatwoot inbox templates ### Integrations diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index b28eed63..aa346f0a 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1111,11 +1111,7 @@ export class ChatwootService { } } - if ( - body.message_type === 'template' && - body.content_type === 'input_csat' && - body.event === 'message_created' - ) { + if (body.message_type === 'template' && body.event === 'message_created') { this.logger.verbose('check if is csat'); const data: SendTextDto = { From 7103a953056929c7a5ab215cdaccaadfb8d8b528 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 13:43:18 -0300 Subject: [PATCH 030/177] feat: Added connection with pairing code in chatwoot --- CHANGELOG.md | 1 + .../controllers/instance.controller.ts | 32 +++---------- src/whatsapp/dto/chatwoot.dto.ts | 1 + src/whatsapp/models/chatwoot.model.ts | 2 + src/whatsapp/services/chatwoot.service.ts | 27 +++++++++-- src/whatsapp/services/monitor.service.ts | 3 ++ src/whatsapp/services/whatsapp.service.ts | 47 +++++++++++++++---- src/whatsapp/types/wa.types.ts | 2 + 8 files changed, 76 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10f6b6bb..7f8fd11e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Created settings controller * Added reject call and send text message when receiving a call * Added setting to ignore group messages +* Added connection with pairing code in chatwoot ### Fixed diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e7827f15..31db7918 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -103,16 +103,10 @@ export class InstanceController { if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; - let getPairingCode: string; if (qrcode) { this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(); - if (number) { - this.logger.verbose('creating number'); - await delay(5000); - getPairingCode = await instance.client.requestPairingCode(number); - } + await instance.connectToWhatsapp(number); await delay(2000); getQrcode = instance.qrCode; } @@ -126,14 +120,9 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + qrcode: getQrcode, }; - if (getPairingCode) { - result['pairingCode'] = getPairingCode; - } else { - result['qrcode'] = getQrcode; - } - this.logger.verbose('instance created'); this.logger.verbose(result); @@ -166,6 +155,7 @@ export class InstanceController { url: chatwoot_url, sign_msg: chatwoot_sign_msg || false, name_inbox: instance.instanceName, + number, }); this.chatwootService.initInstanceChatwoot( @@ -173,6 +163,7 @@ export class InstanceController { instance.instanceName, `${urlServer}/chatwoot/webhook/${instance.instanceName}`, qrcode, + number, ); } catch (error) { this.logger.log(error); @@ -193,6 +184,7 @@ export class InstanceController { token: chatwoot_token, url: chatwoot_url, sign_msg: chatwoot_sign_msg || false, + number, name_inbox: instance.instanceName, webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, }, @@ -220,19 +212,7 @@ export class InstanceController { if (state == 'close') { this.logger.verbose('connecting'); - await instance.connectToWhatsapp(); - let pairingCode = null; - if (number) { - this.logger.verbose('creating pairing code'); - await delay(5000); - pairingCode = await instance.client.requestPairingCode(number); - } - - if (pairingCode) { - return { - pairingCode, - }; - } + await instance.connectToWhatsapp(number); await delay(2000); return instance.qrCode; diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index e78b0676..a5026a46 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -5,4 +5,5 @@ export class ChatwootDto { url?: string; name_inbox?: string; sign_msg?: boolean; + number?: string; } diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index ca082309..54d9e051 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -9,6 +9,7 @@ export class ChatwootRaw { url?: string; name_inbox?: string; sign_msg?: boolean; + number?: string; } const chatwootSchema = new Schema({ @@ -19,6 +20,7 @@ const chatwootSchema = new Schema({ url: { type: String, required: true }, name_inbox: { type: String, required: true }, sign_msg: { type: Boolean, required: true }, + number: { type: String, required: true }, }); export const ChatwootModel = dbserver?.model( diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index aa346f0a..9fd3d6d6 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -13,6 +13,7 @@ import { SendAudioDto } from '../dto/sendMessage.dto'; import { SendMediaDto } from '../dto/sendMessage.dto'; import { ROOT_DIR } from '../../config/path.config'; import { ConfigService, HttpServer } from '../../config/env.config'; +import { delay } from '@whiskeysockets/baileys'; export class ChatwootService { private messageCacheFile: string; @@ -154,6 +155,7 @@ export class ChatwootService { inboxName: string, webhookUrl: string, qrcode: boolean, + number: string, ) { this.logger.verbose('init instance chatwoot: ' + instance.instanceName); @@ -243,11 +245,18 @@ export class ChatwootService { } this.logger.verbose('create message for init instance in chatwoot'); + + let contentMsg = '/init'; + + if (number) { + contentMsg = `/init:${number}`; + } + const message = await client.messages.create({ accountId: this.provider.account_id, conversationId: conversation.id, data: { - content: '/init', + content: contentMsg, message_type: 'outgoing', }, }); @@ -953,13 +962,14 @@ export class ChatwootService { const command = messageReceived.replace('/', ''); - if (command === 'init' || command === 'iniciar') { + if (command.includes('init') || command.includes('iniciar')) { this.logger.verbose('command init found'); const state = waInstance?.connectionStatus?.state; if (state !== 'open') { this.logger.verbose('connect to whatsapp'); - await waInstance.connectToWhatsapp(); + const number = command.split(':')[1]; + await waInstance.connectToWhatsapp(number); } else { this.logger.verbose('whatsapp already connected'); await this.createBotMessage( @@ -1556,7 +1566,16 @@ export class ChatwootService { fileName, ); - const msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds:`; + let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + + if (body?.qrcode?.pairingCode) { + msgQrCode = + msgQrCode + + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( + 0, + 4, + )}-${body.qrcode.pairingCode.substring(4, 8)}`; + } this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgQrCode, 'incoming'); diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 6c31ad58..7ffa81e1 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -25,6 +25,7 @@ import { ContactModel, MessageModel, MessageUpModel, + SettingsModel, WebhookModel, } from '../models'; @@ -241,6 +242,7 @@ export class WAMonitoringService { execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); return; } @@ -254,6 +256,7 @@ export class WAMonitoringService { await AuthModel.deleteMany({ _id: instanceName }); await WebhookModel.deleteMany({ _id: instanceName }); await ChatwootModel.deleteMany({ _id: instanceName }); + await SettingsModel.deleteMany({ _id: instanceName }); return; } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 7adaf641..9cb9b43f 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -152,6 +152,8 @@ export class WAStartupService { private endSession = false; private logBaileys = this.configService.get('LOG').BAILEYS; + private phoneNumber: string; + private chatwootService = new ChatwootService(waMonitor, this.configService); public set instanceName(name: string) { @@ -241,6 +243,12 @@ export class WAStartupService { public get qrCode(): wa.QrCode { this.logger.verbose('Getting qrcode'); + if (this.instance.qrcode?.pairingCode) { + return { + pairingCode: this.instance.qrcode?.pairingCode, + }; + } + return { code: this.instance.qrcode?.code, base64: this.instance.qrcode?.base64, @@ -588,11 +596,6 @@ export class WAStartupService { return this.eventEmitter.emit('no.connection', this.instance.name); } - // pairing code - // await delay(5000); - // const code = await this.client.requestPairingCode('557499879409'); - // console.log(`Pairing code: ${code}`); - this.logger.verbose('Incrementing QR code count'); this.instance.qrcode.count++; @@ -603,6 +606,13 @@ export class WAStartupService { color: { light: '#ffffff', dark: '#198754' }, }; + if (this.phoneNumber) { + await delay(2000); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode( + this.phoneNumber, + ); + } + this.logger.verbose('Generating QR code'); qrcode.toDataURL(qr, optsQrcode, (error, base64) => { if (error) { @@ -614,7 +624,12 @@ export class WAStartupService { this.instance.qrcode.code = qr; this.sendDataWebhook(Events.QRCODE_UPDATED, { - qrcode: { instance: this.instance.name, code: qr, base64 }, + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, }); if (this.localChatwoot.enabled) { @@ -622,7 +637,12 @@ export class WAStartupService { Events.QRCODE_UPDATED, { instanceName: this.instance.name }, { - qrcode: { instance: this.instance.name, code: qr, base64 }, + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, }, ); } @@ -631,7 +651,7 @@ export class WAStartupService { this.logger.verbose('Generating QR code in terminal'); qrcodeTerminal.generate(qr, { small: true }, (qrcode) => this.logger.log( - `\n{ instance: ${this.instance.name}, qrcodeCount: ${this.instance.qrcode.count} }\n` + + `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + qrcode, ), ); @@ -798,7 +818,7 @@ export class WAStartupService { return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); } - public async connectToWhatsapp(): Promise { + public async connectToWhatsapp(number?: string): Promise { this.logger.verbose('Connecting to whatsapp'); try { this.loadWebhook(); @@ -872,6 +892,15 @@ export class WAStartupService { this.logger.verbose('Socket event handler initialized'); + this.phoneNumber = number; + + // if (number) { + // this.logger.verbose('creating pairing code'); + // await delay(5000); + // this.phoneNumber = number; + // this.instance.qrcode.pairingCode = await this.client.requestPairingCode(number); + // } + return this.client; } catch (error) { this.logger.error(error); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 4b699d7e..d0c5f80c 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -27,11 +27,13 @@ export enum Events { export declare namespace wa { export type QrCode = { count?: number; + pairingCode?: string; base64?: string; code?: string; }; export type Instance = { qrcode?: QrCode; + pairingCode?: string; authState?: { state: AuthenticationState; saveCreds: () => void }; name?: string; wuid?: string; From fff420b652120af7919c01b9a4c55445da2bca9b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 15:05:03 -0300 Subject: [PATCH 031/177] fix: command to create new instances set to /new_instance:: --- CHANGELOG.md | 1 + .../controllers/chatwoot.controller.ts | 6 ++ src/whatsapp/services/chatwoot.service.ts | 56 ++++++++++++++++++- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f8fd11e..57a8c4cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * Fixed issue where it was not possible to open a conversation when sent at first by me on my cell phone in chatwoot * Now it only updates the contact name if it is the same as the phone number in chatwoot * Now accepts all chatwoot inbox templates +* Command to create new instances set to /new_instance:: ### Integrations diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index de0aef7a..13e8fcd4 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -94,4 +94,10 @@ export class ChatwootController { return chatwootService.receiveWebhook(instance, data); } + + public async newInstance(data: any) { + const chatwootService = new ChatwootService(waMonitor, this.configService); + + return chatwootService.newInstance(data); + } } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 9fd3d6d6..399261c2 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -13,7 +13,6 @@ import { SendAudioDto } from '../dto/sendMessage.dto'; import { SendMediaDto } from '../dto/sendMessage.dto'; import { ROOT_DIR } from '../../config/path.config'; import { ConfigService, HttpServer } from '../../config/env.config'; -import { delay } from '@whiskeysockets/baileys'; export class ChatwootService { private messageCacheFile: string; @@ -1017,7 +1016,7 @@ export class ChatwootService { await waInstance?.client?.ws?.close(); } - if (command.includes('#inbox_whatsapp')) { + if (command.includes('new_instance')) { const urlServer = this.configService.get('SERVER').URL; const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; @@ -1030,6 +1029,10 @@ export class ChatwootService { chatwoot_sign_msg: this.provider.sign_msg, }; + if (command.split(':')[2]) { + data['number'] = command.split(':')[2]; + } + const config = { method: 'post', maxBodyLength: Infinity, @@ -1585,4 +1588,53 @@ export class ChatwootService { this.logger.error(error); } } + + public async newInstance(data: any) { + try { + const instanceName = data.instanceName; + const qrcode = true; + const number = data.number; + const accountId = data.accountId; + const chatwootToken = data.token; + const chatwootUrl = data.url; + const signMsg = true; + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + console.log('data: ', data); + + const requestData = { + instanceName, + qrcode, + chatwoot_account_id: accountId, + chatwoot_token: chatwootToken, + chatwoot_url: chatwootUrl, + chatwoot_sign_msg: signMsg, + }; + + if (number) { + requestData['number'] = number; + } + + console.log('requestData: ', requestData); + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: requestData, + }; + + // await axios.request(config); + + return true; + } catch (error) { + this.logger.error(error); + return null; + } + } } From 4d00351db790b498f919f3083787a85ad7788ecb Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 15:05:26 -0300 Subject: [PATCH 032/177] fix: command to create new instances set to /new_instance:: --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57a8c4cc..3cecc446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ * Created settings controller * Added reject call and send text message when receiving a call * Added setting to ignore group messages -* Added connection with pairing code in chatwoot +* Added connection with pairing code in chatwoot with command /init: ### Fixed From 45c11a5a8e9474a580557d8a8aa50f200d34646c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 15:12:13 -0300 Subject: [PATCH 033/177] fix: fix in chatwoot set, sign msg can now be disabled --- CHANGELOG.md | 1 + src/whatsapp/controllers/chatwoot.controller.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cecc446..7009fce9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * Now it only updates the contact name if it is the same as the phone number in chatwoot * Now accepts all chatwoot inbox templates * Command to create new instances set to /new_instance:: +* Fix in chatwoot set, sign msg can now be disabled ### Integrations diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index 13e8fcd4..d5e5e841 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -33,7 +33,7 @@ export class ChatwootController { throw new BadRequestException('token is required'); } - if (!data.sign_msg) { + if (data.sign_msg !== true && data.sign_msg !== false) { throw new BadRequestException('sign_msg is required'); } } From 68d980795ad3fc57a4b902945be094934d9095cd Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 15:13:46 -0300 Subject: [PATCH 034/177] fix: fix in chatwoot set, sign msg can now be disabled --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7009fce9..ed6500be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ * Created settings controller * Added reject call and send text message when receiving a call * Added setting to ignore group messages -* Added connection with pairing code in chatwoot with command /init: +* Added connection with pairing code in chatwoot with command /init:{NUMBER} ### Fixed @@ -16,7 +16,7 @@ * Fixed issue where it was not possible to open a conversation when sent at first by me on my cell phone in chatwoot * Now it only updates the contact name if it is the same as the phone number in chatwoot * Now accepts all chatwoot inbox templates -* Command to create new instances set to /new_instance:: +* Command to create new instances set to /new_instance:{NAME}:{NUMBER} * Fix in chatwoot set, sign msg can now be disabled ### Integrations @@ -55,7 +55,7 @@ * Added messages.delete event * Added restart instance endpoint -* Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:' +* Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:{INSTANCE_NAME} * Change Baileys version to: 6.4.0 * Send contact in chatwoot * Send contact array in chatwoot From 8d91e7cb1d04abb2cf01e703a59222f04805fc5e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 16:21:29 -0300 Subject: [PATCH 035/177] feat: Added encoding option in endpoint sendWhatsAppAudio --- CHANGELOG.md | 1 + .../controllers/instance.controller.ts | 2 +- src/whatsapp/dto/sendMessage.dto.ts | 1 + src/whatsapp/services/chatwoot.service.ts | 4 -- src/whatsapp/services/whatsapp.service.ts | 58 ++++++++++++------- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed6500be..beeb2888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Added reject call and send text message when receiving a call * Added setting to ignore group messages * Added connection with pairing code in chatwoot with command /init:{NUMBER} +* Added encoding option in endpoint sendWhatsAppAudio ### Fixed diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 31db7918..ef930c7b 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -107,7 +107,7 @@ export class InstanceController { if (qrcode) { this.logger.verbose('creating qrcode'); await instance.connectToWhatsapp(number); - await delay(2000); + await delay(3000); getQrcode = instance.qrCode; } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 0a20674c..c2ddb3a2 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -16,6 +16,7 @@ export class Options { quoted?: Quoted; mentions?: Mentions; linkPreview?: boolean; + encoding?: boolean; } class OptionsMessage { options: Options; diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 399261c2..c77162ad 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1601,8 +1601,6 @@ export class ChatwootService { const urlServer = this.configService.get('SERVER').URL; const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - console.log('data: ', data); - const requestData = { instanceName, qrcode, @@ -1616,8 +1614,6 @@ export class ChatwootService { requestData['number'] = number; } - console.log('requestData: ', requestData); - const config = { method: 'post', maxBodyLength: Infinity, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 9cb9b43f..d475988a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1354,7 +1354,6 @@ export class WAStartupService { if (events.call) { this.logger.verbose('Listening event: call'); - console.log('events.call', events.call); const call = events.call[0]; if (settings?.reject_call && call.status == 'offer') { @@ -1662,8 +1661,6 @@ export class WAStartupService { const linkPreview = options?.linkPreview != false ? undefined : false; - console.log('linkPreview', linkPreview); - let quoted: WAMessage; if (options?.quoted) { @@ -2179,26 +2176,45 @@ export class WAStartupService { public async audioWhatsapp(data: SendAudioDto) { this.logger.verbose('Sending audio whatsapp'); - const convert = await this.processAudio(data.audioMessage.audio, data.number); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - const result = this.sendMessageWithTyping( - data.number, - { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - return result; - } else { - throw new InternalServerErrorException(convert); + if (!data.options?.encoding && data.options?.encoding !== false) { + data.options.encoding = true; } + + if (data.options?.encoding) { + const convert = await this.processAudio(data.audioMessage.audio, data.number); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + const result = this.sendMessageWithTyping( + data.number, + { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); + + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); + + return result; + } else { + throw new InternalServerErrorException(convert); + } + } + + return await this.sendMessageWithTyping( + data.number, + { + audio: isURL(data.audioMessage.audio) + ? { url: data.audioMessage.audio } + : Buffer.from(data.audioMessage.audio, 'base64'), + ptt: true, + mimetype: 'audio/ogg; codecs=opus', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); } public async buttonMessage(data: SendButtonDto) { From 1c30728880874eac25f7373a1f8c702042b24682 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 17:05:18 -0300 Subject: [PATCH 036/177] version: 1.4.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beeb2888..1bb71df6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.0 (homolog) +# 1.4.0 (2023-07-24 17:03) ### Features From f7293255cf05d74c6c33ba887bc7774d926fcd5d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 18:21:11 -0300 Subject: [PATCH 037/177] fix: Fixed reconnect with pairing code or qrcode --- CHANGELOG.md | 6 ++++++ src/whatsapp/controllers/instance.controller.ts | 4 ++-- src/whatsapp/services/whatsapp.service.ts | 10 +++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bb71df6..2d62c451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.1 (homolog) + +### Fixed + +* Fixed reconnect with pairing code or qrcode + # 1.4.0 (2023-07-24 17:03) ### Features diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index ef930c7b..fa3b0812 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -107,7 +107,7 @@ export class InstanceController { if (qrcode) { this.logger.verbose('creating qrcode'); await instance.connectToWhatsapp(number); - await delay(3000); + await delay(5000); getQrcode = instance.qrCode; } @@ -214,7 +214,7 @@ export class InstanceController { this.logger.verbose('connecting'); await instance.connectToWhatsapp(number); - await delay(2000); + await delay(5000); return instance.qrCode; } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d475988a..37ec3341 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -606,11 +606,14 @@ export class WAStartupService { color: { light: '#ffffff', dark: '#198754' }, }; + console.log(this.phoneNumber); if (this.phoneNumber) { await delay(2000); this.instance.qrcode.pairingCode = await this.client.requestPairingCode( this.phoneNumber, ); + } else { + this.instance.qrcode.pairingCode = null; } this.logger.verbose('Generating QR code'); @@ -894,13 +897,6 @@ export class WAStartupService { this.phoneNumber = number; - // if (number) { - // this.logger.verbose('creating pairing code'); - // await delay(5000); - // this.phoneNumber = number; - // this.instance.qrcode.pairingCode = await this.client.requestPairingCode(number); - // } - return this.client; } catch (error) { this.logger.error(error); From f9abd90cc9044961eb2078132f6c538433135614 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 18:28:01 -0300 Subject: [PATCH 038/177] fix: connection state --- CHANGELOG.md | 1 + src/validate/validate.schema.ts | 2 -- src/whatsapp/controllers/instance.controller.ts | 17 +++++++++++------ src/whatsapp/services/whatsapp.service.ts | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d62c451..b9672e6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Fixed reconnect with pairing code or qrcode +* Fixed problem in createJid # 1.4.0 (2023-07-24 17:03) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 18a070ab..aea723ca 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -124,7 +124,6 @@ const optionsSchema: JSONSchema7 = { const numberDefinition: JSONSchema7Definition = { type: 'string', - // pattern: '^\\d+[\\.@\\w-]+', description: 'Invalid format', }; @@ -446,7 +445,6 @@ export const whatsappNumberSchema: JSONSchema7 = { uniqueItems: true, items: { type: 'string', - // pattern: '^\\d+', description: '"numbers" must be an array of numeric strings', }, }, diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index fa3b0812..7322e194 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -245,7 +245,12 @@ export class InstanceController { public async connectionState({ instanceName }: InstanceDto) { this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); - return this.waMonitor.waInstances[instanceName]?.connectionStatus; + return { + instance: { + instanceName: instanceName, + state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, + }, + }; } public async fetchInstances({ instanceName }: InstanceDto) { @@ -260,9 +265,9 @@ export class InstanceController { public async logout({ instanceName }: InstanceDto) { this.logger.verbose('requested logout from ' + instanceName + ' instance'); - const stateConn = await this.connectionState({ instanceName }); + const { instance } = await this.connectionState({ instanceName }); - if (stateConn.state === 'close') { + if (instance.state === 'close') { throw new BadRequestException( 'The "' + instanceName + '" instance is not connected', ); @@ -285,15 +290,15 @@ export class InstanceController { public async deleteInstance({ instanceName }: InstanceDto) { this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); - const stateConn = await this.connectionState({ instanceName }); + const { instance } = await this.connectionState({ instanceName }); - if (stateConn.state === 'open') { + if (instance.state === 'open') { throw new BadRequestException( 'The "' + instanceName + '" instance needs to be disconnected', ); } try { - if (stateConn.state === 'connecting') { + if (instance.state === 'connecting') { this.logger.verbose('logging out instance: ' + instanceName); await this.logout({ instanceName }); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 37ec3341..6c7c96f0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1517,7 +1517,7 @@ export class WAStartupService { .split(/\:/)[0] .split('@')[0]; - if (number.includes('-') && number.length >= 24) { + if (number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; From 8d1f2313ac002b179cd7ed79089f83a28bb2b326 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 18:28:39 -0300 Subject: [PATCH 039/177] version: 1.4.1 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9672e6d..7dd59c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.1 (homolog) +# 1.4.1 (2023-07-24 18:28) ### Fixed diff --git a/package.json b/package.json index 92745ead..1145676d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.0", + "version": "1.4.1", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 0cc1f18a7eaafaa851194a0955f5bbf9637350bf Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:05:32 -0300 Subject: [PATCH 040/177] =?UTF-8?q?[BUG]=20Corre=C3=A7=C3=A3o=20de=20menci?= =?UTF-8?q?onar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caso seja enviado everyOne como false sem passar nada no mentioned --- src/whatsapp/services/whatsapp.service.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6c7c96f0..833637b2 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1686,20 +1686,13 @@ export class WAStartupService { if (options?.mentions) { this.logger.verbose('Mentions defined'); - if ( - !Array.isArray(options.mentions.mentioned) && - !options.mentions.everyOne - ) { - throw new BadRequestException('Mentions must be an array'); - } - - if (options.mentions.everyOne) { + if (options.mentions?.everyOne) { this.logger.verbose('Mentions everyone'); this.logger.verbose('Getting group metadata'); mentions = groupMetadata.participants.map((participant) => participant.id); this.logger.verbose('Getting group metadata for mentions'); - } else { + } else if(options.mentions?.mentioned?.length) { this.logger.verbose('Mentions manually defined'); mentions = options.mentions.mentioned.map((mention) => { const jid = this.createJid(mention); From ef4be6a612ff50465d1e48925eef14d578592b68 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:53:03 -0300 Subject: [PATCH 041/177] Start --- src/validate/validate.schema.ts | 1 + src/whatsapp/dto/group.dto.ts | 3 ++- src/whatsapp/services/whatsapp.service.ts | 11 ++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 18a070ab..761f01ba 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -669,6 +669,7 @@ export const createGroupSchema: JSONSchema7 = { subject: { type: 'string' }, description: { type: 'string' }, profilePicture: { type: 'string' }, + promoteParticipants: { type: 'boolean', enum: [true, false] }, participants: { type: 'array', minItems: 1, diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index bc36e27f..6dfdc45c 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,7 +1,8 @@ export class CreateGroupDto { subject: string; - description?: string; participants: string[]; + description?: string; + promoteParticipants?: boolean; } export class GroupPictureDto { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d475988a..4f832852 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2785,11 +2785,20 @@ export class WAStartupService { this.logger.verbose('Updating group description: ' + create.description); await this.client.groupUpdateDescription(id, create.description); } + + if (create?.promoteParticipants) { + this.logger.verbose('Prometing group participants: ' + create.description); + await this.updateGParticipant({ + groupJid: id, + action: "promote", + participants: participants + }); + } const group = await this.client.groupMetadata(id); this.logger.verbose('Getting group metadata'); - return { groupMetadata: group }; + return group; } catch (error) { this.logger.error(error); throw new InternalServerErrorException('Error creating group', error.toString()); From 58ed6f395fce5ba7a8d8c7cc15592e981204cc15 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:59:09 -0300 Subject: [PATCH 042/177] =?UTF-8?q?Valida=C3=A7=C3=A3o=20de=20Grupo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/whatsapp/services/whatsapp.service.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 833637b2..a2767d16 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1517,14 +1517,22 @@ export class WAStartupService { .split(/\:/)[0] .split('@')[0]; + // Verificação de Grupos Antigos + if(number.includes('-') && number.length >= 24){ + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = number.replace(/\D/g, ''); + + // Verificação de Grupos Novos if (number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - number = number.replace(/\D/g, ''); - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); return `${number}@s.whatsapp.net`; } From 84f3f072794d054d0e7097f3495f28569b6a1147 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:11:15 -0300 Subject: [PATCH 043/177] fix: Fixed validation is set settings --- src/whatsapp/controllers/settings.controller.ts | 4 ---- src/whatsapp/services/whatsapp.service.ts | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 59031634..f538abe6 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -15,10 +15,6 @@ export class SettingsController { 'requested createSettings from ' + instance.instanceName + ' instance', ); - if (data.reject_call && data.msg_call.trim() == '') { - throw new BadRequestException('msg_call is required'); - } - return this.settingsService.create(instance, data); } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 833637b2..0cfaf24c 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1692,7 +1692,7 @@ export class WAStartupService { this.logger.verbose('Getting group metadata'); mentions = groupMetadata.participants.map((participant) => participant.id); this.logger.verbose('Getting group metadata for mentions'); - } else if(options.mentions?.mentioned?.length) { + } else if (options.mentions?.mentioned?.length) { this.logger.verbose('Mentions manually defined'); mentions = options.mentions.mentioned.map((mention) => { const jid = this.createJid(mention); From c5824767c845013c83dceb735b2e13a0606985e1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:11:49 -0300 Subject: [PATCH 044/177] fix: Fixed validation is set settings --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd59c0d..25812c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.4.2 (homolog) + +### Fixed + +* Fixed validation is set settings +* Adjusts in group validations + # 1.4.1 (2023-07-24 18:28) ### Fixed From b77f22790bb5ea17133993f005d3613193698f3a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:13:18 -0300 Subject: [PATCH 045/177] fix: Fixed validation is set settings --- src/whatsapp/services/whatsapp.service.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ade1e951..69e9562a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1517,16 +1517,14 @@ export class WAStartupService { .split(/\:/)[0] .split('@')[0]; - // Verificação de Grupos Antigos - if(number.includes('-') && number.length >= 24){ + if (number.includes('-') && number.length >= 24) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - + number = number.replace(/\D/g, ''); - // Verificação de Grupos Novos if (number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); @@ -2782,13 +2780,13 @@ export class WAStartupService { this.logger.verbose('Updating group description: ' + create.description); await this.client.groupUpdateDescription(id, create.description); } - + if (create?.promoteParticipants) { this.logger.verbose('Prometing group participants: ' + create.description); await this.updateGParticipant({ groupJid: id, - action: "promote", - participants: participants + action: 'promote', + participants: participants, }); } From f475391ba6b3c8af8d0fbdf02819b0a7bfacee80 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:32:15 -0300 Subject: [PATCH 046/177] fix: Ajusts in sticker message to chatwoot --- .../controllers/instance.controller.ts | 259 +++++++++--------- src/whatsapp/repository/repository.manager.ts | 5 + src/whatsapp/services/chatwoot.service.ts | 6 +- src/whatsapp/services/whatsapp.service.ts | 7 +- 4 files changed, 141 insertions(+), 136 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 7322e194..e9e690b3 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -41,77 +41,136 @@ export class InstanceController { chatwoot_url, chatwoot_sign_msg, }: InstanceDto) { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + try { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException( - 'The instance name must be lowercase and without special characters', - ); - } - - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException( + 'The instance name must be lowercase and without special characters', + ); } - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); + + this.logger.verbose('creating instance'); + const instance = new WAStartupService( + this.configService, + this.eventEmitter, + this.repository, + this.cache, + ); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); + + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + let getEvents: string[]; + + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } + + this.logger.verbose('creating webhook'); + try { + this.webhookService.create(instance, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); + + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, webhook_by_events, + events: getEvents, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, }); - getEvents = (await this.webhookService.find(instance)).events; + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); } catch (error) { this.logger.log(error); } - } - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { + return { instance: { instanceName: instance.instanceName, status: 'created', @@ -120,75 +179,21 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, - qrcode: getQrcode, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - number, - ); } catch (error) { - this.logger.log(error); + console.log(error); + return { error: true, message: error.toString() }; } - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; } public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index dde636c7..d506cc46 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -102,7 +102,12 @@ export class RepositoryBroker { this.logger.verbose('creating store path: ' + storePath); const tempDir = join(storePath, 'temp'); + const chatwootDir = join(storePath, 'chatwoot'); + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c77162ad..6e55d145 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1179,7 +1179,7 @@ export class ChatwootService { videoMessage: msg.videoMessage?.caption, extendedTextMessage: msg.extendedTextMessage?.text, messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: msg.stickerMessage?.fileSha256.toString('base64'), + stickerMessage: undefined, documentMessage: msg.documentMessage?.caption, documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, @@ -1199,10 +1199,6 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; - if (typeKey === 'stickerMessage') { - return null; - } - if (typeKey === 'contactMessage') { const vCardData = result.split('\n'); const contactInfo = {}; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 69e9562a..ff6fdd71 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -116,16 +116,15 @@ import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-d import Long from 'long'; import { WebhookRaw } from '../models/webhook.model'; import { ChatwootRaw } from '../models/chatwoot.model'; +import { SettingsRaw } from '../models'; import { dbserver } from '../../db/db.connect'; import NodeCache from 'node-cache'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import sharp from 'sharp'; import { RedisCache } from '../../db/redis.client'; import { Log } from '../../config/env.config'; -import ProxyAgent from 'proxy-agent'; import { ChatwootService } from './chatwoot.service'; import { waMonitor } from '../whatsapp.module'; -import { SettingsRaw } from '../models'; export class WAStartupService { constructor( @@ -382,7 +381,7 @@ export class WAStartupService { if (!data) { this.logger.verbose('Settings not found'); - throw new NotFoundException('Settings not found'); + return null; } this.logger.verbose(`Settings url: ${data.reject_call}`); @@ -1129,7 +1128,7 @@ export class WAStartupService { received.messageTimestamp = received.messageTimestamp?.toNumber(); } - if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { + if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { this.logger.verbose('group ignored'); return; } From c76334a68aab4622d75abd905bbd59eaee8e2fa9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:32:29 -0300 Subject: [PATCH 047/177] fix: Ajusts in sticker message to chatwoot --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25812c6e..cddb23a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixed validation is set settings * Adjusts in group validations +* Ajusts in sticker message to chatwoot # 1.4.1 (2023-07-24 18:28) From 4d9ca4b4511ba997f28b4efa764b9079a180bcb4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:52:34 -0300 Subject: [PATCH 048/177] version: 1.4.2 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cddb23a1..7429fddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.2 (homolog) +# 1.4.2 (2023-07-24 20:52) ### Fixed diff --git a/package.json b/package.json index 1145676d..6489b86c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.1", + "version": "1.4.2", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From a12231a0aa003a01510cec3dc7db5d8e430fb523 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 09:57:28 -0300 Subject: [PATCH 049/177] fix: Adjusts in settings with options always_online, read_messages and read_status --- CHANGELOG.md | 6 +++++ src/validate/validate.schema.ts | 23 ++++++++++++++---- src/whatsapp/dto/chat.dto.ts | 2 +- src/whatsapp/dto/settings.dto.ts | 3 +++ src/whatsapp/models/settings.model.ts | 6 +++++ src/whatsapp/services/whatsapp.service.ts | 29 +++++++++++++++++++++-- src/whatsapp/types/wa.types.ts | 3 +++ 7 files changed, 65 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7429fddc..bc6da5f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.3 (homolog) + +### Fixed + +* Adjusts in settings with options always_online, read_messages and read_status + # 1.4.2 (2023-07-24 20:52) ### Fixed diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 3c1f8d0a..318835b1 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -455,7 +455,7 @@ export const readMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', properties: { - readMessages: { + read_messages: { type: 'array', minItems: 1, uniqueItems: true, @@ -470,7 +470,7 @@ export const readMessageSchema: JSONSchema7 = { }, }, }, - required: ['readMessages'], + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { @@ -884,7 +884,22 @@ export const settingsSchema: JSONSchema7 = { reject_call: { type: 'boolean', enum: [true, false] }, msg_call: { type: 'string' }, groups_ignore: { type: 'boolean', enum: [true, false] }, + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, }, - required: ['reject_call'], - ...isNotEmpty('reject_call'), + required: [ + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ], + ...isNotEmpty( + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ), }; diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 5af66a5e..4681ef76 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -59,7 +59,7 @@ class Key { remoteJid: string; } export class ReadMessageDto { - readMessages: Key[]; + read_messages: Key[]; } class LastMessage { diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 20a6cba0..594ab3a4 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -2,4 +2,7 @@ export class SettingsDto { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b5eb7fe7..b6d2488d 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -6,6 +6,9 @@ export class SettingsRaw { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ @@ -13,6 +16,9 @@ const settingsSchema = new Schema({ reject_call: { type: Boolean, required: true }, msg_call: { type: String, required: true }, groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); export const SettingsModel = dbserver?.model( diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ff6fdd71..66a46aca 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -362,6 +362,15 @@ export class WAStartupService { this.localSettings.groups_ignore = data?.groups_ignore; this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + this.logger.verbose('Settings loaded'); } @@ -371,8 +380,13 @@ export class WAStartupService { this.logger.verbose(`Settings reject_call: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); Object.assign(this.localSettings, data); this.logger.verbose('Settings set'); + + this.client?.ws?.close(); } public async findSettings() { @@ -387,6 +401,9 @@ export class WAStartupService { this.logger.verbose(`Settings url: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); return data; } @@ -847,6 +864,7 @@ export class WAStartupService { printQRInTerminal: false, browser, version, + markOnlineOnConnect: this.localSettings.always_online, connectTimeoutMs: 60_000, qrTimeout: 40_000, defaultQueryTimeoutMs: undefined, @@ -1143,6 +1161,14 @@ export class WAStartupService { source: getDevice(received.key.id), }; + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + this.logger.log(messageRaw); this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); @@ -2400,7 +2426,7 @@ export class WAStartupService { this.logger.verbose('Marking message as read'); try { const keys: proto.IMessageKey[] = []; - data.readMessages.forEach((read) => { + data.read_messages.forEach((read) => { if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { keys.push({ remoteJid: read.remoteJid, @@ -2640,7 +2666,6 @@ export class WAStartupService { await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); this.logger.verbose('Groups add privacy updated'); - // reinicia a instancia this.client?.ws?.close(); return { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d0c5f80c..9644b76e 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -61,6 +61,9 @@ export declare namespace wa { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; }; export type StateConnection = { From 62e2a8a6e3a882e8350131aa53becc28ee862df7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:23:18 -0300 Subject: [PATCH 050/177] fix: Fixed send webhook for event CALL --- CHANGELOG.md | 1 + Docker/.env.example | 1 + Dockerfile | 1 + src/config/env.config.ts | 2 ++ src/dev-env.yml | 1 + src/validate/validate.schema.ts | 2 ++ src/whatsapp/services/whatsapp.service.ts | 4 ++++ src/whatsapp/types/wa.types.ts | 1 + 8 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc6da5f1..3d875a4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Adjusts in settings with options always_online, read_messages and read_status +* Fixed send webhook for event CALL # 1.4.2 (2023-07-24 20:52) diff --git a/Docker/.env.example b/Docker/.env.example index c3dbe505..f4e8291d 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -73,6 +73,7 @@ WEBHOOK_EVENTS_GROUPS_UPSERT=true WEBHOOK_EVENTS_GROUPS_UPDATE=true WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true WEBHOOK_EVENTS_CONNECTION_UPDATE=true +WEBHOOK_EVENTS_CALL=true # This event fires every time a new token is requested via the refresh route WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/Dockerfile b/Dockerfile index 93fa60c4..0b3ac950 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,6 +74,7 @@ ENV WEBHOOK_EVENTS_GROUPS_UPSERT=true ENV WEBHOOK_EVENTS_GROUPS_UPDATE=true ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true +ENV WEBHOOK_EVENTS_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 88b718de..78c90ec9 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -89,6 +89,7 @@ export type EventsWebhook = { GROUPS_UPSERT: boolean; GROUP_UPDATE: boolean; GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; NEW_JWT_TOKEN: boolean; }; @@ -245,6 +246,7 @@ export class ConfigService { GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', }, }, diff --git a/src/dev-env.yml b/src/dev-env.yml index 41368ea4..b45d3201 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -110,6 +110,7 @@ WEBHOOK: GROUP_UPDATE: true GROUP_PARTICIPANTS_UPDATE: true CONNECTION_UPDATE: true + CALL: true # This event fires every time a new token is requested via the refresh route NEW_JWT_TOKEN: false diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 318835b1..62b7e41c 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -53,6 +53,7 @@ export const instanceNameSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, @@ -854,6 +855,7 @@ export const webhookSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 66a46aca..8959197e 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1388,11 +1388,15 @@ export class WAStartupService { text: settings.msg_call, }); + this.logger.verbose('Sending data to event messages.upsert'); this.client.ev.emit('messages.upsert', { messages: [msg], type: 'notify', }); } + + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); } if (events['connection.update']) { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 9644b76e..80aede98 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -22,6 +22,7 @@ export enum Events { GROUPS_UPSERT = 'groups.upsert', GROUPS_UPDATE = 'groups.update', GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { From c314d00ccd98ae8bcc55b0873e2ccf1497fff88c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:42:34 -0300 Subject: [PATCH 051/177] fix: Create instance with settings --- .../controllers/instance.controller.ts | 24 +++++++++++++++++++ src/whatsapp/dto/instance.dto.ts | 12 +++++++--- src/whatsapp/whatsapp.module.ts | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e9e690b3..9be6ab5d 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -13,6 +13,7 @@ import { Logger } from '../../config/logger.config'; import { wa } from '../types/wa.types'; import { RedisCache } from '../../db/redis.client'; import { isURL } from 'class-validator'; +import { SettingsService } from '../services/settings.service'; export class InstanceController { constructor( @@ -23,6 +24,7 @@ export class InstanceController { private readonly authService: AuthService, private readonly webhookService: WebhookService, private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, private readonly cache: RedisCache, ) {} @@ -40,6 +42,12 @@ export class InstanceController { chatwoot_token, chatwoot_url, chatwoot_sign_msg, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -102,6 +110,20 @@ export class InstanceController { } } + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; + + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; @@ -121,6 +143,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, qrcode: getQrcode, }; @@ -179,6 +202,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, chatwoot: { enabled: true, account_id: chatwoot_account_id, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 9e8a7ec3..ca88a729 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,11 +1,17 @@ export class InstanceDto { instanceName: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; qrcode?: boolean; number?: string; token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; chatwoot_account_id?: string; chatwoot_token?: string; chatwoot_url?: string; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 9f2fed00..b8f3b1ad 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -94,6 +94,7 @@ export const instanceController = new InstanceController( authService, webhookService, chatwootService, + settingsService, cache, ); export const viewsController = new ViewsController(waMonitor, configService); From fdee1df5b32ef9d867819b83ab2acd9051a360e3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:42:45 -0300 Subject: [PATCH 052/177] fix: Create instance with settings --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d875a4a..7c9472f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Adjusts in settings with options always_online, read_messages and read_status * Fixed send webhook for event CALL +* Create instance with settings # 1.4.2 (2023-07-24 20:52) From 1cd7291068d8818aa6f3e8cfabe6ecfc6fc9fa19 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:51:28 -0300 Subject: [PATCH 053/177] version: 1.4.3 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9472f9..315ee04d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.3 (homolog) +# 1.4.3 (2023-07-25 10:51) ### Fixed diff --git a/package.json b/package.json index 6489b86c..716aeec4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.2", + "version": "1.4.3", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 4c006970a24c798a701c3a2adc1e573e0b8956be Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 11:52:26 -0300 Subject: [PATCH 054/177] fix: Fixed chatwoot line wrap issue --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/whatsapp/services/chatwoot.service.ts | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 315ee04d..8eda7c55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.4 (homolog) + +### Fixed + +* Fixed chatwoot line wrap issue + # 1.4.3 (2023-07-25 10:51) ### Fixed diff --git a/package.json b/package.json index 716aeec4..8cfd9f8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.3", + "version": "1.4.4", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 6e55d145..39873651 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1125,12 +1125,12 @@ export class ChatwootService { } if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is csat'); + this.logger.verbose('check if is template'); const data: SendTextDto = { number: chatId, textMessage: { - text: body.content, + text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), }, options: { delay: 1200, From 89f40d54d979b38d0583275b8fc20665d35bff20 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 12:41:54 -0300 Subject: [PATCH 055/177] fix: Solved receive location in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eda7c55..4a2f5b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Fixed chatwoot line wrap issue +* Solved receive location in chatwoot # 1.4.3 (2023-07-25 10:51) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 39873651..5a981238 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -13,6 +13,7 @@ import { SendAudioDto } from '../dto/sendMessage.dto'; import { SendMediaDto } from '../dto/sendMessage.dto'; import { ROOT_DIR } from '../../config/path.config'; import { ConfigService, HttpServer } from '../../config/env.config'; +import { type } from 'os'; export class ChatwootService { private messageCacheFile: string; @@ -1186,6 +1187,10 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: + msg.locationMessage?.degreesLatitude + + ',' + + msg.locationMessage?.degreesLongitude, }; this.logger.verbose('type message: ' + types); @@ -1199,6 +1204,20 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; + if (typeKey === 'locationMessage') { + const [latitude, longitude] = result.split(','); + + const formattedLocation = `**Location:** + **latitude:** ${latitude} + **longitude:** ${longitude} + https://www.google.com/maps/search/?api=1&query=${latitude},${longitude} + `; + + this.logger.verbose('message content: ' + formattedLocation); + + return formattedLocation; + } + if (typeKey === 'contactMessage') { const vCardData = result.split('\n'); const contactInfo = {}; From 14529f2c3580445a892a46dcdfdc25215e211d1a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 12:47:35 -0300 Subject: [PATCH 056/177] fix: When requesting the pairing code, it also brings the qr code --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2f5b55..bb0fd7bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixed chatwoot line wrap issue * Solved receive location in chatwoot +* When requesting the pairing code, it also brings the qr code # 1.4.3 (2023-07-25 10:51) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 8959197e..370d9b64 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -242,13 +242,9 @@ export class WAStartupService { public get qrCode(): wa.QrCode { this.logger.verbose('Getting qrcode'); - if (this.instance.qrcode?.pairingCode) { - return { - pairingCode: this.instance.qrcode?.pairingCode, - }; - } return { + pairingCode: this.instance.qrcode?.pairingCode, code: this.instance.qrcode?.code, base64: this.instance.qrcode?.base64, }; From f0d8c2d0954bb5a5f9bf7e3db943b7b53bc6dbf9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 13:19:15 -0300 Subject: [PATCH 057/177] fix: Solved receive location in chatwoot --- src/whatsapp/services/chatwoot.service.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 5a981238..c660f6d6 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1187,10 +1187,11 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: - msg.locationMessage?.degreesLatitude + - ',' + - msg.locationMessage?.degreesLongitude, + locationMessage: !msg.protocolMessage + ? msg.locationMessage?.degreesLatitude + + ',' + + msg.locationMessage?.degreesLongitude + : undefined, }; this.logger.verbose('type message: ' + types); From aef92240cc09ab7c74574c24d5ab916de89c0bb6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 15:20:21 -0300 Subject: [PATCH 058/177] fix: Option conversation_pending in chatwoot endpoint --- CHANGELOG.md | 2 + src/validate/validate.schema.ts | 21 ++++++++- .../controllers/chatwoot.controller.ts | 2 + .../controllers/instance.controller.ts | 24 ++++++++++ src/whatsapp/dto/chatwoot.dto.ts | 2 + src/whatsapp/dto/instance.dto.ts | 2 + src/whatsapp/models/chatwoot.model.ts | 2 + src/whatsapp/services/chatwoot.service.ts | 46 ++++++++++++++----- src/whatsapp/services/whatsapp.service.ts | 18 +++++++- src/whatsapp/types/wa.types.ts | 3 ++ 10 files changed, 107 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0fd7bb..3922d284 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ * Fixed chatwoot line wrap issue * Solved receive location in chatwoot * When requesting the pairing code, it also brings the qr code +* Option reopen_conversation in chatwoot endpoint +* Option conversation_pending in chatwoot endpoint # 1.4.3 (2023-07-25 10:51) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 62b7e41c..d7e2ac1e 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -874,9 +874,26 @@ export const chatwootSchema: JSONSchema7 = { token: { type: 'string' }, url: { type: 'string' }, sign_msg: { type: 'boolean', enum: [true, false] }, + reopen_conversation: { type: 'boolean', enum: [true, false] }, + conversation_pending: { type: 'boolean', enum: [true, false] }, }, - required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], - ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), + required: [ + 'enabled', + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ], + ...isNotEmpty( + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ), }; export const settingsSchema: JSONSchema7 = { diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index d5e5e841..ad92e607 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -44,6 +44,8 @@ export class ChatwootController { data.token = ''; data.url = ''; data.sign_msg = false; + data.reopen_conversation = false; + data.conversation_pending = false; } data.name_inbox = instance.instanceName; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 9be6ab5d..d9c351f7 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -42,6 +42,8 @@ export class InstanceController { chatwoot_token, chatwoot_url, chatwoot_sign_msg, + chatwoot_reopen_conversation, + chatwoot_conversation_pending, reject_call, msg_call, groups_ignore, @@ -169,6 +171,24 @@ export class InstanceController { throw new BadRequestException('Invalid "url" property in chatwoot'); } + if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + + if ( + chatwoot_reopen_conversation !== true && + chatwoot_reopen_conversation !== false + ) { + throw new BadRequestException('reopen_conversation is required'); + } + + if ( + chatwoot_conversation_pending !== true && + chatwoot_conversation_pending !== false + ) { + throw new BadRequestException('conversation_pending is required'); + } + const urlServer = this.configService.get('SERVER').URL; try { @@ -180,6 +200,8 @@ export class InstanceController { sign_msg: chatwoot_sign_msg || false, name_inbox: instance.instanceName, number, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, }); this.chatwootService.initInstanceChatwoot( @@ -209,6 +231,8 @@ export class InstanceController { token: chatwoot_token, url: chatwoot_url, sign_msg: chatwoot_sign_msg || false, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, number, name_inbox: instance.instanceName, webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index a5026a46..b270c869 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -6,4 +6,6 @@ export class ChatwootDto { name_inbox?: string; sign_msg?: boolean; number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index ca88a729..c317060f 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -16,4 +16,6 @@ export class InstanceDto { chatwoot_token?: string; chatwoot_url?: string; chatwoot_sign_msg?: boolean; + chatwoot_reopen_conversation?: boolean; + chatwoot_conversation_pending?: boolean; } diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 54d9e051..bac226e9 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -10,6 +10,8 @@ export class ChatwootRaw { name_inbox?: string; sign_msg?: boolean; number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } const chatwootSchema = new Schema({ diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c660f6d6..facea536 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -231,12 +231,19 @@ export class ChatwootService { if (qrcode) { this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + console.log('this.provider', this.provider); const conversation = await client.conversations.create({ accountId: this.provider.account_id, - data: { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }, + data, }); if (!conversation) { @@ -521,11 +528,20 @@ export class ChatwootService { })) as any; if (contactConversations) { + let conversation: any; + if (this.provider.reopen_conversation) { + conversation = contactConversations.payload.find( + (conversation) => conversation.inbox_id == filterInbox.id, + ); + } else { + conversation = contactConversations.payload.find( + (conversation) => + conversation.status !== 'resolved' && + conversation.inbox_id == filterInbox.id, + ); + } this.logger.verbose('return conversation if exists'); - const conversation = contactConversations.payload.find( - (conversation) => - conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, - ); + if (conversation) { this.logger.verbose('conversation found'); return conversation.id; @@ -533,12 +549,18 @@ export class ChatwootService { } this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: filterInbox.id.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + const conversation = await client.conversations.create({ accountId: this.provider.account_id, - data: { - contact_id: `${contactId}`, - inbox_id: `${filterInbox.id}`, - }, + data, }); if (!conversation) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 370d9b64..ccefcfa0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -312,6 +312,19 @@ export class WAStartupService { this.localChatwoot.sign_msg = data?.sign_msg; this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + this.localChatwoot.number = data?.number; + this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); + + this.localChatwoot.reopen_conversation = data?.reopen_conversation; + this.logger.verbose( + `Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`, + ); + + this.localChatwoot.conversation_pending = data?.conversation_pending; + this.logger.verbose( + `Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`, + ); + this.logger.verbose('Chatwoot loaded'); } @@ -323,6 +336,8 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); Object.assign(this.localChatwoot, data); this.logger.verbose('Chatwoot set'); @@ -342,6 +357,8 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); return data; } @@ -618,7 +635,6 @@ export class WAStartupService { color: { light: '#ffffff', dark: '#198754' }, }; - console.log(this.phoneNumber); if (this.phoneNumber) { await delay(2000); this.instance.qrcode.pairingCode = await this.client.requestPairingCode( diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 80aede98..a0d514d8 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -56,6 +56,9 @@ export declare namespace wa { url?: string; name_inbox?: string; sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; }; export type LocalSettings = { From 6bb1abd7f0a186dd535cb11610fc860e078cb219 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 15:29:42 -0300 Subject: [PATCH 059/177] fix: Option conversation_pending in chatwoot endpoint --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3922d284..f3a30ac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.4 (homolog) +# 1.4.4 (2023-07-25 15:24) ### Fixed From ecae077c6d50dc480934409efb00ee5f83a87389 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 16:16:49 -0300 Subject: [PATCH 060/177] fix: Option conversation_pending in chatwoot endpoint --- src/whatsapp/services/chatwoot.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index facea536..045c6519 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1209,7 +1209,7 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: !msg.protocolMessage + locationMessage: msg.locationMessage ? msg.locationMessage?.degreesLatitude + ',' + msg.locationMessage?.degreesLongitude From dd0c1e20a723b835407efbb3b96005de5a5a7680 Mon Sep 17 00:00:00 2001 From: CodePhix Date: Tue, 25 Jul 2023 19:59:42 -0300 Subject: [PATCH 061/177] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ccefcfa0..bd07f951 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1277,7 +1277,7 @@ export class WAStartupService { 5: 'PLAYED', }; for await (const { key, update } of args) { - if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { + if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { this.logger.verbose('group ignored'); return; } From de0c9a1eff88aa1d22fad9ba9f8b8676caa4aa96 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:34:10 -0300 Subject: [PATCH 062/177] fix: fixed problems in localization template --- CHANGELOG.md | 6 ++++++ src/whatsapp/services/chatwoot.service.ts | 15 ++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3a30ac7..88129b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.5 (2023-07-26 09:32) + +### Fixed + +* Fixed problems in localization template + # 1.4.4 (2023-07-25 15:24) ### Fixed diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 045c6519..90a0fa1a 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -240,7 +240,6 @@ export class ChatwootService { data['status'] = 'pending'; } - console.log('this.provider', this.provider); const conversation = await client.conversations.create({ accountId: this.provider.account_id, data, @@ -1209,11 +1208,8 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage - ? msg.locationMessage?.degreesLatitude + - ',' + - msg.locationMessage?.degreesLongitude - : undefined, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, }; this.logger.verbose('type message: ' + types); @@ -1227,8 +1223,9 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; - if (typeKey === 'locationMessage') { - const [latitude, longitude] = result.split(','); + if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { + const latitude = result.degreesLatitude; + const longitude = result.degreesLongitude; const formattedLocation = `**Location:** **latitude:** ${latitude} @@ -1311,7 +1308,7 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const types = this.getTypeMessage(msg); - += const messageContent = this.getMessageContent(types); this.logger.verbose('conversation message: ' + messageContent); From 3f41974a753285fd36fce7f0cdef3c4eb6cf044f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:38:22 -0300 Subject: [PATCH 063/177] fix: Fix mids going duplicated in chatwoot --- CHANGELOG.md | 3 ++- src/whatsapp/services/chatwoot.service.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88129b0e..cf5498ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ### Fixed -* Fixed problems in localization template +* Fixed problems in localization template in chatwoot +* Fix mids going duplicated in chatwoot # 1.4.4 (2023-07-25 15:24) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 90a0fa1a..2d470c37 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1308,7 +1308,7 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const types = this.getTypeMessage(msg); -= + const messageContent = this.getMessageContent(types); this.logger.verbose('conversation message: ' + messageContent); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index bd07f951..4c9bf62d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1147,7 +1147,7 @@ export class WAStartupService { if ( type !== 'notify' || - // received.message?.protocolMessage || + received.message?.protocolMessage || received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected'); From 67e98456bb39bfc7e545c5b90bf76160f458dce6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:39:27 -0300 Subject: [PATCH 064/177] fix: Fix mids going duplicated in chatwoot --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8cfd9f8d..0ef463d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.4", + "version": "1.4.5", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From e151eb85f0d556d5fa21c526aba140f0b6d7947f Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 10:30:26 -0300 Subject: [PATCH 065/177] wip --- .eslintrc.js | 11 +- package.json | 13 +- src/config/env.config.ts | 2 +- src/config/logger.config.ts | 3 +- src/db/db.connect.ts | 1 + src/db/redis.client.ts | 3 +- src/main.ts | 12 +- src/utils/server-up.ts | 5 +- src/utils/use-multi-file-auth-state-db.ts | 13 +- .../use-multi-file-auth-state-redis-db.ts | 5 +- src/whatsapp/abstract/abstract.repository.ts | 1 + src/whatsapp/abstract/abstract.router.ts | 12 +- src/whatsapp/controllers/chat.controller.ts | 5 +- .../controllers/chatwoot.controller.ts | 13 +- src/whatsapp/controllers/group.controller.ts | 2 +- .../controllers/instance.controller.ts | 13 +- .../controllers/sendMessage.controller.ts | 6 +- .../controllers/settings.controller.ts | 3 +- src/whatsapp/controllers/views.controller.ts | 1 + .../controllers/webhook.controller.ts | 3 +- src/whatsapp/dto/chat.dto.ts | 2 +- src/whatsapp/guards/auth.guard.ts | 9 +- src/whatsapp/guards/instance.guard.ts | 3 +- src/whatsapp/models/auth.model.ts | 1 + src/whatsapp/models/chat.model.ts | 1 + src/whatsapp/models/chatwoot.model.ts | 1 + src/whatsapp/models/contact.model.ts | 1 + src/whatsapp/models/message.model.ts | 1 + src/whatsapp/models/settings.model.ts | 1 + src/whatsapp/models/webhook.model.ts | 1 + src/whatsapp/repository/auth.repository.ts | 11 +- src/whatsapp/repository/chat.repository.ts | 9 +- .../repository/chatwoot.repository.ts | 9 +- src/whatsapp/repository/contact.repository.ts | 5 +- src/whatsapp/repository/message.repository.ts | 9 +- .../repository/messageUp.repository.ts | 9 +- src/whatsapp/repository/repository.manager.ts | 44 +++--- .../repository/settings.repository.ts | 9 +- src/whatsapp/repository/webhook.repository.ts | 9 +- src/whatsapp/routers/chat.router.ts | 15 +- src/whatsapp/routers/chatwoot.router.ts | 15 +- src/whatsapp/routers/group.router.ts | 23 +-- src/whatsapp/routers/index.router.ts | 9 +- src/whatsapp/routers/instance.router.ts | 15 +- src/whatsapp/routers/sendMessage.router.ts | 5 +- src/whatsapp/routers/settings.router.ts | 5 +- src/whatsapp/routers/view.router.ts | 1 + src/whatsapp/routers/webhook.router.ts | 3 +- src/whatsapp/services/auth.service.ts | 19 +-- src/whatsapp/services/chatwoot.service.ts | 19 ++- src/whatsapp/services/monitor.service.ts | 27 ++-- src/whatsapp/services/settings.service.ts | 2 +- src/whatsapp/services/webhook.service.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 146 +++++++++--------- src/whatsapp/whatsapp.module.ts | 45 +++--- 55 files changed, 340 insertions(+), 273 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d3545e60..e1bcd14d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,10 +3,14 @@ module.exports = { parserOptions: { sourceType: 'CommonJS', }, - plugins: ['@typescript-eslint/eslint-plugin'], + plugins: [ + '@typescript-eslint', + 'simple-import-sort', + 'import' + ], extends: [ + 'eslint:recommended', 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', 'plugin:prettier/recommended' ], globals: { @@ -27,6 +31,9 @@ module.exports = { '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-unused-vars': 'off', + 'import/first': 'error', + 'import/no-duplicates': 'error', + 'simple-import-sort/imports': 'error', '@typescript-eslint/ban-types': [ 'error', { diff --git a/package.json b/package.json index 1145676d..4d82309c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "start": "ts-node --files --transpile-only ./src/main.ts", "start:prod": "bash start.sh", "dev:server": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./src/main.ts", - "test": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./test/all.test.ts" + "test": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./test/all.test.ts", + "lint": "eslint --fix --ext .ts src" }, "repository": { "type": "git", @@ -84,12 +85,14 @@ "@types/qrcode": "^1.5.0", "@types/qrcode-terminal": "^0.12.0", "@types/uuid": "^8.3.4", - "@typescript-eslint/eslint-plugin": "^5.57.1", - "@typescript-eslint/parser": "^5.57.1", - "eslint": "^8.38.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.45.0", "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.7", + "eslint-plugin-simple-import-sort": "^10.0.0", + "prettier": "^2.8.8", "ts-node-dev": "^2.0.0", "typescript": "^4.9.5" } diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 88b718de..0c99a12b 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -1,7 +1,7 @@ +import { isBooleanString } from 'class-validator'; import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; -import { isBooleanString } from 'class-validator'; export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index 26e4c38f..a5ca6a23 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -1,6 +1,7 @@ -import { configService, Log } from './env.config'; import dayjs from 'dayjs'; +import { configService, Log } from './env.config'; + const formatDateLog = (timestamp: number) => dayjs(timestamp) .toDate() diff --git a/src/db/db.connect.ts b/src/db/db.connect.ts index 59530b48..b11610c7 100644 --- a/src/db/db.connect.ts +++ b/src/db/db.connect.ts @@ -1,4 +1,5 @@ import mongoose from 'mongoose'; + import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; diff --git a/src/db/redis.client.ts b/src/db/redis.client.ts index 50e7efcb..a9cbfb0b 100644 --- a/src/db/redis.client.ts +++ b/src/db/redis.client.ts @@ -1,7 +1,8 @@ import { createClient, RedisClientType } from '@redis/client'; -import { Logger } from '../config/logger.config'; import { BufferJSON } from '@whiskeysockets/baileys'; + import { Redis } from '../config/env.config'; +import { Logger } from '../config/logger.config'; export class RedisCache { constructor() { diff --git a/src/main.ts b/src/main.ts index ac66e7b5..7184f921 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,18 @@ +import 'express-async-errors'; + +// import * as Sentry from '@sentry/node'; import compression from 'compression'; -import { configService, Cors, HttpServer } from './config/env.config'; import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; + +import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; -import { waMonitor } from './whatsapp/whatsapp.module'; -import { HttpStatus, router } from './whatsapp/routers/index.router'; -import 'express-async-errors'; import { ServerUP } from './utils/server-up'; -import * as Sentry from '@sentry/node'; +import { HttpStatus, router } from './whatsapp/routers/index.router'; +import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { waMonitor.loadInstance(); diff --git a/src/utils/server-up.ts b/src/utils/server-up.ts index 9868efc0..e06caea7 100644 --- a/src/utils/server-up.ts +++ b/src/utils/server-up.ts @@ -1,8 +1,9 @@ import { Express } from 'express'; import { readFileSync } from 'fs'; -import { configService, SslConf } from '../config/env.config'; -import * as https from 'https'; import * as http from 'http'; +import * as https from 'https'; + +import { configService, SslConf } from '../config/env.config'; export class ServerUP { static #app: Express; diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index d0c518da..e26b7a7e 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -6,6 +6,7 @@ import { proto, SignalDataTypeMap, } from '@whiskeysockets/baileys'; + import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; import { dbserver } from '../db/db.connect'; @@ -29,7 +30,9 @@ export async function useMultiFileAuthStateDb( JSON.parse(JSON.stringify(data, BufferJSON.replacer)), { upsert: true }, ); - } catch {} + } catch (error) { + logger.error(error); + } }; const readData = async (key: string): Promise => { @@ -38,14 +41,18 @@ export async function useMultiFileAuthStateDb( const data = await collection.findOne({ _id: key }); const creds = JSON.stringify(data); return JSON.parse(creds, BufferJSON.reviver); - } catch {} + } catch (error) { + logger.error(error); + } }; const removeData = async (key: string) => { try { await client.connect(); return await collection.deleteOne({ _id: key }); - } catch {} + } catch (error) { + logger.error(error); + } }; const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index c5450ddc..392d99ca 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -5,9 +5,10 @@ import { proto, SignalDataTypeMap, } from '@whiskeysockets/baileys'; -import { RedisCache } from '../db/redis.client'; -import { Logger } from '../config/logger.config'; + import { Redis } from '../config/env.config'; +import { Logger } from '../config/logger.config'; +import { RedisCache } from '../db/redis.client'; export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{ state: AuthenticationState; diff --git a/src/whatsapp/abstract/abstract.repository.ts b/src/whatsapp/abstract/abstract.repository.ts index a7215383..a0c4de6f 100644 --- a/src/whatsapp/abstract/abstract.repository.ts +++ b/src/whatsapp/abstract/abstract.repository.ts @@ -1,5 +1,6 @@ import { existsSync, mkdirSync, writeFileSync } from 'fs'; import { join } from 'path'; + import { ConfigService, Database } from '../../config/env.config'; import { ROOT_DIR } from '../../config/path.config'; diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index cb224cd6..7a9dc427 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -1,11 +1,13 @@ -import { InstanceDto } from '../dto/instance.dto'; -import { JSONSchema7 } from 'json-schema'; -import { Request } from 'express'; -import { validate } from 'jsonschema'; -import { BadRequestException } from '../../exceptions'; import 'express-async-errors'; + +import { Request } from 'express'; +import { JSONSchema7 } from 'json-schema'; +import { validate } from 'jsonschema'; + import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto'; +import { InstanceDto } from '../dto/instance.dto'; type DataValidate = { request: Request; diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index 454ddabf..8217b908 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -1,7 +1,10 @@ import { proto } from '@whiskeysockets/baileys'; + +import { Logger } from '../../config/logger.config'; import { ArchiveChatDto, DeleteMessage, + getBase64FromMediaMessageDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -9,14 +12,12 @@ import { ProfileStatusDto, ReadMessageDto, WhatsAppNumberDto, - getBase64FromMediaMessageDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; import { MessageQuery } from '../repository/message.repository'; import { MessageUpQuery } from '../repository/messageUp.repository'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('ChatController'); diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index d5e5e841..892c6905 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -1,11 +1,12 @@ import { isURL } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; -import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; -import { waMonitor } from '../whatsapp.module'; + import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChatwootService } from '../services/chatwoot.service'; +import { waMonitor } from '../whatsapp.module'; const logger = new Logger('ChatwootController'); diff --git a/src/whatsapp/controllers/group.controller.ts b/src/whatsapp/controllers/group.controller.ts index f4d381ce..56195f65 100644 --- a/src/whatsapp/controllers/group.controller.ts +++ b/src/whatsapp/controllers/group.controller.ts @@ -1,3 +1,4 @@ +import { Logger } from '../../config/logger.config'; import { CreateGroupDto, GetParticipant, @@ -13,7 +14,6 @@ import { } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('ChatController'); diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 7322e194..ab21986d 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -1,18 +1,19 @@ import { delay } from '@whiskeysockets/baileys'; +import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; + import { Auth, ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; -import { WAMonitoringService } from '../services/monitor.service'; -import { WAStartupService } from '../services/whatsapp.service'; -import { WebhookService } from '../services/webhook.service'; import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; +import { WAMonitoringService } from '../services/monitor.service'; +import { WebhookService } from '../services/webhook.service'; +import { WAStartupService } from '../services/whatsapp.service'; import { wa } from '../types/wa.types'; -import { RedisCache } from '../../db/redis.client'; -import { isURL } from 'class-validator'; export class InstanceController { constructor( diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index fb942a9c..2f49ca50 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -1,4 +1,6 @@ import { isBase64, isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { @@ -16,8 +18,6 @@ import { } from '../dto/sendMessage.dto'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; - const logger = new Logger('MessageRouter'); export class SendMessageController { @@ -109,7 +109,7 @@ export class SendMessageController { public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { logger.verbose('requested sendReaction from ' + instanceName + ' instance'); - if (!data.reactionMessage.reaction.match(/[^\(\)\w\sà-ú"-\+]+/)) { + if (!data.reactionMessage.reaction.match(/[^()\w\sà-ú"-+]+/)) { throw new BadRequestException('"reaction" must be an emoji'); } return await this.waMonitor.waInstances[instanceName].reactionMessage(data); diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 59031634..2c763b80 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -1,9 +1,10 @@ import { isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { SettingsService } from '../services/settings.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsController'); diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index 3f54ef39..327a209b 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -1,4 +1,5 @@ import { Request, Response } from 'express'; + import { Auth, ConfigService } from '../../config/env.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index b5747b2e..281147db 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -1,9 +1,10 @@ import { isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { WebhookService } from '../services/webhook.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('WebhookController'); diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 5af66a5e..2800c6ff 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,8 +1,8 @@ import { + proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue, - proto, } from '@whiskeysockets/baileys'; export class OnWhatsAppDto { diff --git a/src/whatsapp/guards/auth.guard.ts b/src/whatsapp/guards/auth.guard.ts index 8607cab4..6ddc297e 100644 --- a/src/whatsapp/guards/auth.guard.ts +++ b/src/whatsapp/guards/auth.guard.ts @@ -1,12 +1,13 @@ import { isJWT } from 'class-validator'; import { NextFunction, Request, Response } from 'express'; import jwt from 'jsonwebtoken'; + +import { name } from '../../../package.json'; import { Auth, configService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; -import { name } from '../../../package.json'; +import { ForbiddenException, UnauthorizedException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { JwtPayload } from '../services/auth.service'; -import { ForbiddenException, UnauthorizedException } from '../../exceptions'; import { repository } from '../whatsapp.module'; const logger = new Logger('GUARD'); @@ -86,7 +87,9 @@ async function apikey(req: Request, res: Response, next: NextFunction) { if (instanceKey.apikey === key) { return next(); } - } catch (error) {} + } catch (error) { + logger.error(error); + } throw new UnauthorizedException(); } diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 1e79ff1d..964b99b6 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -1,6 +1,8 @@ import { NextFunction, Request, Response } from 'express'; import { existsSync } from 'fs'; import { join } from 'path'; + +import { configService, Database, Redis } from '../../config/env.config'; import { INSTANCE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; import { @@ -10,7 +12,6 @@ import { } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; -import { Database, Redis, configService } from '../../config/env.config'; async function getInstance(instanceName: string) { const db = configService.get('DATABASE'); diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index b5da800d..5c5b6a41 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class AuthRaw { diff --git a/src/whatsapp/models/chat.model.ts b/src/whatsapp/models/chat.model.ts index ebf7f217..20153603 100644 --- a/src/whatsapp/models/chat.model.ts +++ b/src/whatsapp/models/chat.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ChatRaw { diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 54d9e051..307565eb 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { diff --git a/src/whatsapp/models/contact.model.ts b/src/whatsapp/models/contact.model.ts index c15411fa..d9b51e1e 100644 --- a/src/whatsapp/models/contact.model.ts +++ b/src/whatsapp/models/contact.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ContactRaw { diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index 4a684e53..c4f475ad 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; import { wa } from '../types/wa.types'; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b5eb7fe7..e70605e4 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class SettingsRaw { diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index 62ee38f4..fa91326c 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class WebhookRaw { diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 0d7e177f..9949cec3 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -1,10 +1,11 @@ -import { join } from 'path'; -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { IAuthModel, AuthRaw } from '../models'; import { readFileSync } from 'fs'; -import { AUTH_DIR } from '../../config/path.config'; +import { join } from 'path'; + +import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { AUTH_DIR } from '../../config/path.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { AuthRaw, IAuthModel } from '../models'; export class AuthRepository extends Repository { constructor( diff --git a/src/whatsapp/repository/chat.repository.ts b/src/whatsapp/repository/chat.repository.ts index 0f05760c..31e1764a 100644 --- a/src/whatsapp/repository/chat.repository.ts +++ b/src/whatsapp/repository/chat.repository.ts @@ -1,9 +1,10 @@ -import { join } from 'path'; -import { ConfigService, StoreConf } from '../../config/env.config'; -import { IInsert, Repository } from '../abstract/abstract.repository'; import { opendirSync, readFileSync, rmSync } from 'fs'; -import { ChatRaw, IChatModel } from '../models'; +import { join } from 'path'; + +import { ConfigService, StoreConf } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ChatRaw, IChatModel } from '../models'; export class ChatQuery { where: ChatRaw; diff --git a/src/whatsapp/repository/chatwoot.repository.ts b/src/whatsapp/repository/chatwoot.repository.ts index 3d24022a..bc722cd6 100644 --- a/src/whatsapp/repository/chatwoot.repository.ts +++ b/src/whatsapp/repository/chatwoot.repository.ts @@ -1,9 +1,10 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { IChatwootModel, ChatwootRaw } from '../models'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ChatwootRaw, IChatwootModel } from '../models'; export class ChatwootRepository extends Repository { constructor( diff --git a/src/whatsapp/repository/contact.repository.ts b/src/whatsapp/repository/contact.repository.ts index 648b5bf4..6a16f2a1 100644 --- a/src/whatsapp/repository/contact.repository.ts +++ b/src/whatsapp/repository/contact.repository.ts @@ -1,9 +1,10 @@ import { opendirSync, readFileSync } from 'fs'; import { join } from 'path'; + import { ConfigService, StoreConf } from '../../config/env.config'; -import { ContactRaw, IContactModel } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ContactRaw, IContactModel } from '../models'; export class ContactQuery { where: ContactRaw; diff --git a/src/whatsapp/repository/message.repository.ts b/src/whatsapp/repository/message.repository.ts index dbfe01fc..d9ccea99 100644 --- a/src/whatsapp/repository/message.repository.ts +++ b/src/whatsapp/repository/message.repository.ts @@ -1,9 +1,10 @@ -import { ConfigService, StoreConf } from '../../config/env.config'; -import { join } from 'path'; -import { IMessageModel, MessageRaw } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; import { opendirSync, readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService, StoreConf } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IMessageModel, MessageRaw } from '../models'; export class MessageQuery { where: MessageRaw; diff --git a/src/whatsapp/repository/messageUp.repository.ts b/src/whatsapp/repository/messageUp.repository.ts index 6a9f9cc4..fe2f623b 100644 --- a/src/whatsapp/repository/messageUp.repository.ts +++ b/src/whatsapp/repository/messageUp.repository.ts @@ -1,9 +1,10 @@ -import { ConfigService, StoreConf } from '../../config/env.config'; -import { IMessageUpModel, MessageUpdateRaw } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { join } from 'path'; import { opendirSync, readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService, StoreConf } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IMessageUpModel, MessageUpdateRaw } from '../models'; export class MessageUpQuery { where: MessageUpdateRaw; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index dde636c7..eea039a9 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -1,17 +1,17 @@ -import { MessageRepository } from './message.repository'; -import { ChatRepository } from './chat.repository'; -import { ContactRepository } from './contact.repository'; -import { MessageUpRepository } from './messageUp.repository'; -import { MongoClient } from 'mongodb'; -import { WebhookRepository } from './webhook.repository'; -import { ChatwootRepository } from './chatwoot.repository'; -import { SettingsRepository } from './settings.repository'; - -import { AuthRepository } from './auth.repository'; -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { join } from 'path'; import fs from 'fs'; +import { MongoClient } from 'mongodb'; +import { join } from 'path'; + +import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { AuthRepository } from './auth.repository'; +import { ChatRepository } from './chat.repository'; +import { ChatwootRepository } from './chatwoot.repository'; +import { ContactRepository } from './contact.repository'; +import { MessageRepository } from './message.repository'; +import { MessageUpRepository } from './messageUp.repository'; +import { SettingsRepository } from './settings.repository'; +import { WebhookRepository } from './webhook.repository'; export class RepositoryBroker { constructor( public readonly message: MessageRepository, @@ -97,17 +97,17 @@ export class RepositoryBroker { this.logger.error(error); } } else { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - - const tempDir = join(storePath, 'temp'); - - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } try { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } } catch (error) { this.logger.error(error); } diff --git a/src/whatsapp/repository/settings.repository.ts b/src/whatsapp/repository/settings.repository.ts index d253643d..704a3d7d 100644 --- a/src/whatsapp/repository/settings.repository.ts +++ b/src/whatsapp/repository/settings.repository.ts @@ -1,9 +1,10 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { ISettingsModel, SettingsRaw } from '../models'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ISettingsModel, SettingsRaw } from '../models'; export class SettingsRepository extends Repository { constructor( diff --git a/src/whatsapp/repository/webhook.repository.ts b/src/whatsapp/repository/webhook.repository.ts index d9b34af1..dc6d9154 100644 --- a/src/whatsapp/repository/webhook.repository.ts +++ b/src/whatsapp/repository/webhook.repository.ts @@ -1,9 +1,10 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { IWebhookModel, WebhookRaw } from '../models'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IWebhookModel, WebhookRaw } from '../models'; export class WebhookRepository extends Repository { constructor( diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index 49e64117..ecc8ebb6 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -1,4 +1,7 @@ +import { proto } from '@whiskeysockets/baileys'; import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { archiveChatSchema, contactValidateSchema, @@ -13,9 +16,11 @@ import { readMessageSchema, whatsappNumberSchema, } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; import { ArchiveChatDto, DeleteMessage, + getBase64FromMediaMessageDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -23,17 +28,13 @@ import { ProfileStatusDto, ReadMessageDto, WhatsAppNumberDto, - getBase64FromMediaMessageDto, } from '../dto/chat.dto'; +import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; import { MessageQuery } from '../repository/message.repository'; -import { chatController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; -import { HttpStatus } from './index.router'; import { MessageUpQuery } from '../repository/messageUp.repository'; -import { proto } from '@whiskeysockets/baileys'; -import { InstanceDto } from '../dto/instance.dto'; -import { Logger } from '../../config/logger.config'; +import { chatController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('ChatRouter'); diff --git a/src/whatsapp/routers/chatwoot.router.ts b/src/whatsapp/routers/chatwoot.router.ts index 3d87f137..74e47552 100644 --- a/src/whatsapp/routers/chatwoot.router.ts +++ b/src/whatsapp/routers/chatwoot.router.ts @@ -1,12 +1,13 @@ import { RequestHandler, Router } from 'express'; -import { instanceNameSchema, chatwootSchema } from '../../validate/validate.schema'; -import { RouterBroker } from '../abstract/abstract.router'; -import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { chatwootController } from '../whatsapp.module'; -import { ChatwootService } from '../services/chatwoot.service'; -import { HttpStatus } from './index.router'; + import { Logger } from '../../config/logger.config'; +import { chatwootSchema, instanceNameSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChatwootService } from '../services/chatwoot.service'; +import { chatwootController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('ChatwootRouter'); diff --git a/src/whatsapp/routers/group.router.ts b/src/whatsapp/routers/group.router.ts index 4c1b3023..7d95ef10 100644 --- a/src/whatsapp/routers/group.router.ts +++ b/src/whatsapp/routers/group.router.ts @@ -1,34 +1,35 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { createGroupSchema, + getParticipantsSchema, + groupInviteSchema, groupJidSchema, - updateParticipantsSchema, - updateSettingsSchema, + groupSendInviteSchema, toggleEphemeralSchema, + updateGroupDescriptionSchema, updateGroupPictureSchema, updateGroupSubjectSchema, - updateGroupDescriptionSchema, - groupInviteSchema, - groupSendInviteSchema, - getParticipantsSchema, + updateParticipantsSchema, + updateSettingsSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { CreateGroupDto, + GetParticipant, + GroupDescriptionDto, GroupInvite, GroupJid, GroupPictureDto, + GroupSendInvite, GroupSubjectDto, - GroupDescriptionDto, + GroupToggleEphemeralDto, GroupUpdateParticipantDto, GroupUpdateSettingDto, - GroupToggleEphemeralDto, - GroupSendInvite, - GetParticipant, } from '../dto/group.dto'; import { groupController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('GroupRouter'); diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 4cf7befb..f58906b9 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -1,16 +1,17 @@ import { Router } from 'express'; +import fs from 'fs'; + import { Auth, configService } from '../../config/env.config'; -import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard'; import { authGuard } from '../guards/auth.guard'; +import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard'; import { ChatRouter } from './chat.router'; +import { ChatwootRouter } from './chatwoot.router'; import { GroupRouter } from './group.router'; import { InstanceRouter } from './instance.router'; import { MessageRouter } from './sendMessage.router'; +import { SettingsRouter } from './settings.router'; import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; -import { ChatwootRouter } from './chatwoot.router'; -import fs from 'fs'; -import { SettingsRouter } from './settings.router'; enum HttpStatus { OK = 200, diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 850ffebd..e3dbd4a9 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -1,13 +1,14 @@ import { RequestHandler, Router } from 'express'; -import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema'; -import { InstanceDto } from '../dto/instance.dto'; -import { instanceController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; -import { HttpStatus } from './index.router'; -import { OldToken } from '../services/auth.service'; + import { Auth, ConfigService, Database } from '../../config/env.config'; -import { dbserver } from '../../db/db.connect'; import { Logger } from '../../config/logger.config'; +import { dbserver } from '../../db/db.connect'; +import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { OldToken } from '../services/auth.service'; +import { instanceController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('InstanceRouter'); diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index f6f9c3eb..ae79d387 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -1,4 +1,6 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { audioMessageSchema, buttonMessageSchema, @@ -12,6 +14,7 @@ import { stickerMessageSchema, textMessageSchema, } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; import { SendAudioDto, SendButtonDto, @@ -26,9 +29,7 @@ import { SendTextDto, } from '../dto/sendMessage.dto'; import { sendMessageController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('MessageRouter'); diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts index 3ec3df83..c45dd49b 100644 --- a/src/whatsapp/routers/settings.router.ts +++ b/src/whatsapp/routers/settings.router.ts @@ -1,12 +1,13 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { instanceNameSchema, settingsSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; -import { settingsController } from '../whatsapp.module'; import { SettingsService } from '../services/settings.service'; +import { settingsController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsRouter'); diff --git a/src/whatsapp/routers/view.router.ts b/src/whatsapp/routers/view.router.ts index b5ddc008..c5e18129 100644 --- a/src/whatsapp/routers/view.router.ts +++ b/src/whatsapp/routers/view.router.ts @@ -1,4 +1,5 @@ import { RequestHandler, Router } from 'express'; + import { RouterBroker } from '../abstract/abstract.router'; import { viewsController } from '../whatsapp.module'; diff --git a/src/whatsapp/routers/webhook.router.ts b/src/whatsapp/routers/webhook.router.ts index c520d9d5..835d6014 100644 --- a/src/whatsapp/routers/webhook.router.ts +++ b/src/whatsapp/routers/webhook.router.ts @@ -1,11 +1,12 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { instanceNameSchema, webhookSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { webhookController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('WebhookRouter'); diff --git a/src/whatsapp/services/auth.service.ts b/src/whatsapp/services/auth.service.ts index 88a84905..3854e148 100644 --- a/src/whatsapp/services/auth.service.ts +++ b/src/whatsapp/services/auth.service.ts @@ -1,14 +1,15 @@ -import { Auth, ConfigService, Webhook } from '../../config/env.config'; -import { InstanceDto } from '../dto/instance.dto'; -import { name as apiName } from '../../../package.json'; -import { verify, sign } from 'jsonwebtoken'; -import { Logger } from '../../config/logger.config'; -import { v4 } from 'uuid'; -import { isJWT } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; import axios from 'axios'; -import { WAMonitoringService } from './monitor.service'; +import { isJWT } from 'class-validator'; +import { sign, verify } from 'jsonwebtoken'; +import { v4 } from 'uuid'; + +import { name as apiName } from '../../../package.json'; +import { Auth, ConfigService, Webhook } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; +import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; +import { WAMonitoringService } from './monitor.service'; export type JwtPayload = { instanceName: string; diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c77162ad..11a2a78f 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1,18 +1,17 @@ -import { InstanceDto } from '../dto/instance.dto'; -import path from 'path'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; import ChatwootClient from '@figuro/chatwoot-sdk'; -import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import axios from 'axios'; import FormData from 'form-data'; -import { SendTextDto } from '../dto/sendMessage.dto'; +import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import mimeTypes from 'mime-types'; -import { SendAudioDto } from '../dto/sendMessage.dto'; -import { SendMediaDto } from '../dto/sendMessage.dto'; -import { ROOT_DIR } from '../../config/path.config'; +import path from 'path'; + import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { ROOT_DIR } from '../../config/path.config'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; +import { WAMonitoringService } from './monitor.service'; export class ChatwootService { private messageCacheFile: string; diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 7ffa81e1..afeeb872 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -1,9 +1,10 @@ -import { opendirSync, readdirSync, rmSync } from 'fs'; -import { WAStartupService } from './whatsapp.service'; -import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; +import { execSync } from 'child_process'; import EventEmitter2 from 'eventemitter2'; +import { opendirSync, readdirSync, rmSync } from 'fs'; +import { Db } from 'mongodb'; +import mongoose from 'mongoose'; import { join } from 'path'; -import { Logger } from '../../config/logger.config'; + import { Auth, ConfigService, @@ -12,13 +13,11 @@ import { HttpServer, Redis, } from '../../config/env.config'; -import { RepositoryBroker } from '../repository/repository.manager'; -import { NotFoundException } from '../../exceptions'; -import { Db } from 'mongodb'; -import { RedisCache } from '../../db/redis.client'; -import { execSync } from 'child_process'; +import { Logger } from '../../config/logger.config'; +import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; -import mongoose from 'mongoose'; +import { RedisCache } from '../../db/redis.client'; +import { NotFoundException } from '../../exceptions'; import { AuthModel, ChatwootModel, @@ -28,6 +27,8 @@ import { SettingsModel, WebhookModel, } from '../models'; +import { RepositoryBroker } from '../repository/repository.manager'; +import { WAStartupService } from './whatsapp.service'; export class WAMonitoringService { constructor( @@ -183,7 +184,7 @@ export class WAMonitoringService { }); this.logger.verbose('instance files deleted: ' + name); }); - } else if (this.redis.ENABLED) { + // } else if (this.redis.ENABLED) { } else { const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); for await (const dirent of dir) { @@ -337,7 +338,9 @@ export class WAMonitoringService { try { this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); this.waInstances[instanceName] = undefined; - } catch {} + } catch (error) { + this.logger.error(error); + } try { this.logger.verbose('request cleaning up instance: ' + instanceName); diff --git a/src/whatsapp/services/settings.service.ts b/src/whatsapp/services/settings.service.ts index 9a82046a..f00138e1 100644 --- a/src/whatsapp/services/settings.service.ts +++ b/src/whatsapp/services/settings.service.ts @@ -1,7 +1,7 @@ +import { Logger } from '../../config/logger.config'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; export class SettingsService { constructor(private readonly waMonitor: WAMonitoringService) {} diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index 2370e05b..1ffdce6f 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -1,7 +1,7 @@ +import { Logger } from '../../config/logger.config'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; export class WebhookService { constructor(private readonly waMonitor: WAMonitoringService) {} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6c7c96f0..17c654da 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,9 +1,10 @@ +import ffmpegPath from '@ffmpeg-installer/ffmpeg'; +import { Boom } from '@hapi/boom'; import makeWASocket, { AnyMessageContent, BufferedEventData, BufferJSON, CacheStore, - makeCacheableSignalKeyStore, Chat, ConnectionState, Contact, @@ -12,11 +13,13 @@ import makeWASocket, { downloadMediaMessage, fetchLatestBaileysVersion, generateWAMessageFromContent, + getAggregateVotesInPollMessage, getContentType, getDevice, GroupMetadata, isJidGroup, isJidUser, + makeCacheableSignalKeyStore, MessageUpsertType, MiscMessageGenerationOptions, ParticipantAction, @@ -29,8 +32,24 @@ import makeWASocket, { WAMessage, WAMessageUpdate, WASocket, - getAggregateVotesInPollMessage, } from '@whiskeysockets/baileys'; +import axios from 'axios'; +import { exec, execSync } from 'child_process'; +import { arrayUnique, isBase64, isURL } from 'class-validator'; +import EventEmitter2 from 'eventemitter2'; +import fs, { existsSync, readFileSync } from 'fs'; +import Long from 'long'; +import NodeCache from 'node-cache'; +import { getMIMEType } from 'node-mime-types'; +import { release } from 'os'; +import { join } from 'path'; +import P from 'pino'; +import ProxyAgent from 'proxy-agent'; +import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; +import qrcodeTerminal from 'qrcode-terminal'; +import sharp from 'sharp'; +import { v4 } from 'uuid'; + import { Auth, CleanStoreConf, @@ -38,31 +57,45 @@ import { ConfigSessionPhone, Database, HttpServer, + Log, QrCode, Redis, Webhook, } from '../../config/env.config'; -import fs from 'fs'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; -import { existsSync, readFileSync } from 'fs'; -import { join } from 'path'; -import axios from 'axios'; -import { v4 } from 'uuid'; -import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; -import qrcodeTerminal from 'qrcode-terminal'; -import { Events, TypeMediaMessage, wa, MessageSubtype } from '../types/wa.types'; -import { Boom } from '@hapi/boom'; -import EventEmitter2 from 'eventemitter2'; -import { release } from 'os'; -import P from 'pino'; -import { execSync, exec } from 'child_process'; -import ffmpegPath from '@ffmpeg-installer/ffmpeg'; -import { RepositoryBroker } from '../repository/repository.manager'; -import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; -import { ContactRaw } from '../models/contact.model'; -import { ChatRaw } from '../models/chat.model'; -import { getMIMEType } from 'node-mime-types'; +import { dbserver } from '../../db/db.connect'; +import { RedisCache } from '../../db/redis.client'; +import { + BadRequestException, + InternalServerErrorException, + NotFoundException, +} from '../../exceptions'; +import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; +import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; +import { + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, +} from '../dto/chat.dto'; +import { + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, +} from '../dto/group.dto'; import { ContactMessage, MediaMessage, @@ -73,59 +106,26 @@ import { SendListDto, SendLocationDto, SendMediaDto, - SendReactionDto, - SendTextDto, SendPollDto, - SendStickerDto, + SendReactionDto, SendStatusDto, + SendStickerDto, + SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { arrayUnique, isBase64, isURL } from 'class-validator'; -import { - ArchiveChatDto, - DeleteMessage, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, - getBase64FromMediaMessageDto, -} from '../dto/chat.dto'; -import { MessageQuery } from '../repository/message.repository'; -import { ContactQuery } from '../repository/contact.repository'; -import { - BadRequestException, - InternalServerErrorException, - NotFoundException, -} from '../../exceptions'; -import { - CreateGroupDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, - GroupToggleEphemeralDto, - GroupSubjectDto, - GroupDescriptionDto, - GroupSendInvite, - GetParticipant, -} from '../dto/group.dto'; -import { MessageUpQuery } from '../repository/messageUp.repository'; -import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; -import Long from 'long'; -import { WebhookRaw } from '../models/webhook.model'; -import { ChatwootRaw } from '../models/chatwoot.model'; -import { dbserver } from '../../db/db.connect'; -import NodeCache from 'node-cache'; -import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; -import sharp from 'sharp'; -import { RedisCache } from '../../db/redis.client'; -import { Log } from '../../config/env.config'; -import ProxyAgent from 'proxy-agent'; -import { ChatwootService } from './chatwoot.service'; -import { waMonitor } from '../whatsapp.module'; import { SettingsRaw } from '../models'; +import { ChatRaw } from '../models/chat.model'; +import { ChatwootRaw } from '../models/chatwoot.model'; +import { ContactRaw } from '../models/contact.model'; +import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; +import { WebhookRaw } from '../models/webhook.model'; +import { ContactQuery } from '../repository/contact.repository'; +import { MessageQuery } from '../repository/message.repository'; +import { MessageUpQuery } from '../repository/messageUp.repository'; +import { RepositoryBroker } from '../repository/repository.manager'; +import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; +import { waMonitor } from '../whatsapp.module'; +import { ChatwootService } from './chatwoot.service'; export class WAStartupService { constructor( @@ -395,7 +395,7 @@ export class WAStartupService { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[\.-]/gm, '_').toUpperCase(); + const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); const expose = @@ -796,7 +796,9 @@ export class WAStartupService { ); } } - } catch (error) {} + } catch (error) { + this.logger.error(error); + } }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); } } @@ -1514,7 +1516,7 @@ export class WAStartupService { .replace(/\+/g, '') .replace(/\(/g, '') .replace(/\)/g, '') - .split(/\:/)[0] + .split(':')[0] .split('@')[0]; if (number.length >= 18) { diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 9f2fed00..30f43015 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -1,43 +1,44 @@ +import { delay } from '@whiskeysockets/baileys'; + import { Auth, configService } from '../config/env.config'; -import { Logger } from '../config/logger.config'; import { eventEmitter } from '../config/event.config'; -import { MessageRepository } from './repository/message.repository'; -import { WAMonitoringService } from './services/monitor.service'; -import { ChatRepository } from './repository/chat.repository'; -import { ContactRepository } from './repository/contact.repository'; -import { MessageUpRepository } from './repository/messageUp.repository'; +import { Logger } from '../config/logger.config'; +import { dbserver } from '../db/db.connect'; +import { RedisCache } from '../db/redis.client'; import { ChatController } from './controllers/chat.controller'; +import { ChatwootController } from './controllers/chatwoot.controller'; +import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; -import { AuthService } from './services/auth.service'; -import { GroupController } from './controllers/group.controller'; +import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; -import { WebhookService } from './services/webhook.service'; import { WebhookController } from './controllers/webhook.controller'; -import { ChatwootService } from './services/chatwoot.service'; -import { ChatwootController } from './controllers/chatwoot.controller'; -import { RepositoryBroker } from './repository/repository.manager'; import { AuthModel, ChatModel, + ChatwootModel, ContactModel, MessageModel, MessageUpModel, - ChatwootModel, - WebhookModel, SettingsModel, + WebhookModel, } from './models'; -import { dbserver } from '../db/db.connect'; -import { WebhookRepository } from './repository/webhook.repository'; -import { ChatwootRepository } from './repository/chatwoot.repository'; import { AuthRepository } from './repository/auth.repository'; -import { WAStartupService } from './services/whatsapp.service'; -import { delay } from '@whiskeysockets/baileys'; -import { Events } from './types/wa.types'; -import { RedisCache } from '../db/redis.client'; +import { ChatRepository } from './repository/chat.repository'; +import { ChatwootRepository } from './repository/chatwoot.repository'; +import { ContactRepository } from './repository/contact.repository'; +import { MessageRepository } from './repository/message.repository'; +import { MessageUpRepository } from './repository/messageUp.repository'; +import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; +import { WebhookRepository } from './repository/webhook.repository'; +import { AuthService } from './services/auth.service'; +import { ChatwootService } from './services/chatwoot.service'; +import { WAMonitoringService } from './services/monitor.service'; import { SettingsService } from './services/settings.service'; -import { SettingsController } from './controllers/settings.controller'; +import { WebhookService } from './services/webhook.service'; +import { WAStartupService } from './services/whatsapp.service'; +import { Events } from './types/wa.types'; const logger = new Logger('WA MODULE'); From 03f3020e9f1c426524af2814416f43dbb6f946ca Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 10:30:56 -0300 Subject: [PATCH 066/177] wip --- .eslintrc.js | 1 + src/whatsapp/models/index.ts | 6 +++--- src/whatsapp/routers/index.router.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e1bcd14d..9ee852a4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { 'import/first': 'error', 'import/no-duplicates': 'error', 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', '@typescript-eslint/ban-types': [ 'error', { diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index e6c6d8b4..ee472de6 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -1,7 +1,7 @@ +export * from './auth.model'; export * from './chat.model'; +export * from './chatwoot.model'; export * from './contact.model'; export * from './message.model'; -export * from './auth.model'; -export * from './webhook.model'; -export * from './chatwoot.model'; export * from './settings.model'; +export * from './webhook.model'; diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index f58906b9..3cdcced7 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -49,4 +49,4 @@ router .use('/chatwoot', new ChatwootRouter(...guards).router) .use('/settings', new SettingsRouter(...guards).router); -export { router, HttpStatus }; +export { HttpStatus, router }; From 249aecbc0d0ba3071792df88eb5dab2df820bb16 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 10:58:13 -0300 Subject: [PATCH 067/177] wip --- .eslintrc.js | 2 +- .prettierrc.js | 11 +- src/config/env.config.ts | 410 +- src/config/error.config.ts | 28 +- src/config/event.config.ts | 6 +- src/config/logger.config.ts | 210 +- src/db/db.connect.ts | 26 +- src/db/redis.client.ts | 180 +- src/exceptions/400.exception.ts | 14 +- src/exceptions/401.exception.ts | 14 +- src/exceptions/403.exception.ts | 14 +- src/exceptions/404.exception.ts | 14 +- src/exceptions/500.exception.ts | 14 +- src/main.ts | 138 +- src/utils/server-up.ts | 34 +- src/utils/use-multi-file-auth-state-db.ts | 154 +- .../use-multi-file-auth-state-redis-db.ts | 133 +- src/validate/validate.schema.ts | 1404 ++-- src/whatsapp/abstract/abstract.repository.ts | 86 +- src/whatsapp/abstract/abstract.router.ts | 358 +- src/whatsapp/controllers/chat.controller.ts | 197 +- .../controllers/chatwoot.controller.ts | 147 +- src/whatsapp/controllers/group.controller.ts | 184 +- .../controllers/instance.controller.ts | 539 +- .../controllers/sendMessage.controller.ts | 184 +- .../controllers/settings.controller.ts | 28 +- src/whatsapp/controllers/views.controller.ts | 29 +- .../controllers/webhook.controller.ts | 34 +- src/whatsapp/dto/chat.dto.ts | 89 +- src/whatsapp/dto/chatwoot.dto.ts | 14 +- src/whatsapp/dto/group.dto.ts | 38 +- src/whatsapp/dto/instance.dto.ts | 22 +- src/whatsapp/dto/sendMessage.dto.ts | 144 +- src/whatsapp/dto/settings.dto.ts | 6 +- src/whatsapp/dto/webhook.dto.ts | 8 +- src/whatsapp/guards/auth.guard.ts | 124 +- src/whatsapp/guards/instance.guard.ts | 83 +- src/whatsapp/models/auth.model.ts | 12 +- src/whatsapp/models/chat.model.ts | 14 +- src/whatsapp/models/chatwoot.model.ts | 38 +- src/whatsapp/models/contact.model.ts | 20 +- src/whatsapp/models/message.model.ts | 94 +- src/whatsapp/models/settings.model.ts | 22 +- src/whatsapp/models/webhook.model.ts | 20 +- src/whatsapp/repository/auth.repository.ts | 109 +- src/whatsapp/repository/chat.repository.ts | 199 +- .../repository/chatwoot.repository.ts | 112 +- src/whatsapp/repository/contact.repository.ts | 332 +- src/whatsapp/repository/message.repository.ts | 265 +- .../repository/messageUp.repository.ts | 223 +- src/whatsapp/repository/repository.manager.ts | 194 +- .../repository/settings.repository.ts | 112 +- src/whatsapp/repository/webhook.repository.ts | 108 +- src/whatsapp/routers/chat.router.ts | 570 +- src/whatsapp/routers/chatwoot.router.ts | 94 +- src/whatsapp/routers/group.router.ts | 475 +- src/whatsapp/routers/index.router.ts | 46 +- src/whatsapp/routers/instance.router.ts | 316 +- src/whatsapp/routers/sendMessage.router.ts | 363 +- src/whatsapp/routers/settings.router.ts | 66 +- src/whatsapp/routers/view.router.ts | 14 +- src/whatsapp/routers/webhook.router.ts | 66 +- src/whatsapp/services/auth.service.ts | 307 +- src/whatsapp/services/chatwoot.service.ts | 3072 +++++---- src/whatsapp/services/monitor.service.ts | 651 +- src/whatsapp/services/settings.service.ts | 44 +- src/whatsapp/services/webhook.service.ts | 44 +- src/whatsapp/services/whatsapp.service.ts | 5628 ++++++++--------- src/whatsapp/types/wa.types.ts | 143 +- src/whatsapp/whatsapp.module.ts | 59 +- 70 files changed, 9184 insertions(+), 9768 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9ee852a4..f805da92 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,7 +30,7 @@ module.exports = { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', 'import/first': 'error', 'import/no-duplicates': 'error', 'simple-import-sort/imports': 'error', diff --git a/.prettierrc.js b/.prettierrc.js index 067abea5..362adbcb 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,8 +2,11 @@ module.exports = { semi: true, trailingComma: 'all', singleQuote: true, - printWidth: 90, - tabWidth: 2, - bracketSameLine: true, - bracketSpacing: true + printWidth: 120, + arrowParens: 'always', + tabWidth: 4, + useTabs: false, + bracketSameLine: false, + bracketSpacing: true, + parser: 'typescript' } \ No newline at end of file diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 0c99a12b..737fff51 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -7,107 +7,99 @@ export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { - ORIGIN: string[]; - METHODS: HttpMethods[]; - CREDENTIALS: boolean; + ORIGIN: string[]; + METHODS: HttpMethods[]; + CREDENTIALS: boolean; }; export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; -export type LogLevel = - | 'ERROR' - | 'WARN' - | 'DEBUG' - | 'INFO' - | 'LOG' - | 'VERBOSE' - | 'DARK' - | 'WEBHOOKS'; +export type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS'; export type Log = { - LEVEL: LogLevel[]; - COLOR: boolean; - BAILEYS: LogBaileys; + LEVEL: LogLevel[]; + COLOR: boolean; + BAILEYS: LogBaileys; }; export type SaveData = { - INSTANCE: boolean; - NEW_MESSAGE: boolean; - MESSAGE_UPDATE: boolean; - CONTACTS: boolean; - CHATS: boolean; + INSTANCE: boolean; + NEW_MESSAGE: boolean; + MESSAGE_UPDATE: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type StoreConf = { - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type CleanStoreConf = { - CLEANING_INTERVAL: number; - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + CLEANING_INTERVAL: number; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type DBConnection = { - URI: string; - DB_PREFIX_NAME: string; + URI: string; + DB_PREFIX_NAME: string; }; export type Database = { - CONNECTION: DBConnection; - ENABLED: boolean; - SAVE_DATA: SaveData; + CONNECTION: DBConnection; + ENABLED: boolean; + SAVE_DATA: SaveData; }; export type Redis = { - ENABLED: boolean; - URI: string; - PREFIX_KEY: string; + ENABLED: boolean; + URI: string; + PREFIX_KEY: string; }; export type EventsWebhook = { - APPLICATION_STARTUP: boolean; - QRCODE_UPDATED: boolean; - MESSAGES_SET: boolean; - MESSAGES_UPSERT: boolean; - MESSAGES_UPDATE: boolean; - MESSAGES_DELETE: boolean; - SEND_MESSAGE: boolean; - CONTACTS_SET: boolean; - CONTACTS_UPDATE: boolean; - CONTACTS_UPSERT: boolean; - PRESENCE_UPDATE: boolean; - CHATS_SET: boolean; - CHATS_UPDATE: boolean; - CHATS_DELETE: boolean; - CHATS_UPSERT: boolean; - CONNECTION_UPDATE: boolean; - GROUPS_UPSERT: boolean; - GROUP_UPDATE: boolean; - GROUP_PARTICIPANTS_UPDATE: boolean; - NEW_JWT_TOKEN: boolean; + APPLICATION_STARTUP: boolean; + QRCODE_UPDATED: boolean; + MESSAGES_SET: boolean; + MESSAGES_UPSERT: boolean; + MESSAGES_UPDATE: boolean; + MESSAGES_DELETE: boolean; + SEND_MESSAGE: boolean; + CONTACTS_SET: boolean; + CONTACTS_UPDATE: boolean; + CONTACTS_UPSERT: boolean; + PRESENCE_UPDATE: boolean; + CHATS_SET: boolean; + CHATS_UPDATE: boolean; + CHATS_DELETE: boolean; + CHATS_UPSERT: boolean; + CONNECTION_UPDATE: boolean; + GROUPS_UPSERT: boolean; + GROUP_UPDATE: boolean; + GROUP_PARTICIPANTS_UPDATE: boolean; + NEW_JWT_TOKEN: boolean; }; export type ApiKey = { KEY: string }; export type Jwt = { EXPIRIN_IN: number; SECRET: string }; export type Auth = { - API_KEY: ApiKey; - EXPOSE_IN_FETCH_INSTANCES: boolean; - JWT: Jwt; - TYPE: 'jwt' | 'apikey'; + API_KEY: ApiKey; + EXPOSE_IN_FETCH_INSTANCES: boolean; + JWT: Jwt; + TYPE: 'jwt' | 'apikey'; }; export type DelInstance = number | boolean; export type GlobalWebhook = { - URL: string; - ENABLED: boolean; - WEBHOOK_BY_EVENTS: boolean; + URL: string; + ENABLED: boolean; + WEBHOOK_BY_EVENTS: boolean; }; export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; @@ -116,161 +108,157 @@ export type QrCode = { LIMIT: number }; export type Production = boolean; export interface Env { - SERVER: HttpServer; - CORS: Cors; - SSL_CONF: SslConf; - STORE: StoreConf; - CLEAN_STORE: CleanStoreConf; - DATABASE: Database; - REDIS: Redis; - LOG: Log; - DEL_INSTANCE: DelInstance; - WEBHOOK: Webhook; - CONFIG_SESSION_PHONE: ConfigSessionPhone; - QRCODE: QrCode; - AUTHENTICATION: Auth; - PRODUCTION?: Production; + SERVER: HttpServer; + CORS: Cors; + SSL_CONF: SslConf; + STORE: StoreConf; + CLEAN_STORE: CleanStoreConf; + DATABASE: Database; + REDIS: Redis; + LOG: Log; + DEL_INSTANCE: DelInstance; + WEBHOOK: Webhook; + CONFIG_SESSION_PHONE: ConfigSessionPhone; + QRCODE: QrCode; + AUTHENTICATION: Auth; + PRODUCTION?: Production; } export type Key = keyof Env; export class ConfigService { - constructor() { - this.loadEnv(); - } - - private env: Env; - - public get(key: Key) { - return this.env[key] as T; - } - - private loadEnv() { - this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); - this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; - if (process.env?.DOCKER_ENV === 'true') { - this.env.SERVER.TYPE = 'http'; - this.env.SERVER.PORT = 8080; + constructor() { + this.loadEnv(); } - } - private envYaml(): Env { - return load( - readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' }), - ) as Env; - } + private env: Env; - private envProcess(): Env { - return { - SERVER: { - TYPE: process.env.SERVER_TYPE as 'http' | 'https', - PORT: Number.parseInt(process.env.SERVER_PORT), - URL: process.env.SERVER_URL, - }, - CORS: { - ORIGIN: process.env.CORS_ORIGIN.split(','), - METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], - CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', - }, - SSL_CONF: { - PRIVKEY: process.env?.SSL_CONF_PRIVKEY, - FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, - }, - STORE: { - MESSAGES: process.env?.STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.STORE_CONTACTS === 'true', - CHATS: process.env?.STORE_CHATS === 'true', - }, - CLEAN_STORE: { - CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) - ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) - : 7200, - MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', - CHATS: process.env?.CLEAN_STORE_CHATS === 'true', - }, - DATABASE: { - CONNECTION: { - URI: process.env.DATABASE_CONNECTION_URI, - DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, - }, - ENABLED: process.env?.DATABASE_ENABLED === 'true', - SAVE_DATA: { - INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', - NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', - MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', - CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', - CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', - }, - }, - REDIS: { - ENABLED: process.env?.REDIS_ENABLED === 'true', - URI: process.env.REDIS_URI, - PREFIX_KEY: process.env.REDIS_PREFIX_KEY, - }, - LOG: { - LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], - COLOR: process.env?.LOG_COLOR === 'true', - BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', - }, - DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 'true' - : Number.parseInt(process.env.DEL_INSTANCE) || false, - WEBHOOK: { - GLOBAL: { - URL: process.env?.WEBHOOK_GLOBAL_URL, - ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', - WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', - }, - EVENTS: { - APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', - QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', - MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', - MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', - MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', - MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', - SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', - CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', - CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', - CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', - PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', - CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', - CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', - CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', - CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', - CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', - GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', - GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', - GROUP_PARTICIPANTS_UPDATE: - process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', - NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', - }, - }, - CONFIG_SESSION_PHONE: { - CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', - NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', - }, - QRCODE: { - LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, - }, - AUTHENTICATION: { - TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', - API_KEY: { - KEY: process.env.AUTHENTICATION_API_KEY, - }, - EXPOSE_IN_FETCH_INSTANCES: - process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', - JWT: { - EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) - ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) - : 3600, - SECRET: process.env.AUTHENTICATION_JWT_SECRET, - }, - }, - }; - } + public get(key: Key) { + return this.env[key] as T; + } + + private loadEnv() { + this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); + this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; + if (process.env?.DOCKER_ENV === 'true') { + this.env.SERVER.TYPE = 'http'; + this.env.SERVER.PORT = 8080; + } + } + + private envYaml(): Env { + return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; + } + + private envProcess(): Env { + return { + SERVER: { + TYPE: process.env.SERVER_TYPE as 'http' | 'https', + PORT: Number.parseInt(process.env.SERVER_PORT), + URL: process.env.SERVER_URL, + }, + CORS: { + ORIGIN: process.env.CORS_ORIGIN.split(','), + METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], + CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', + }, + SSL_CONF: { + PRIVKEY: process.env?.SSL_CONF_PRIVKEY, + FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, + }, + STORE: { + MESSAGES: process.env?.STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.STORE_CONTACTS === 'true', + CHATS: process.env?.STORE_CHATS === 'true', + }, + CLEAN_STORE: { + CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) + ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) + : 7200, + MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', + CHATS: process.env?.CLEAN_STORE_CHATS === 'true', + }, + DATABASE: { + CONNECTION: { + URI: process.env.DATABASE_CONNECTION_URI, + DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, + }, + ENABLED: process.env?.DATABASE_ENABLED === 'true', + SAVE_DATA: { + INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', + NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', + MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', + CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', + CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', + }, + }, + REDIS: { + ENABLED: process.env?.REDIS_ENABLED === 'true', + URI: process.env.REDIS_URI, + PREFIX_KEY: process.env.REDIS_PREFIX_KEY, + }, + LOG: { + LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], + COLOR: process.env?.LOG_COLOR === 'true', + BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', + }, + DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) + ? process.env.DEL_INSTANCE === 'true' + : Number.parseInt(process.env.DEL_INSTANCE) || false, + WEBHOOK: { + GLOBAL: { + URL: process.env?.WEBHOOK_GLOBAL_URL, + ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', + WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', + }, + EVENTS: { + APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', + QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', + MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', + MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', + MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', + MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', + SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', + CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', + CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', + CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', + PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', + CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', + CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', + CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', + CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', + CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', + GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', + GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', + GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', + }, + }, + CONFIG_SESSION_PHONE: { + CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', + }, + QRCODE: { + LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, + }, + AUTHENTICATION: { + TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', + API_KEY: { + KEY: process.env.AUTHENTICATION_API_KEY, + }, + EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', + JWT: { + EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) + ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) + : 3600, + SECRET: process.env.AUTHENTICATION_JWT_SECRET, + }, + }, + }; + } } export const configService = new ConfigService(); diff --git a/src/config/error.config.ts b/src/config/error.config.ts index 6449d52e..999205c4 100644 --- a/src/config/error.config.ts +++ b/src/config/error.config.ts @@ -1,21 +1,21 @@ import { Logger } from './logger.config'; export function onUnexpectedError() { - process.on('uncaughtException', (error, origin) => { - const logger = new Logger('uncaughtException'); - logger.error({ - origin, - stderr: process.stderr.fd, - error, + process.on('uncaughtException', (error, origin) => { + const logger = new Logger('uncaughtException'); + logger.error({ + origin, + stderr: process.stderr.fd, + error, + }); }); - }); - process.on('unhandledRejection', (error, origin) => { - const logger = new Logger('unhandledRejection'); - logger.error({ - origin, - stderr: process.stderr.fd, - error, + process.on('unhandledRejection', (error, origin) => { + const logger = new Logger('unhandledRejection'); + logger.error({ + origin, + stderr: process.stderr.fd, + error, + }); }); - }); } diff --git a/src/config/event.config.ts b/src/config/event.config.ts index 8451ffdf..ec917110 100644 --- a/src/config/event.config.ts +++ b/src/config/event.config.ts @@ -1,7 +1,7 @@ import EventEmitter2 from 'eventemitter2'; export const eventEmitter = new EventEmitter2({ - delimiter: '.', - newListener: false, - ignoreErrors: false, + delimiter: '.', + newListener: false, + ignoreErrors: false, }); diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index a5ca6a23..9fe6bac2 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -3,135 +3,135 @@ import dayjs from 'dayjs'; import { configService, Log } from './env.config'; const formatDateLog = (timestamp: number) => - dayjs(timestamp) - .toDate() - .toString() - .replace(/\sGMT.+/, ''); + dayjs(timestamp) + .toDate() + .toString() + .replace(/\sGMT.+/, ''); enum Color { - LOG = '\x1b[32m', - INFO = '\x1b[34m', - WARN = '\x1b[33m', - ERROR = '\x1b[31m', - DEBUG = '\x1b[36m', - VERBOSE = '\x1b[37m', - DARK = '\x1b[30m', + LOG = '\x1b[32m', + INFO = '\x1b[34m', + WARN = '\x1b[33m', + ERROR = '\x1b[31m', + DEBUG = '\x1b[36m', + VERBOSE = '\x1b[37m', + DARK = '\x1b[30m', } enum Command { - RESET = '\x1b[0m', - BRIGHT = '\x1b[1m', - UNDERSCORE = '\x1b[4m', + RESET = '\x1b[0m', + BRIGHT = '\x1b[1m', + UNDERSCORE = '\x1b[4m', } enum Level { - LOG = Color.LOG + '%s' + Command.RESET, - DARK = Color.DARK + '%s' + Command.RESET, - INFO = Color.INFO + '%s' + Command.RESET, - WARN = Color.WARN + '%s' + Command.RESET, - ERROR = Color.ERROR + '%s' + Command.RESET, - DEBUG = Color.DEBUG + '%s' + Command.RESET, - VERBOSE = Color.VERBOSE + '%s' + Command.RESET, + LOG = Color.LOG + '%s' + Command.RESET, + DARK = Color.DARK + '%s' + Command.RESET, + INFO = Color.INFO + '%s' + Command.RESET, + WARN = Color.WARN + '%s' + Command.RESET, + ERROR = Color.ERROR + '%s' + Command.RESET, + DEBUG = Color.DEBUG + '%s' + Command.RESET, + VERBOSE = Color.VERBOSE + '%s' + Command.RESET, } enum Type { - LOG = 'LOG', - WARN = 'WARN', - INFO = 'INFO', - DARK = 'DARK', - ERROR = 'ERROR', - DEBUG = 'DEBUG', - VERBOSE = 'VERBOSE', + LOG = 'LOG', + WARN = 'WARN', + INFO = 'INFO', + DARK = 'DARK', + ERROR = 'ERROR', + DEBUG = 'DEBUG', + VERBOSE = 'VERBOSE', } enum Background { - LOG = '\x1b[42m', - INFO = '\x1b[44m', - WARN = '\x1b[43m', - DARK = '\x1b[40m', - ERROR = '\x1b[41m', - DEBUG = '\x1b[46m', - VERBOSE = '\x1b[47m', + LOG = '\x1b[42m', + INFO = '\x1b[44m', + WARN = '\x1b[43m', + DARK = '\x1b[40m', + ERROR = '\x1b[41m', + DEBUG = '\x1b[46m', + VERBOSE = '\x1b[47m', } export class Logger { - private readonly configService = configService; - constructor(private context = 'Logger') {} + private readonly configService = configService; + constructor(private context = 'Logger') {} - public setContext(value: string) { - this.context = value; - } - - private console(value: any, type: Type) { - const types: Type[] = []; - - this.configService.get('LOG').LEVEL.forEach((level) => types.push(Type[level])); - - const typeValue = typeof value; - if (types.includes(type)) { - if (configService.get('LOG').COLOR) { - console.log( - /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], - '[Evolution API]', - Command.BRIGHT + Color[type], - process.pid.toString(), - Command.RESET, - Command.BRIGHT + Color[type], - '-', - Command.BRIGHT + Color.VERBOSE, - `${formatDateLog(Date.now())} `, - Command.RESET, - Color[type] + Background[type] + Command.BRIGHT, - `${type} ` + Command.RESET, - Color.WARN + Command.BRIGHT, - `[${this.context}]` + Command.RESET, - Color[type] + Command.BRIGHT, - `[${typeValue}]` + Command.RESET, - Color[type], - typeValue !== 'object' ? value : '', - Command.RESET, - ); - typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : ''; - } else { - console.log( - '[Evolution API]', - process.pid.toString(), - '-', - `${formatDateLog(Date.now())} `, - `${type} `, - `[${this.context}]`, - `[${typeValue}]`, - value, - ); - } + public setContext(value: string) { + this.context = value; } - } - public log(value: any) { - this.console(value, Type.LOG); - } + private console(value: any, type: Type) { + const types: Type[] = []; - public info(value: any) { - this.console(value, Type.INFO); - } + this.configService.get('LOG').LEVEL.forEach((level) => types.push(Type[level])); - public warn(value: any) { - this.console(value, Type.WARN); - } + const typeValue = typeof value; + if (types.includes(type)) { + if (configService.get('LOG').COLOR) { + console.log( + /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], + '[Evolution API]', + Command.BRIGHT + Color[type], + process.pid.toString(), + Command.RESET, + Command.BRIGHT + Color[type], + '-', + Command.BRIGHT + Color.VERBOSE, + `${formatDateLog(Date.now())} `, + Command.RESET, + Color[type] + Background[type] + Command.BRIGHT, + `${type} ` + Command.RESET, + Color.WARN + Command.BRIGHT, + `[${this.context}]` + Command.RESET, + Color[type] + Command.BRIGHT, + `[${typeValue}]` + Command.RESET, + Color[type], + typeValue !== 'object' ? value : '', + Command.RESET, + ); + typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : ''; + } else { + console.log( + '[Evolution API]', + process.pid.toString(), + '-', + `${formatDateLog(Date.now())} `, + `${type} `, + `[${this.context}]`, + `[${typeValue}]`, + value, + ); + } + } + } - public error(value: any) { - this.console(value, Type.ERROR); - } + public log(value: any) { + this.console(value, Type.LOG); + } - public verbose(value: any) { - this.console(value, Type.VERBOSE); - } + public info(value: any) { + this.console(value, Type.INFO); + } - public debug(value: any) { - this.console(value, Type.DEBUG); - } + public warn(value: any) { + this.console(value, Type.WARN); + } - public dark(value: any) { - this.console(value, Type.DARK); - } + public error(value: any) { + this.console(value, Type.ERROR); + } + + public verbose(value: any) { + this.console(value, Type.VERBOSE); + } + + public debug(value: any) { + this.console(value, Type.DEBUG); + } + + public dark(value: any) { + this.console(value, Type.DARK); + } } diff --git a/src/db/db.connect.ts b/src/db/db.connect.ts index b11610c7..e7e965ac 100644 --- a/src/db/db.connect.ts +++ b/src/db/db.connect.ts @@ -7,19 +7,19 @@ const logger = new Logger('MongoDB'); const db = configService.get('DATABASE'); export const dbserver = (() => { - if (db.ENABLED) { - logger.verbose('connecting'); - const dbs = mongoose.createConnection(db.CONNECTION.URI, { - dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api', - }); - logger.verbose('connected in ' + db.CONNECTION.URI); - logger.info('ON - dbName: ' + dbs['$dbName']); + if (db.ENABLED) { + logger.verbose('connecting'); + const dbs = mongoose.createConnection(db.CONNECTION.URI, { + dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api', + }); + logger.verbose('connected in ' + db.CONNECTION.URI); + logger.info('ON - dbName: ' + dbs['$dbName']); - process.on('beforeExit', () => { - logger.verbose('instance destroyed'); - dbserver.destroy(true, (error) => logger.error(error)); - }); + process.on('beforeExit', () => { + logger.verbose('instance destroyed'); + dbserver.destroy(true, (error) => logger.error(error)); + }); - return dbs; - } + return dbs; + } })(); diff --git a/src/db/redis.client.ts b/src/db/redis.client.ts index a9cbfb0b..5f0604bc 100644 --- a/src/db/redis.client.ts +++ b/src/db/redis.client.ts @@ -5,113 +5,101 @@ import { Redis } from '../config/env.config'; import { Logger } from '../config/logger.config'; export class RedisCache { - constructor() { - this.logger.verbose('instance created'); - process.on('beforeExit', async () => { - this.logger.verbose('instance destroyed'); - if (this.statusConnection) { - this.logger.verbose('instance disconnect'); - await this.client.disconnect(); - } - }); - } - - private statusConnection = false; - private instanceName: string; - private redisEnv: Redis; - - public set reference(reference: string) { - this.logger.verbose('set reference: ' + reference); - this.instanceName = reference; - } - - public async connect(redisEnv: Redis) { - this.logger.verbose('connecting'); - this.client = createClient({ url: redisEnv.URI }); - this.logger.verbose('connected in ' + redisEnv.URI); - await this.client.connect(); - this.statusConnection = true; - this.redisEnv = redisEnv; - } - - private readonly logger = new Logger(RedisCache.name); - private client: RedisClientType; - - public async instanceKeys(): Promise { - try { - this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*'); - return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']); - } catch (error) { - this.logger.error(error); + constructor() { + this.logger.verbose('instance created'); + process.on('beforeExit', async () => { + this.logger.verbose('instance destroyed'); + if (this.statusConnection) { + this.logger.verbose('instance disconnect'); + await this.client.disconnect(); + } + }); } - } - public async keyExists(key?: string) { - if (key) { - this.logger.verbose('keyExists: ' + key); - return !!(await this.instanceKeys()).find((i) => i === key); + private statusConnection = false; + private instanceName: string; + private redisEnv: Redis; + + public set reference(reference: string) { + this.logger.verbose('set reference: ' + reference); + this.instanceName = reference; } - this.logger.verbose('keyExists: ' + this.instanceName); - return !!(await this.instanceKeys()).find((i) => i === this.instanceName); - } - public async writeData(field: string, data: any) { - try { - this.logger.verbose('writeData: ' + field); - const json = JSON.stringify(data, BufferJSON.replacer); - - return await this.client.hSet( - this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - field, - json, - ); - } catch (error) { - this.logger.error(error); + public async connect(redisEnv: Redis) { + this.logger.verbose('connecting'); + this.client = createClient({ url: redisEnv.URI }); + this.logger.verbose('connected in ' + redisEnv.URI); + await this.client.connect(); + this.statusConnection = true; + this.redisEnv = redisEnv; } - } - public async readData(field: string) { - try { - this.logger.verbose('readData: ' + field); - const data = await this.client.hGet( - this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - field, - ); + private readonly logger = new Logger(RedisCache.name); + private client: RedisClientType; - if (data) { - this.logger.verbose('readData: ' + field + ' success'); - return JSON.parse(data, BufferJSON.reviver); - } - - this.logger.verbose('readData: ' + field + ' not found'); - return null; - } catch (error) { - this.logger.error(error); + public async instanceKeys(): Promise { + try { + this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*'); + return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']); + } catch (error) { + this.logger.error(error); + } } - } - public async removeData(field: string) { - try { - this.logger.verbose('removeData: ' + field); - return await this.client.hDel( - this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - field, - ); - } catch (error) { - this.logger.error(error); + public async keyExists(key?: string) { + if (key) { + this.logger.verbose('keyExists: ' + key); + return !!(await this.instanceKeys()).find((i) => i === key); + } + this.logger.verbose('keyExists: ' + this.instanceName); + return !!(await this.instanceKeys()).find((i) => i === this.instanceName); } - } - public async delAll(hash?: string) { - try { - this.logger.verbose('instance delAll: ' + hash); - const result = await this.client.del( - hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - ); + public async writeData(field: string, data: any) { + try { + this.logger.verbose('writeData: ' + field); + const json = JSON.stringify(data, BufferJSON.replacer); - return result; - } catch (error) { - this.logger.error(error); + return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json); + } catch (error) { + this.logger.error(error); + } + } + + public async readData(field: string) { + try { + this.logger.verbose('readData: ' + field); + const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); + + if (data) { + this.logger.verbose('readData: ' + field + ' success'); + return JSON.parse(data, BufferJSON.reviver); + } + + this.logger.verbose('readData: ' + field + ' not found'); + return null; + } catch (error) { + this.logger.error(error); + } + } + + public async removeData(field: string) { + try { + this.logger.verbose('removeData: ' + field); + return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); + } catch (error) { + this.logger.error(error); + } + } + + public async delAll(hash?: string) { + try { + this.logger.verbose('instance delAll: ' + hash); + const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName); + + return result; + } catch (error) { + this.logger.error(error); + } } - } } diff --git a/src/exceptions/400.exception.ts b/src/exceptions/400.exception.ts index 833295c1..8b5c9c16 100644 --- a/src/exceptions/400.exception.ts +++ b/src/exceptions/400.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class BadRequestException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.BAD_REQUEST, - error: 'Bad Request', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.BAD_REQUEST, + error: 'Bad Request', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/401.exception.ts b/src/exceptions/401.exception.ts index 72734d4e..97724396 100644 --- a/src/exceptions/401.exception.ts +++ b/src/exceptions/401.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class UnauthorizedException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.UNAUTHORIZED, - error: 'Unauthorized', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.UNAUTHORIZED, + error: 'Unauthorized', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/403.exception.ts b/src/exceptions/403.exception.ts index f53ca9a5..9670fe25 100644 --- a/src/exceptions/403.exception.ts +++ b/src/exceptions/403.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class ForbiddenException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.FORBIDDEN, - error: 'Forbidden', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.FORBIDDEN, + error: 'Forbidden', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/404.exception.ts b/src/exceptions/404.exception.ts index 1119d1a1..44181fe5 100644 --- a/src/exceptions/404.exception.ts +++ b/src/exceptions/404.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class NotFoundException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.NOT_FOUND, - error: 'Not Found', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.NOT_FOUND, + error: 'Not Found', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/500.exception.ts b/src/exceptions/500.exception.ts index 2a41dfa5..88d70573 100644 --- a/src/exceptions/500.exception.ts +++ b/src/exceptions/500.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class InternalServerErrorException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.INTERNAL_SERVER_ERROR, - error: 'Internal Server Error', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.INTERNAL_SERVER_ERROR, + error: 'Internal Server Error', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/main.ts b/src/main.ts index 7184f921..5d70661e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,96 +15,94 @@ import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { - waMonitor.loadInstance(); + waMonitor.loadInstance(); } function bootstrap() { - const logger = new Logger('SERVER'); - const app = express(); + const logger = new Logger('SERVER'); + const app = express(); - // Sentry.init({ - // dsn: '', - // integrations: [ - // // enable HTTP calls tracing - // new Sentry.Integrations.Http({ tracing: true }), - // // enable Express.js middleware tracing - // new Sentry.Integrations.Express({ app }), - // // Automatically instrument Node.js libraries and frameworks - // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), - // ], + // Sentry.init({ + // dsn: '', + // integrations: [ + // // enable HTTP calls tracing + // new Sentry.Integrations.Http({ tracing: true }), + // // enable Express.js middleware tracing + // new Sentry.Integrations.Express({ app }), + // // Automatically instrument Node.js libraries and frameworks + // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), + // ], - // // Set tracesSampleRate to 1.0 to capture 100% - // // of transactions for performance monitoring. - // // We recommend adjusting this value in production - // tracesSampleRate: 1.0, - // }); + // // Set tracesSampleRate to 1.0 to capture 100% + // // of transactions for performance monitoring. + // // We recommend adjusting this value in production + // tracesSampleRate: 1.0, + // }); - // app.use(Sentry.Handlers.requestHandler()); + // app.use(Sentry.Handlers.requestHandler()); - // app.use(Sentry.Handlers.tracingHandler()); + // app.use(Sentry.Handlers.tracingHandler()); - app.use( - cors({ - origin(requestOrigin, callback) { - const { ORIGIN } = configService.get('CORS'); - !requestOrigin ? (requestOrigin = '*') : undefined; - if (ORIGIN.indexOf(requestOrigin) !== -1) { - return callback(null, true); - } - return callback(new Error('Not allowed by CORS')); - }, - methods: [...configService.get('CORS').METHODS], - credentials: configService.get('CORS').CREDENTIALS, - }), - urlencoded({ extended: true, limit: '136mb' }), - json({ limit: '136mb' }), - compression(), - ); + app.use( + cors({ + origin(requestOrigin, callback) { + const { ORIGIN } = configService.get('CORS'); + !requestOrigin ? (requestOrigin = '*') : undefined; + if (ORIGIN.indexOf(requestOrigin) !== -1) { + return callback(null, true); + } + return callback(new Error('Not allowed by CORS')); + }, + methods: [...configService.get('CORS').METHODS], + credentials: configService.get('CORS').CREDENTIALS, + }), + urlencoded({ extended: true, limit: '136mb' }), + json({ limit: '136mb' }), + compression(), + ); - app.set('view engine', 'hbs'); - app.set('views', join(ROOT_DIR, 'views')); - app.use(express.static(join(ROOT_DIR, 'public'))); + app.set('view engine', 'hbs'); + app.set('views', join(ROOT_DIR, 'views')); + app.use(express.static(join(ROOT_DIR, 'public'))); - app.use('/', router); + app.use('/', router); - // app.use(Sentry.Handlers.errorHandler()); + // app.use(Sentry.Handlers.errorHandler()); - // app.use(function onError(err, req, res, next) { - // res.statusCode = 500; - // res.end(res.sentry + '\n'); - // }); + // app.use(function onError(err, req, res, next) { + // res.statusCode = 500; + // res.end(res.sentry + '\n'); + // }); - app.use( - (err: Error, req: Request, res: Response, next: NextFunction) => { - if (err) { - return res.status(err['status'] || 500).json(err); - } - }, - (req: Request, res: Response, next: NextFunction) => { - const { method, url } = req; + app.use( + (err: Error, req: Request, res: Response) => { + if (err) { + return res.status(err['status'] || 500).json(err); + } + }, + (req: Request, res: Response, next: NextFunction) => { + const { method, url } = req; - res.status(HttpStatus.NOT_FOUND).json({ - status: HttpStatus.NOT_FOUND, - message: `Cannot ${method.toUpperCase()} ${url}`, - error: 'Not Found', - }); + res.status(HttpStatus.NOT_FOUND).json({ + status: HttpStatus.NOT_FOUND, + message: `Cannot ${method.toUpperCase()} ${url}`, + error: 'Not Found', + }); - next(); - }, - ); + next(); + }, + ); - const httpServer = configService.get('SERVER'); + const httpServer = configService.get('SERVER'); - ServerUP.app = app; - const server = ServerUP[httpServer.TYPE]; + ServerUP.app = app; + const server = ServerUP[httpServer.TYPE]; - server.listen(httpServer.PORT, () => - logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT), - ); + server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); - initWA(); + initWA(); - onUnexpectedError(); + onUnexpectedError(); } bootstrap(); diff --git a/src/utils/server-up.ts b/src/utils/server-up.ts index e06caea7..a6205249 100644 --- a/src/utils/server-up.ts +++ b/src/utils/server-up.ts @@ -6,24 +6,24 @@ import * as https from 'https'; import { configService, SslConf } from '../config/env.config'; export class ServerUP { - static #app: Express; + static #app: Express; - static set app(e: Express) { - this.#app = e; - } + static set app(e: Express) { + this.#app = e; + } - static get https() { - const { FULLCHAIN, PRIVKEY } = configService.get('SSL_CONF'); - return https.createServer( - { - cert: readFileSync(FULLCHAIN), - key: readFileSync(PRIVKEY), - }, - ServerUP.#app, - ); - } + static get https() { + const { FULLCHAIN, PRIVKEY } = configService.get('SSL_CONF'); + return https.createServer( + { + cert: readFileSync(FULLCHAIN), + key: readFileSync(PRIVKEY), + }, + ServerUP.#app, + ); + } - static get http() { - return http.createServer(ServerUP.#app); - } + static get http() { + return http.createServer(ServerUP.#app); + } } diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index e26b7a7e..a372fbcf 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -1,10 +1,10 @@ import { - AuthenticationCreds, - AuthenticationState, - BufferJSON, - initAuthCreds, - proto, - SignalDataTypeMap, + AuthenticationCreds, + AuthenticationState, + BufferJSON, + initAuthCreds, + proto, + SignalDataTypeMap, } from '@whiskeysockets/baileys'; import { configService, Database } from '../config/env.config'; @@ -12,88 +12,86 @@ import { Logger } from '../config/logger.config'; import { dbserver } from '../db/db.connect'; export async function useMultiFileAuthStateDb( - coll: string, + coll: string, ): Promise<{ state: AuthenticationState; saveCreds: () => Promise }> { - const logger = new Logger(useMultiFileAuthStateDb.name); + const logger = new Logger(useMultiFileAuthStateDb.name); - const client = dbserver.getClient(); + const client = dbserver.getClient(); - const collection = client - .db(configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(coll); + const collection = client + .db(configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(coll); - const writeData = async (data: any, key: string): Promise => { - try { - await client.connect(); - return await collection.replaceOne( - { _id: key }, - JSON.parse(JSON.stringify(data, BufferJSON.replacer)), - { upsert: true }, - ); - } catch (error) { - logger.error(error); - } - }; + const writeData = async (data: any, key: string): Promise => { + try { + await client.connect(); + return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), { + upsert: true, + }); + } catch (error) { + logger.error(error); + } + }; - const readData = async (key: string): Promise => { - try { - await client.connect(); - const data = await collection.findOne({ _id: key }); - const creds = JSON.stringify(data); - return JSON.parse(creds, BufferJSON.reviver); - } catch (error) { - logger.error(error); - } - }; + const readData = async (key: string): Promise => { + try { + await client.connect(); + const data = await collection.findOne({ _id: key }); + const creds = JSON.stringify(data); + return JSON.parse(creds, BufferJSON.reviver); + } catch (error) { + logger.error(error); + } + }; - const removeData = async (key: string) => { - try { - await client.connect(); - return await collection.deleteOne({ _id: key }); - } catch (error) { - logger.error(error); - } - }; + const removeData = async (key: string) => { + try { + await client.connect(); + return await collection.deleteOne({ _id: key }); + } catch (error) { + logger.error(error); + } + }; - const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); + const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); - return { - state: { - creds, - keys: { - get: async (type, ids: string[]) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const data: { [_: string]: SignalDataTypeMap[type] } = {}; - await Promise.all( - ids.map(async (id) => { - let value = await readData(`${type}-${id}`); - if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.fromObject(value); - } + return { + state: { + creds, + keys: { + get: async (type, ids: string[]) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const data: { [_: string]: SignalDataTypeMap[type] } = {}; + await Promise.all( + ids.map(async (id) => { + let value = await readData(`${type}-${id}`); + if (type === 'app-state-sync-key' && value) { + value = proto.Message.AppStateSyncKeyData.fromObject(value); + } - data[id] = value; - }), - ); + data[id] = value; + }), + ); - return data; + return data; + }, + set: async (data: any) => { + const tasks: Promise[] = []; + for (const category in data) { + for (const id in data[category]) { + const value = data[category][id]; + const key = `${category}-${id}`; + tasks.push(value ? writeData(value, key) : removeData(key)); + } + } + + await Promise.all(tasks); + }, + }, }, - set: async (data: any) => { - const tasks: Promise[] = []; - for (const category in data) { - for (const id in data[category]) { - const value = data[category][id]; - const key = `${category}-${id}`; - tasks.push(value ? writeData(value, key) : removeData(key)); - } - } - - await Promise.all(tasks); + saveCreds: async () => { + return writeData(creds, 'creds'); }, - }, - }, - saveCreds: async () => { - return writeData(creds, 'creds'); - }, - }; + }; } diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index 392d99ca..f26d7d02 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -1,85 +1,84 @@ import { - AuthenticationCreds, - AuthenticationState, - initAuthCreds, - proto, - SignalDataTypeMap, + AuthenticationCreds, + AuthenticationState, + initAuthCreds, + proto, + SignalDataTypeMap, } from '@whiskeysockets/baileys'; -import { Redis } from '../config/env.config'; import { Logger } from '../config/logger.config'; import { RedisCache } from '../db/redis.client'; export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{ - state: AuthenticationState; - saveCreds: () => Promise; + state: AuthenticationState; + saveCreds: () => Promise; }> { - const logger = new Logger(useMultiFileAuthStateRedisDb.name); + const logger = new Logger(useMultiFileAuthStateRedisDb.name); - const writeData = async (data: any, key: string): Promise => { - try { - return await cache.writeData(key, data); - } catch (error) { - return logger.error({ localError: 'writeData', error }); - } - }; + const writeData = async (data: any, key: string): Promise => { + try { + return await cache.writeData(key, data); + } catch (error) { + return logger.error({ localError: 'writeData', error }); + } + }; - const readData = async (key: string): Promise => { - try { - return await cache.readData(key); - } catch (error) { - logger.error({ readData: 'writeData', error }); - return; - } - }; + const readData = async (key: string): Promise => { + try { + return await cache.readData(key); + } catch (error) { + logger.error({ readData: 'writeData', error }); + return; + } + }; - const removeData = async (key: string) => { - try { - return await cache.removeData(key); - } catch (error) { - logger.error({ readData: 'removeData', error }); - } - }; + const removeData = async (key: string) => { + try { + return await cache.removeData(key); + } catch (error) { + logger.error({ readData: 'removeData', error }); + } + }; - const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); + const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); - return { - state: { - creds, - keys: { - get: async (type, ids: string[]) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const data: { [_: string]: SignalDataTypeMap[type] } = {}; - await Promise.all( - ids.map(async (id) => { - let value = await readData(`${type}-${id}`); - if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.fromObject(value); - } + return { + state: { + creds, + keys: { + get: async (type, ids: string[]) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const data: { [_: string]: SignalDataTypeMap[type] } = {}; + await Promise.all( + ids.map(async (id) => { + let value = await readData(`${type}-${id}`); + if (type === 'app-state-sync-key' && value) { + value = proto.Message.AppStateSyncKeyData.fromObject(value); + } - data[id] = value; - }), - ); + data[id] = value; + }), + ); - return data; + return data; + }, + set: async (data: any) => { + const tasks: Promise[] = []; + for (const category in data) { + for (const id in data[category]) { + const value = data[category][id]; + const key = `${category}-${id}`; + tasks.push(value ? await writeData(value, key) : await removeData(key)); + } + } + + await Promise.all(tasks); + }, + }, }, - set: async (data: any) => { - const tasks: Promise[] = []; - for (const category in data) { - for (const id in data[category]) { - const value = data[category][id]; - const key = `${category}-${id}`; - tasks.push(value ? await writeData(value, key) : await removeData(key)); - } - } - - await Promise.all(tasks); + saveCreds: async () => { + return await writeData(creds, 'creds'); }, - }, - }, - saveCreds: async () => { - return await writeData(creds, 'creds'); - }, - }; + }; } diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index aea723ca..c83d6a61 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -2,888 +2,888 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; import { v4 } from 'uuid'; const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => { - const properties = {}; - propertyNames.forEach( - (property) => - (properties[property] = { - minLength: 1, - description: `The "${property}" cannot be empty`, - }), - ); - return { - if: { - propertyNames: { - enum: [...propertyNames], - }, - }, - then: { properties }, - }; + const properties = {}; + propertyNames.forEach( + (property) => + (properties[property] = { + minLength: 1, + description: `The "${property}" cannot be empty`, + }), + ); + return { + if: { + propertyNames: { + enum: [...propertyNames], + }, + }, + then: { properties }, + }; }; // Instance Schema export const instanceNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - instanceName: { type: 'string' }, - webhook: { type: 'string' }, - webhook_by_events: { type: 'boolean' }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'NEW_JWT_TOKEN', - ], - }, + $id: v4(), + type: 'object', + properties: { + instanceName: { type: 'string' }, + webhook: { type: 'string' }, + webhook_by_events: { type: 'boolean' }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'NEW_JWT_TOKEN', + ], + }, + }, + qrcode: { type: 'boolean', enum: [true, false] }, + number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, + token: { type: 'string' }, }, - qrcode: { type: 'boolean', enum: [true, false] }, - number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, - token: { type: 'string' }, - }, - ...isNotEmpty('instanceName'), + ...isNotEmpty('instanceName'), }; export const oldTokenSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - oldToken: { type: 'string' }, - }, - required: ['oldToken'], - ...isNotEmpty('oldToken'), + $id: v4(), + type: 'object', + properties: { + oldToken: { type: 'string' }, + }, + required: ['oldToken'], + ...isNotEmpty('oldToken'), }; const quotedOptionsSchema: JSONSchema7 = { - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id'], - ...isNotEmpty('id'), + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id'], + ...isNotEmpty('id'), + }, + message: { type: 'object' }, }, - message: { type: 'object' }, - }, }; const mentionsOptionsSchema: JSONSchema7 = { - properties: { - everyOne: { type: 'boolean', enum: [true, false] }, - mentioned: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"mentioned" must be an array of numeric strings', - }, + properties: { + everyOne: { type: 'boolean', enum: [true, false] }, + mentioned: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"mentioned" must be an array of numeric strings', + }, + }, }, - }, }; // Send Message Schema const optionsSchema: JSONSchema7 = { - properties: { - delay: { - type: 'integer', - description: 'Enter a value in milliseconds', + properties: { + delay: { + type: 'integer', + description: 'Enter a value in milliseconds', + }, + presence: { + type: 'string', + enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], + }, + quoted: { ...quotedOptionsSchema }, + mentions: { ...mentionsOptionsSchema }, }, - presence: { - type: 'string', - enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], - }, - quoted: { ...quotedOptionsSchema }, - mentions: { ...mentionsOptionsSchema }, - }, }; const numberDefinition: JSONSchema7Definition = { - type: 'string', - description: 'Invalid format', + type: 'string', + description: 'Invalid format', }; export const textMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - textMessage: { - type: 'object', - properties: { - text: { type: 'string' }, - }, - required: ['text'], - ...isNotEmpty('text'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + textMessage: { + type: 'object', + properties: { + text: { type: 'string' }, + }, + required: ['text'], + ...isNotEmpty('text'), + }, }, - }, - required: ['textMessage', 'number'], + required: ['textMessage', 'number'], }; export const pollMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - pollMessage: { - type: 'object', - properties: { - name: { type: 'string' }, - selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, - values: { - type: 'array', - minItems: 2, - maxItems: 10, - uniqueItems: true, - items: { - type: 'string', - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + pollMessage: { + type: 'object', + properties: { + name: { type: 'string' }, + selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, + values: { + type: 'array', + minItems: 2, + maxItems: 10, + uniqueItems: true, + items: { + type: 'string', + }, + }, + }, + required: ['name', 'selectableCount', 'values'], + ...isNotEmpty('name', 'selectableCount', 'values'), }, - }, - required: ['name', 'selectableCount', 'values'], - ...isNotEmpty('name', 'selectableCount', 'values'), }, - }, - required: ['pollMessage', 'number'], + required: ['pollMessage', 'number'], }; export const statusMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - statusMessage: { - type: 'object', - properties: { - type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, - content: { type: 'string' }, - caption: { type: 'string' }, - backgroundColor: { type: 'string' }, - font: { type: 'integer', minimum: 0, maximum: 5 }, - statusJidList: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"statusJidList" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + statusMessage: { + type: 'object', + properties: { + type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, + content: { type: 'string' }, + caption: { type: 'string' }, + backgroundColor: { type: 'string' }, + font: { type: 'integer', minimum: 0, maximum: 5 }, + statusJidList: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"statusJidList" must be an array of numeric strings', + }, + }, + allContacts: { type: 'boolean', enum: [true, false] }, + }, + required: ['type', 'content'], + ...isNotEmpty('type', 'content'), }, - allContacts: { type: 'boolean', enum: [true, false] }, - }, - required: ['type', 'content'], - ...isNotEmpty('type', 'content'), }, - }, - required: ['statusMessage'], + required: ['statusMessage'], }; export const mediaMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - mediaMessage: { - type: 'object', - properties: { - mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, - media: { type: 'string' }, - fileName: { type: 'string' }, - caption: { type: 'string' }, - }, - required: ['mediatype', 'media'], - ...isNotEmpty('fileName', 'caption', 'media'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + mediaMessage: { + type: 'object', + properties: { + mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, + media: { type: 'string' }, + fileName: { type: 'string' }, + caption: { type: 'string' }, + }, + required: ['mediatype', 'media'], + ...isNotEmpty('fileName', 'caption', 'media'), + }, }, - }, - required: ['mediaMessage', 'number'], + required: ['mediaMessage', 'number'], }; export const stickerMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - stickerMessage: { - type: 'object', - properties: { - image: { type: 'string' }, - }, - required: ['image'], - ...isNotEmpty('image'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + stickerMessage: { + type: 'object', + properties: { + image: { type: 'string' }, + }, + required: ['image'], + ...isNotEmpty('image'), + }, }, - }, - required: ['stickerMessage', 'number'], + required: ['stickerMessage', 'number'], }; export const audioMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - audioMessage: { - type: 'object', - properties: { - audio: { type: 'string' }, - }, - required: ['audio'], - ...isNotEmpty('audio'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + audioMessage: { + type: 'object', + properties: { + audio: { type: 'string' }, + }, + required: ['audio'], + ...isNotEmpty('audio'), + }, }, - }, - required: ['audioMessage', 'number'], + required: ['audioMessage', 'number'], }; export const buttonMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - buttonMessage: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttons: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + buttonMessage: { type: 'object', properties: { - buttonText: { type: 'string' }, - buttonId: { type: 'string' }, + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttons: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + buttonText: { type: 'string' }, + buttonId: { type: 'string' }, + }, + required: ['buttonText', 'buttonId'], + ...isNotEmpty('buttonText', 'buttonId'), + }, + }, + mediaMessage: { + type: 'object', + properties: { + media: { type: 'string' }, + fileName: { type: 'string' }, + mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, + }, + required: ['media', 'mediatype'], + ...isNotEmpty('media', 'fileName'), + }, }, - required: ['buttonText', 'buttonId'], - ...isNotEmpty('buttonText', 'buttonId'), - }, + required: ['title', 'buttons'], + ...isNotEmpty('title', 'description'), }, - mediaMessage: { - type: 'object', - properties: { - media: { type: 'string' }, - fileName: { type: 'string' }, - mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, - }, - required: ['media', 'mediatype'], - ...isNotEmpty('media', 'fileName'), - }, - }, - required: ['title', 'buttons'], - ...isNotEmpty('title', 'description'), }, - }, - required: ['number', 'buttonMessage'], + required: ['number', 'buttonMessage'], }; export const locationMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - locationMessage: { - type: 'object', - properties: { - latitude: { type: 'number' }, - longitude: { type: 'number' }, - name: { type: 'string' }, - address: { type: 'string' }, - }, - required: ['latitude', 'longitude'], - ...isNotEmpty('name', 'addresss'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + locationMessage: { + type: 'object', + properties: { + latitude: { type: 'number' }, + longitude: { type: 'number' }, + name: { type: 'string' }, + address: { type: 'string' }, + }, + required: ['latitude', 'longitude'], + ...isNotEmpty('name', 'addresss'), + }, }, - }, - required: ['number', 'locationMessage'], + required: ['number', 'locationMessage'], }; export const listMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - listMessage: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttonText: { type: 'string' }, - sections: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + listMessage: { type: 'object', properties: { - title: { type: 'string' }, - rows: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - rowId: { type: 'string' }, - }, - required: ['title', 'description', 'rowId'], - ...isNotEmpty('title', 'description', 'rowId'), + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttonText: { type: 'string' }, + sections: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + rows: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + rowId: { type: 'string' }, + }, + required: ['title', 'description', 'rowId'], + ...isNotEmpty('title', 'description', 'rowId'), + }, + }, + }, + required: ['title', 'rows'], + ...isNotEmpty('title'), + }, }, - }, }, - required: ['title', 'rows'], - ...isNotEmpty('title'), - }, + required: ['title', 'description', 'buttonText', 'sections'], + ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - }, - required: ['title', 'description', 'buttonText', 'sections'], - ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - }, - required: ['number', 'listMessage'], + required: ['number', 'listMessage'], }; export const contactMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - contactMessage: { - type: 'array', - items: { - type: 'object', - properties: { - fullName: { type: 'string' }, - wuid: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"wuid" must be a numeric string', - }, - phoneNumber: { type: 'string', minLength: 10 }, - organization: { type: 'string' }, - email: { type: 'string' }, - url: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + contactMessage: { + type: 'array', + items: { + type: 'object', + properties: { + fullName: { type: 'string' }, + wuid: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"wuid" must be a numeric string', + }, + phoneNumber: { type: 'string', minLength: 10 }, + organization: { type: 'string' }, + email: { type: 'string' }, + url: { type: 'string' }, + }, + required: ['fullName', 'phoneNumber'], + ...isNotEmpty('fullName'), + }, + minItems: 1, + uniqueItems: true, }, - required: ['fullName', 'phoneNumber'], - ...isNotEmpty('fullName'), - }, - minItems: 1, - uniqueItems: true, }, - }, - required: ['number', 'contactMessage'], + required: ['number', 'contactMessage'], }; export const reactionMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reactionMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'remoteJid', 'fromMe'], - ...isNotEmpty('id', 'remoteJid'), + $id: v4(), + type: 'object', + properties: { + reactionMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'remoteJid', 'fromMe'], + ...isNotEmpty('id', 'remoteJid'), + }, + reaction: { type: 'string' }, + }, + required: ['key', 'reaction'], + ...isNotEmpty('reaction'), }, - reaction: { type: 'string' }, - }, - required: ['key', 'reaction'], - ...isNotEmpty('reaction'), }, - }, - required: ['reactionMessage'], + required: ['reactionMessage'], }; // Chat Schema export const whatsappNumberSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - description: '"numbers" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + description: '"numbers" must be an array of numeric strings', + }, + }, }, - }, }; export const readMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - readMessages: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + readMessages: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, }, - }, - required: ['readMessages'], + required: ['readMessages'], }; export const privacySettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - privacySettings: { - type: 'object', - properties: { - readreceipts: { type: 'string', enum: ['all', 'none'] }, - profile: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], + $id: v4(), + type: 'object', + properties: { + privacySettings: { + type: 'object', + properties: { + readreceipts: { type: 'string', enum: ['all', 'none'] }, + profile: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + status: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + online: { type: 'string', enum: ['all', 'match_last_seen'] }, + last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, + groupadd: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + }, + required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], + ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - status: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - online: { type: 'string', enum: ['all', 'match_last_seen'] }, - last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, - groupadd: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - }, - required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], - ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - }, - required: ['privacySettings'], + required: ['privacySettings'], }; export const archiveChatSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - lastMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), + $id: v4(), + type: 'object', + properties: { + lastMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, + messageTimestamp: { type: 'integer', minLength: 1 }, + }, + required: ['key'], + ...isNotEmpty('messageTimestamp'), }, - messageTimestamp: { type: 'integer', minLength: 1 }, - }, - required: ['key'], - ...isNotEmpty('messageTimestamp'), + archive: { type: 'boolean', enum: [true, false] }, }, - archive: { type: 'boolean', enum: [true, false] }, - }, - required: ['lastMessage', 'archive'], + required: ['lastMessage', 'archive'], }; export const deleteMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - participant: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid', 'participant'), + $id: v4(), + type: 'object', + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + participant: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid', 'participant'), }; export const contactValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - pushName: { type: 'string', minLength: 1 }, - id: { type: 'string', minLength: 1 }, - }, - ...isNotEmpty('_id', 'id', 'pushName'), + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + pushName: { type: 'string', minLength: 1 }, + id: { type: 'string', minLength: 1 }, + }, + ...isNotEmpty('_id', 'id', 'pushName'), + }, }, - }, }; export const profileNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - name: { type: 'string' }, - }, - ...isNotEmpty('name'), + $id: v4(), + type: 'object', + properties: { + name: { type: 'string' }, + }, + ...isNotEmpty('name'), }; export const profileStatusSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - status: { type: 'string' }, - }, - ...isNotEmpty('status'), + $id: v4(), + type: 'object', + properties: { + status: { type: 'string' }, + }, + ...isNotEmpty('status'), }; export const profilePictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { type: 'string' }, - picture: { type: 'string' }, - }, + $id: v4(), + type: 'object', + properties: { + number: { type: 'string' }, + picture: { type: 'string' }, + }, }; export const profileSchema: JSONSchema7 = { - type: 'object', - properties: { - wuid: { type: 'string' }, - name: { type: 'string' }, - picture: { type: 'string' }, - status: { type: 'string' }, - isBusiness: { type: 'boolean' }, - }, + type: 'object', + properties: { + wuid: { type: 'string' }, + name: { type: 'string' }, + picture: { type: 'string' }, + status: { type: 'string' }, + isBusiness: { type: 'boolean' }, + }, }; export const messageValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - key: { - type: 'object', - if: { - propertyNames: { - enum: ['fromMe', 'remoteJid', 'id'], - }, - }, - then: { + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', properties: { - remoteJid: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - id: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - fromMe: { type: 'boolean', enum: [true, false] }, + _id: { type: 'string', minLength: 1 }, + key: { + type: 'object', + if: { + propertyNames: { + enum: ['fromMe', 'remoteJid', 'id'], + }, + }, + then: { + properties: { + remoteJid: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + id: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + }, + }, + message: { type: 'object' }, }, - }, + ...isNotEmpty('_id'), }, - message: { type: 'object' }, - }, - ...isNotEmpty('_id'), + limit: { type: 'integer' }, }, - limit: { type: 'integer' }, - }, }; export const messageUpSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string' }, - remoteJid: { type: 'string' }, - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - participant: { type: 'string' }, - status: { - type: 'string', - enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string' }, + remoteJid: { type: 'string' }, + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + participant: { type: 'string' }, + status: { + type: 'string', + enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], + }, + }, + ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), }, - }, - ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), + limit: { type: 'integer' }, }, - limit: { type: 'integer' }, - }, }; // Group Schema export const createGroupSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - subject: { type: 'string' }, - description: { type: 'string' }, - profilePicture: { type: 'string' }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + subject: { type: 'string' }, + description: { type: 'string' }, + profilePicture: { type: 'string' }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, }, - }, - required: ['subject', 'participants'], - ...isNotEmpty('subject', 'description', 'profilePicture'), + required: ['subject', 'participants'], + ...isNotEmpty('subject', 'description', 'profilePicture'), }; export const groupJidSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, - }, - required: ['groupJid'], - ...isNotEmpty('groupJid'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, + }, + required: ['groupJid'], + ...isNotEmpty('groupJid'), }; export const getParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - getParticipants: { type: 'string', enum: ['true', 'false'] }, - }, - required: ['getParticipants'], - ...isNotEmpty('getParticipants'), + $id: v4(), + type: 'object', + properties: { + getParticipants: { type: 'string', enum: ['true', 'false'] }, + }, + required: ['getParticipants'], + ...isNotEmpty('getParticipants'), }; export const groupSendInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"numbers" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"numbers" must be an array of numeric strings', + }, + }, }, - }, - required: ['groupJid', 'description', 'numbers'], - ...isNotEmpty('groupJid', 'description', 'numbers'), + required: ['groupJid', 'description', 'numbers'], + ...isNotEmpty('groupJid', 'description', 'numbers'), }; export const groupInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, - }, - required: ['inviteCode'], - ...isNotEmpty('inviteCode'), + $id: v4(), + type: 'object', + properties: { + inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, + }, + required: ['inviteCode'], + ...isNotEmpty('inviteCode'), }; export const updateParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['add', 'remove', 'promote', 'demote'], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['add', 'remove', 'promote', 'demote'], + }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, - }, - required: ['groupJid', 'action', 'participants'], - ...isNotEmpty('groupJid', 'action'), + required: ['groupJid', 'action', 'participants'], + ...isNotEmpty('groupJid', 'action'), }; export const updateSettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], + }, }, - }, - required: ['groupJid', 'action'], - ...isNotEmpty('groupJid', 'action'), + required: ['groupJid', 'action'], + ...isNotEmpty('groupJid', 'action'), }; export const toggleEphemeralSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - expiration: { - type: 'number', - enum: [0, 86400, 604800, 7776000], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + expiration: { + type: 'number', + enum: [0, 86400, 604800, 7776000], + }, }, - }, - required: ['groupJid', 'expiration'], - ...isNotEmpty('groupJid', 'expiration'), + required: ['groupJid', 'expiration'], + ...isNotEmpty('groupJid', 'expiration'), }; export const updateGroupPictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - image: { type: 'string' }, - }, - required: ['groupJid', 'image'], - ...isNotEmpty('groupJid', 'image'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + image: { type: 'string' }, + }, + required: ['groupJid', 'image'], + ...isNotEmpty('groupJid', 'image'), }; export const updateGroupSubjectSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - subject: { type: 'string' }, - }, - required: ['groupJid', 'subject'], - ...isNotEmpty('groupJid', 'subject'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + subject: { type: 'string' }, + }, + required: ['groupJid', 'subject'], + ...isNotEmpty('groupJid', 'subject'), }; export const updateGroupDescriptionSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - }, - required: ['groupJid', 'description'], - ...isNotEmpty('groupJid', 'description'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + }, + required: ['groupJid', 'description'], + ...isNotEmpty('groupJid', 'description'), }; // Webhook Schema export const webhookSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - url: { type: 'string' }, - enabled: { type: 'boolean', enum: [true, false] }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'NEW_JWT_TOKEN', - ], - }, + $id: v4(), + type: 'object', + properties: { + url: { type: 'string' }, + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'NEW_JWT_TOKEN', + ], + }, + }, }, - }, - required: ['url', 'enabled'], - ...isNotEmpty('url'), + required: ['url', 'enabled'], + ...isNotEmpty('url'), }; export const chatwootSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - enabled: { type: 'boolean', enum: [true, false] }, - account_id: { type: 'string' }, - token: { type: 'string' }, - url: { type: 'string' }, - sign_msg: { type: 'boolean', enum: [true, false] }, - }, - required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], - ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + account_id: { type: 'string' }, + token: { type: 'string' }, + url: { type: 'string' }, + sign_msg: { type: 'boolean', enum: [true, false] }, + }, + required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], + ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), }; export const settingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reject_call: { type: 'boolean', enum: [true, false] }, - msg_call: { type: 'string' }, - groups_ignore: { type: 'boolean', enum: [true, false] }, - }, - required: ['reject_call'], - ...isNotEmpty('reject_call'), + $id: v4(), + type: 'object', + properties: { + reject_call: { type: 'boolean', enum: [true, false] }, + msg_call: { type: 'string' }, + groups_ignore: { type: 'boolean', enum: [true, false] }, + }, + required: ['reject_call'], + ...isNotEmpty('reject_call'), }; diff --git a/src/whatsapp/abstract/abstract.repository.ts b/src/whatsapp/abstract/abstract.repository.ts index a0c4de6f..739489eb 100644 --- a/src/whatsapp/abstract/abstract.repository.ts +++ b/src/whatsapp/abstract/abstract.repository.ts @@ -7,59 +7,61 @@ import { ROOT_DIR } from '../../config/path.config'; export type IInsert = { insertCount: number }; export interface IRepository { - insert(data: any, instanceName: string, saveDb?: boolean): Promise; - update(data: any, instanceName: string, saveDb?: boolean): Promise; - find(query: any): Promise; - delete(query: any, force?: boolean): Promise; + insert(data: any, instanceName: string, saveDb?: boolean): Promise; + update(data: any, instanceName: string, saveDb?: boolean): Promise; + find(query: any): Promise; + delete(query: any, force?: boolean): Promise; - dbSettings: Database; - readonly storePath: string; + dbSettings: Database; + readonly storePath: string; } type WriteStore = { - path: string; - fileName: string; - data: U; + path: string; + fileName: string; + data: U; }; export abstract class Repository implements IRepository { - constructor(configService: ConfigService) { - this.dbSettings = configService.get('DATABASE'); - } - - dbSettings: Database; - readonly storePath = join(ROOT_DIR, 'store'); - - public writeStore = (create: WriteStore) => { - if (!existsSync(create.path)) { - mkdirSync(create.path, { recursive: true }); + constructor(configService: ConfigService) { + this.dbSettings = configService.get('DATABASE'); } - try { - writeFileSync( - join(create.path, create.fileName + '.json'), - JSON.stringify({ ...create.data }), - { encoding: 'utf-8' }, - ); - return { message: 'create - success' }; - } finally { - create.data = undefined; + dbSettings: Database; + readonly storePath = join(ROOT_DIR, 'store'); + + public writeStore = (create: WriteStore) => { + if (!existsSync(create.path)) { + mkdirSync(create.path, { recursive: true }); + } + try { + writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), { + encoding: 'utf-8', + }); + + return { message: 'create - success' }; + } finally { + create.data = undefined; + } + }; + + // eslint-disable-next-line + public insert(data: any, instanceName: string, saveDb = false): Promise { + throw new Error('Method not implemented.'); } - }; - public insert(data: any, instanceName: string, saveDb = false): Promise { - throw new Error('Method not implemented.'); - } + // eslint-disable-next-line + public update(data: any, instanceName: string, saveDb = false): Promise { + throw new Error('Method not implemented.'); + } - public update(data: any, instanceName: string, saveDb = false): Promise { - throw new Error('Method not implemented.'); - } + // eslint-disable-next-line + public find(query: any): Promise { + throw new Error('Method not implemented.'); + } - public find(query: any): Promise { - throw new Error('Method not implemented.'); - } - - delete(query: any, force?: boolean): Promise { - throw new Error('Method not implemented.'); - } + // eslint-disable-next-line + delete(query: any, force?: boolean): Promise { + throw new Error('Method not implemented.'); + } } diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index 7a9dc427..86f05d6a 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -10,216 +10,214 @@ import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; type DataValidate = { - request: Request; - schema: JSONSchema7; - ClassRef: any; - execute: (instance: InstanceDto, data: T) => Promise; + request: Request; + schema: JSONSchema7; + ClassRef: any; + execute: (instance: InstanceDto, data: T) => Promise; }; const logger = new Logger('Validate'); export abstract class RouterBroker { - constructor() {} - public routerPath(path: string, param = true) { - // const route = param ? '/:instanceName/' + path : '/' + path; - let route = '/' + path; - param ? (route += '/:instanceName') : null; + constructor() {} + public routerPath(path: string, param = true) { + // const route = param ? '/:instanceName/' + path : '/' + path; + let route = '/' + path; + param ? (route += '/:instanceName') : null; - return route; - } - - public async dataValidate(args: DataValidate) { - const { request, schema, ClassRef, execute } = args; - - const ref = new ClassRef(); - const body = request.body; - const instance = request.params as unknown as InstanceDto; - - if (request?.query && Object.keys(request.query).length > 0) { - Object.assign(instance, request.query); + return route; } - if (request.originalUrl.includes('/instance/create')) { - Object.assign(instance, body); - } + public async dataValidate(args: DataValidate) { + const { request, schema, ClassRef, execute } = args; - Object.assign(ref, body); + const ref = new ClassRef(); + const body = request.body; + const instance = request.params as unknown as InstanceDto; - const v = schema ? validate(ref, schema) : { valid: true, errors: [] }; - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); + if (request?.query && Object.keys(request.query).length > 0) { + Object.assign(instance, request.query); } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - return await execute(instance, ref); - } - - public async groupNoValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; - - const instance = request.params as unknown as InstanceDto; - - const ref = new ClassRef(); - - Object.assign(ref, request.body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); + if (request.originalUrl.includes('/instance/create')) { + Object.assign(instance, body); } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - return await execute(instance, ref); - } + Object.assign(ref, body); - public async groupValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + const v = schema ? validate(ref, schema) : { valid: true, errors: [] }; - const groupJid = request.query as unknown as GroupJid; - - if (!groupJid?.groupJid) { - throw new BadRequestException( - 'The group id needs to be informed in the query', - 'ex: "groupJid=120362@g.us"', - ); - } - - const instance = request.params as unknown as InstanceDto; - const body = request.body; - - const ref = new ClassRef(); - - Object.assign(body, groupJid); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); + + return await execute(instance, ref); } - return await execute(instance, ref); - } + public async groupNoValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; - public async inviteCodeValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + const instance = request.params as unknown as InstanceDto; - const inviteCode = request.query as unknown as GroupInvite; + const ref = new ClassRef(); - if (!inviteCode?.inviteCode) { - throw new BadRequestException( - 'The group invite code id needs to be informed in the query', - 'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)', - ); - } + Object.assign(ref, request.body); - const instance = request.params as unknown as InstanceDto; - const body = request.body; + const v = validate(ref, schema); - const ref = new ClassRef(); - - Object.assign(body, inviteCode); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); + + return await execute(instance, ref); } - return await execute(instance, ref); - } + public async groupValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; - public async getParticipantsValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + const groupJid = request.query as unknown as GroupJid; - const getParticipants = request.query as unknown as GetParticipant; - - if (!getParticipants?.getParticipants) { - throw new BadRequestException( - 'The getParticipants needs to be informed in the query', - ); - } - - const instance = request.params as unknown as InstanceDto; - const body = request.body; - - const ref = new ClassRef(); - - Object.assign(body, getParticipants); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); + if (!groupJid?.groupJid) { + throw new BadRequestException( + 'The group id needs to be informed in the query', + 'ex: "groupJid=120362@g.us"', + ); } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); + + const instance = request.params as unknown as InstanceDto; + const body = request.body; + + const ref = new ClassRef(); + + Object.assign(body, groupJid); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); + } + + return await execute(instance, ref); } - return await execute(instance, ref); - } + public async inviteCodeValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; + + const inviteCode = request.query as unknown as GroupInvite; + + if (!inviteCode?.inviteCode) { + throw new BadRequestException( + 'The group invite code id needs to be informed in the query', + 'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)', + ); + } + + const instance = request.params as unknown as InstanceDto; + const body = request.body; + + const ref = new ClassRef(); + + Object.assign(body, inviteCode); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); + } + + return await execute(instance, ref); + } + + public async getParticipantsValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; + + const getParticipants = request.query as unknown as GetParticipant; + + if (!getParticipants?.getParticipants) { + throw new BadRequestException('The getParticipants needs to be informed in the query'); + } + + const instance = request.params as unknown as InstanceDto; + const body = request.body; + + const ref = new ClassRef(); + + Object.assign(body, getParticipants); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); + } + + return await execute(instance, ref); + } } diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index 8217b908..c1eff50b 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -1,17 +1,15 @@ -import { proto } from '@whiskeysockets/baileys'; - import { Logger } from '../../config/logger.config'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberDto, - PrivacySettingDto, - ProfileNameDto, - ProfilePictureDto, - ProfileStatusDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberDto, + PrivacySettingDto, + ProfileNameDto, + ProfilePictureDto, + ProfileStatusDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; @@ -22,124 +20,95 @@ import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('ChatController'); export class ChatController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) { - logger.verbose('requested whatsappNumber from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].whatsappNumber(data); - } + public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) { + logger.verbose('requested whatsappNumber from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].whatsappNumber(data); + } - public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) { - logger.verbose('requested readMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data); - } + public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) { + logger.verbose('requested readMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data); + } - public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) { - logger.verbose('requested archiveChat from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].archiveChat(data); - } + public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) { + logger.verbose('requested archiveChat from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].archiveChat(data); + } - public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) { - logger.verbose('requested deleteMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].deleteMessage(data); - } + public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) { + logger.verbose('requested deleteMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].deleteMessage(data); + } - public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) { - logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); - } + public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) { + logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); + } - public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { - logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchProfile( - instanceName, - data.number, - ); - } + public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { + logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number); + } - public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { - logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchContacts(query); - } + public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { + logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchContacts(query); + } - public async getBase64FromMediaMessage( - { instanceName }: InstanceDto, - data: getBase64FromMediaMessageDto, - ) { - logger.verbose( - 'requested getBase64FromMediaMessage from ' + instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data); - } + public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) { + logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data); + } - public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) { - logger.verbose('requested fetchMessages from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchMessages(query); - } + public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) { + logger.verbose('requested fetchMessages from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchMessages(query); + } - public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) { - logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query); - } + public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) { + logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query); + } - public async fetchChats({ instanceName }: InstanceDto) { - logger.verbose('requested fetchChats from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchChats(); - } + public async fetchChats({ instanceName }: InstanceDto) { + logger.verbose('requested fetchChats from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchChats(); + } - public async fetchPrivacySettings({ instanceName }: InstanceDto) { - logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings(); - } + public async fetchPrivacySettings({ instanceName }: InstanceDto) { + logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings(); + } - public async updatePrivacySettings( - { instanceName }: InstanceDto, - data: PrivacySettingDto, - ) { - logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data); - } + public async updatePrivacySettings({ instanceName }: InstanceDto, data: PrivacySettingDto) { + logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data); + } - public async fetchBusinessProfile( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { - logger.verbose('requested fetchBusinessProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile( - data.number, - ); - } + public async fetchBusinessProfile({ instanceName }: InstanceDto, data: ProfilePictureDto) { + logger.verbose('requested fetchBusinessProfile from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile(data.number); + } - public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) { - logger.verbose('requested updateProfileName from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name); - } + public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) { + logger.verbose('requested updateProfileName from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name); + } - public async updateProfileStatus( - { instanceName }: InstanceDto, - data: ProfileStatusDto, - ) { - logger.verbose('requested updateProfileStatus from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfileStatus( - data.status, - ); - } + public async updateProfileStatus({ instanceName }: InstanceDto, data: ProfileStatusDto) { + logger.verbose('requested updateProfileStatus from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfileStatus(data.status); + } - public async updateProfilePicture( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { - logger.verbose('requested updateProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfilePicture( - data.picture, - ); - } + public async updateProfilePicture({ instanceName }: InstanceDto, data: ProfilePictureDto) { + logger.verbose('requested updateProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfilePicture(data.picture); + } - public async removeProfilePicture( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { - logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].removeProfilePicture(); - } + public async removeProfilePicture({ instanceName }: InstanceDto) { + logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].removeProfilePicture(); + } } diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index 892c6905..d4563485 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -11,94 +11,87 @@ import { waMonitor } from '../whatsapp.module'; const logger = new Logger('ChatwootController'); export class ChatwootController { - constructor( - private readonly chatwootService: ChatwootService, - private readonly configService: ConfigService, - ) {} + constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} - public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { - logger.verbose( - 'requested createChatwoot from ' + instance.instanceName + ' instance', - ); + public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { + logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); - if (data.enabled) { - if (!isURL(data.url, { require_tld: false })) { - throw new BadRequestException('url is not valid'); - } + if (data.enabled) { + if (!isURL(data.url, { require_tld: false })) { + throw new BadRequestException('url is not valid'); + } - if (!data.account_id) { - throw new BadRequestException('account_id is required'); - } + if (!data.account_id) { + throw new BadRequestException('account_id is required'); + } - if (!data.token) { - throw new BadRequestException('token is required'); - } + if (!data.token) { + throw new BadRequestException('token is required'); + } - if (data.sign_msg !== true && data.sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } + if (data.sign_msg !== true && data.sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + } + + if (!data.enabled) { + logger.verbose('chatwoot disabled'); + data.account_id = ''; + data.token = ''; + data.url = ''; + data.sign_msg = false; + } + + data.name_inbox = instance.instanceName; + + const result = this.chatwootService.create(instance, data); + + const urlServer = this.configService.get('SERVER').URL; + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; } - if (!data.enabled) { - logger.verbose('chatwoot disabled'); - data.account_id = ''; - data.token = ''; - data.url = ''; - data.sign_msg = false; + public async findChatwoot(instance: InstanceDto) { + logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); + const result = await this.chatwootService.find(instance); + + const urlServer = this.configService.get('SERVER').URL; + + if (Object.keys(result).length === 0) { + return { + enabled: false, + url: '', + account_id: '', + token: '', + sign_msg: false, + name_inbox: '', + webhook_url: '', + }; + } + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; } - data.name_inbox = instance.instanceName; + public async receiveWebhook(instance: InstanceDto, data: any) { + logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); + const chatwootService = new ChatwootService(waMonitor, this.configService); - const result = this.chatwootService.create(instance, data); - - const urlServer = this.configService.get('SERVER').URL; - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; - } - - public async findChatwoot(instance: InstanceDto) { - logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); - const result = await this.chatwootService.find(instance); - - const urlServer = this.configService.get('SERVER').URL; - - if (Object.keys(result).length === 0) { - return { - enabled: false, - url: '', - account_id: '', - token: '', - sign_msg: false, - name_inbox: '', - webhook_url: '', - }; + return chatwootService.receiveWebhook(instance, data); } - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; + public async newInstance(data: any) { + const chatwootService = new ChatwootService(waMonitor, this.configService); - return response; - } - - public async receiveWebhook(instance: InstanceDto, data: any) { - logger.verbose( - 'requested receiveWebhook from ' + instance.instanceName + ' instance', - ); - const chatwootService = new ChatwootService(waMonitor, this.configService); - - return chatwootService.receiveWebhook(instance, data); - } - - public async newInstance(data: any) { - const chatwootService = new ChatwootService(waMonitor, this.configService); - - return chatwootService.newInstance(data); - } + return chatwootService.newInstance(data); + } } diff --git a/src/whatsapp/controllers/group.controller.ts b/src/whatsapp/controllers/group.controller.ts index 56195f65..86e78737 100644 --- a/src/whatsapp/controllers/group.controller.ts +++ b/src/whatsapp/controllers/group.controller.ts @@ -1,16 +1,16 @@ import { Logger } from '../../config/logger.config'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; import { WAMonitoringService } from '../services/monitor.service'; @@ -18,120 +18,80 @@ import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('ChatController'); export class GroupController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async createGroup(instance: InstanceDto, create: CreateGroupDto) { - logger.verbose('requested createGroup from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].createGroup(create); - } + public async createGroup(instance: InstanceDto, create: CreateGroupDto) { + logger.verbose('requested createGroup from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].createGroup(create); + } - public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) { - logger.verbose( - 'requested updateGroupPicture from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture( - update, - ); - } + public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) { + logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update); + } - public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) { - logger.verbose( - 'requested updateGroupSubject from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject( - update, - ); - } + public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) { + logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update); + } - public async updateGroupDescription( - instance: InstanceDto, - update: GroupDescriptionDto, - ) { - logger.verbose( - 'requested updateGroupDescription from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription( - update, - ); - } + public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) { + logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update); + } - public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid); - } + public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid); + } - public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) { - logger.verbose( - 'requested fetchAllGroups from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups( - getPaticipants, - ); - } + public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) { + logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants); + } - public async inviteCode(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid); - } + public async inviteCode(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid); + } - public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) { - logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode); - } + public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) { + logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode); + } - public async sendInvite(instance: InstanceDto, data: GroupSendInvite) { - logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data); - } + public async sendInvite(instance: InstanceDto, data: GroupSendInvite) { + logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data); + } - public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose( - 'requested revokeInviteCode from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode( - groupJid, - ); - } + public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid); + } - public async findParticipants(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose( - 'requested findParticipants from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].findParticipants( - groupJid, - ); - } + public async findParticipants(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid); + } - public async updateGParticipate( - instance: InstanceDto, - update: GroupUpdateParticipantDto, - ) { - logger.verbose( - 'requested updateGParticipate from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant( - update, - ); - } + public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) { + logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update); + } - public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) { - logger.verbose( - 'requested updateGSetting from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update); - } + public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) { + logger.verbose('requested updateGSetting from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update); + } - public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) { - logger.verbose( - 'requested toggleEphemeral from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral( - update, - ); - } + public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) { + logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update); + } - public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid); - } + public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid); + } } diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index ab21986d..79449e29 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -2,7 +2,7 @@ import { delay } from '@whiskeysockets/baileys'; import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; -import { Auth, ConfigService, HttpServer } from '../../config/env.config'; +import { ConfigService, HttpServer } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; @@ -16,309 +16,294 @@ import { WAStartupService } from '../services/whatsapp.service'; import { wa } from '../types/wa.types'; export class InstanceController { - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly eventEmitter: EventEmitter2, - private readonly authService: AuthService, - private readonly webhookService: WebhookService, - private readonly chatwootService: ChatwootService, - private readonly cache: RedisCache, - ) {} + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly eventEmitter: EventEmitter2, + private readonly authService: AuthService, + private readonly webhookService: WebhookService, + private readonly chatwootService: ChatwootService, + private readonly cache: RedisCache, + ) {} - private readonly logger = new Logger(InstanceController.name); + private readonly logger = new Logger(InstanceController.name); - public async createInstance({ - instanceName, - webhook, - webhook_by_events, - events, - qrcode, - number, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - }: InstanceDto) { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException( - 'The instance name must be lowercase and without special characters', - ); - } - - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } - - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); - - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } - - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, + public async createInstance({ + instanceName, webhook, webhook_by_events, - events: getEvents, - qrcode: getQrcode, - }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + events, qrcode, number, - ); - } catch (error) { - this.logger.log(error); + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + }: InstanceDto) { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException('The instance name must be lowercase and without special characters'); + } + + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); + + this.logger.verbose('creating instance'); + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); + + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + let getEvents: string[]; + + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } + + this.logger.verbose('creating webhook'); + try { + this.webhookService.create(instance, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); + + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, + }); + + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); + } catch (error) { + this.logger.log(error); + } + + return { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, + }; } - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; - } + public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { + try { + this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); - public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { - try { - this.logger.verbose( - 'requested connectToWhatsapp from ' + instanceName + ' instance', - ); + const instance = this.waMonitor.waInstances[instanceName]; + const state = instance?.connectionStatus?.state; - const instance = this.waMonitor.waInstances[instanceName]; - const state = instance?.connectionStatus?.state; + this.logger.verbose('state: ' + state); - this.logger.verbose('state: ' + state); + if (state == 'open') { + return await this.connectionState({ instanceName }); + } - if (state == 'open') { - return await this.connectionState({ instanceName }); - } + if (state == 'connecting') { + return instance.qrCode; + } - if (state == 'connecting') { - return instance.qrCode; - } + if (state == 'close') { + this.logger.verbose('connecting'); + await instance.connectToWhatsapp(number); - if (state == 'close') { - this.logger.verbose('connecting'); - await instance.connectToWhatsapp(number); + await delay(5000); + return instance.qrCode; + } - await delay(5000); - return instance.qrCode; - } - - return { - instance: { - instanceName: instanceName, - status: state, - }, - qrcode: instance?.qrCode, - }; - } catch (error) { - this.logger.error(error); - } - } - - public async restartInstance({ instanceName }: InstanceDto) { - try { - this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - - this.logger.verbose('logging out instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - - return { error: false, message: 'Instance restarted' }; - } catch (error) { - this.logger.error(error); - } - } - - public async connectionState({ instanceName }: InstanceDto) { - this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); - return { - instance: { - instanceName: instanceName, - state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, - }, - }; - } - - public async fetchInstances({ instanceName }: InstanceDto) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); - if (instanceName) { - this.logger.verbose('instanceName: ' + instanceName); - return this.waMonitor.instanceInfo(instanceName); + return { + instance: { + instanceName: instanceName, + status: state, + }, + qrcode: instance?.qrCode, + }; + } catch (error) { + this.logger.error(error); + } } - return this.waMonitor.instanceInfo(); - } + public async restartInstance({ instanceName }: InstanceDto) { + try { + this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - public async logout({ instanceName }: InstanceDto) { - this.logger.verbose('requested logout from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); + this.logger.verbose('logging out instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - if (instance.state === 'close') { - throw new BadRequestException( - 'The "' + instanceName + '" instance is not connected', - ); + return { error: false, message: 'Instance restarted' }; + } catch (error) { + this.logger.error(error); + } } - try { - this.logger.verbose('logging out instance: ' + instanceName); - await this.waMonitor.waInstances[instanceName]?.client?.logout( - 'Log out instance: ' + instanceName, - ); - - this.logger.verbose('close connection instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - - return { error: false, message: 'Instance logged out' }; - } catch (error) { - throw new InternalServerErrorException(error.toString()); + public async connectionState({ instanceName }: InstanceDto) { + this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); + return { + instance: { + instanceName: instanceName, + state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, + }, + }; } - } - public async deleteInstance({ instanceName }: InstanceDto) { - this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); + public async fetchInstances({ instanceName }: InstanceDto) { + this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); + if (instanceName) { + this.logger.verbose('instanceName: ' + instanceName); + return this.waMonitor.instanceInfo(instanceName); + } - if (instance.state === 'open') { - throw new BadRequestException( - 'The "' + instanceName + '" instance needs to be disconnected', - ); + return this.waMonitor.instanceInfo(); } - try { - if (instance.state === 'connecting') { - this.logger.verbose('logging out instance: ' + instanceName); - await this.logout({ instanceName }); - delete this.waMonitor.waInstances[instanceName]; - return { error: false, message: 'Instance deleted' }; - } else { - this.logger.verbose('deleting instance: ' + instanceName); + public async logout({ instanceName }: InstanceDto) { + this.logger.verbose('requested logout from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); - delete this.waMonitor.waInstances[instanceName]; - this.eventEmitter.emit('remove.instance', instanceName, 'inner'); - return { error: false, message: 'Instance deleted' }; - } - } catch (error) { - throw new BadRequestException(error.toString()); + if (instance.state === 'close') { + throw new BadRequestException('The "' + instanceName + '" instance is not connected'); + } + + try { + this.logger.verbose('logging out instance: ' + instanceName); + await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); + + this.logger.verbose('close connection instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + + return { error: false, message: 'Instance logged out' }; + } catch (error) { + throw new InternalServerErrorException(error.toString()); + } } - } - public async refreshToken(_: InstanceDto, oldToken: OldToken) { - this.logger.verbose('requested refreshToken'); - return await this.authService.refreshToken(oldToken); - } + public async deleteInstance({ instanceName }: InstanceDto) { + this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); + + if (instance.state === 'open') { + throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); + } + try { + if (instance.state === 'connecting') { + this.logger.verbose('logging out instance: ' + instanceName); + + await this.logout({ instanceName }); + delete this.waMonitor.waInstances[instanceName]; + return { error: false, message: 'Instance deleted' }; + } else { + this.logger.verbose('deleting instance: ' + instanceName); + + delete this.waMonitor.waInstances[instanceName]; + this.eventEmitter.emit('remove.instance', instanceName, 'inner'); + return { error: false, message: 'Instance deleted' }; + } + } catch (error) { + throw new BadRequestException(error.toString()); + } + } + + public async refreshToken(_: InstanceDto, oldToken: OldToken) { + this.logger.verbose('requested refreshToken'); + return await this.authService.refreshToken(oldToken); + } } diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index 2f49ca50..593b858e 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -4,124 +4,112 @@ import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, } from '../dto/sendMessage.dto'; import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('MessageRouter'); export class SendMessageController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async sendText({ instanceName }: InstanceDto, data: SendTextDto) { - logger.verbose('requested sendText from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].textMessage(data); - } - - public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) { - logger.verbose('requested sendMedia from ' + instanceName + ' instance'); - - if ( - isBase64(data?.mediaMessage?.media) && - !data?.mediaMessage?.fileName && - data?.mediaMessage?.mediatype === 'document' - ) { - throw new BadRequestException('For base64 the file name must be informed.'); + public async sendText({ instanceName }: InstanceDto, data: SendTextDto) { + logger.verbose('requested sendText from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].textMessage(data); } - logger.verbose( - 'isURL: ' + - isURL(data?.mediaMessage?.media) + - ', isBase64: ' + - isBase64(data?.mediaMessage?.media), - ); - if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) { - return await this.waMonitor.waInstances[instanceName].mediaMessage(data); + public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) { + logger.verbose('requested sendMedia from ' + instanceName + ' instance'); + + if ( + isBase64(data?.mediaMessage?.media) && + !data?.mediaMessage?.fileName && + data?.mediaMessage?.mediatype === 'document' + ) { + throw new BadRequestException('For base64 the file name must be informed.'); + } + + logger.verbose( + 'isURL: ' + isURL(data?.mediaMessage?.media) + ', isBase64: ' + isBase64(data?.mediaMessage?.media), + ); + if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) { + return await this.waMonitor.waInstances[instanceName].mediaMessage(data); + } + throw new BadRequestException('Owned media must be a url or base64'); } - throw new BadRequestException('Owned media must be a url or base64'); - } - public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) { - logger.verbose('requested sendSticker from ' + instanceName + ' instance'); + public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) { + logger.verbose('requested sendSticker from ' + instanceName + ' instance'); - logger.verbose( - 'isURL: ' + - isURL(data?.stickerMessage?.image) + - ', isBase64: ' + - isBase64(data?.stickerMessage?.image), - ); - if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) { - return await this.waMonitor.waInstances[instanceName].mediaSticker(data); + logger.verbose( + 'isURL: ' + isURL(data?.stickerMessage?.image) + ', isBase64: ' + isBase64(data?.stickerMessage?.image), + ); + if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) { + return await this.waMonitor.waInstances[instanceName].mediaSticker(data); + } + throw new BadRequestException('Owned media must be a url or base64'); } - throw new BadRequestException('Owned media must be a url or base64'); - } - public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) { - logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance'); + public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) { + logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance'); - logger.verbose( - 'isURL: ' + - isURL(data?.audioMessage?.audio) + - ', isBase64: ' + - isBase64(data?.audioMessage?.audio), - ); - if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) { - return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data); + logger.verbose( + 'isURL: ' + isURL(data?.audioMessage?.audio) + ', isBase64: ' + isBase64(data?.audioMessage?.audio), + ); + if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) { + return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data); + } + throw new BadRequestException('Owned media must be a url or base64'); } - throw new BadRequestException('Owned media must be a url or base64'); - } - public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { - logger.verbose('requested sendButtons from ' + instanceName + ' instance'); - if ( - isBase64(data.buttonMessage.mediaMessage?.media) && - !data.buttonMessage.mediaMessage?.fileName - ) { - throw new BadRequestException('For bse64 the file name must be informed.'); + public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { + logger.verbose('requested sendButtons from ' + instanceName + ' instance'); + if (isBase64(data.buttonMessage.mediaMessage?.media) && !data.buttonMessage.mediaMessage?.fileName) { + throw new BadRequestException('For bse64 the file name must be informed.'); + } + return await this.waMonitor.waInstances[instanceName].buttonMessage(data); } - return await this.waMonitor.waInstances[instanceName].buttonMessage(data); - } - public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) { - logger.verbose('requested sendLocation from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].locationMessage(data); - } - - public async sendList({ instanceName }: InstanceDto, data: SendListDto) { - logger.verbose('requested sendList from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].listMessage(data); - } - - public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) { - logger.verbose('requested sendContact from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].contactMessage(data); - } - - public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { - logger.verbose('requested sendReaction from ' + instanceName + ' instance'); - if (!data.reactionMessage.reaction.match(/[^()\w\sà-ú"-+]+/)) { - throw new BadRequestException('"reaction" must be an emoji'); + public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) { + logger.verbose('requested sendLocation from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].locationMessage(data); } - return await this.waMonitor.waInstances[instanceName].reactionMessage(data); - } - public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) { - logger.verbose('requested sendPoll from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].pollMessage(data); - } + public async sendList({ instanceName }: InstanceDto, data: SendListDto) { + logger.verbose('requested sendList from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].listMessage(data); + } - public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) { - logger.verbose('requested sendStatus from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].statusMessage(data); - } + public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) { + logger.verbose('requested sendContact from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].contactMessage(data); + } + + public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { + logger.verbose('requested sendReaction from ' + instanceName + ' instance'); + if (!data.reactionMessage.reaction.match(/[^()\w\sà-ú"-+]+/)) { + throw new BadRequestException('"reaction" must be an emoji'); + } + return await this.waMonitor.waInstances[instanceName].reactionMessage(data); + } + + public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) { + logger.verbose('requested sendPoll from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].pollMessage(data); + } + + public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) { + logger.verbose('requested sendStatus from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].statusMessage(data); + } } diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 2c763b80..1d033783 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -1,5 +1,3 @@ -import { isURL } from 'class-validator'; - import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; @@ -9,22 +7,20 @@ import { SettingsService } from '../services/settings.service'; const logger = new Logger('SettingsController'); export class SettingsController { - constructor(private readonly settingsService: SettingsService) {} + constructor(private readonly settingsService: SettingsService) {} - public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose( - 'requested createSettings from ' + instance.instanceName + ' instance', - ); + public async createSettings(instance: InstanceDto, data: SettingsDto) { + logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); - if (data.reject_call && data.msg_call.trim() == '') { - throw new BadRequestException('msg_call is required'); + if (data.reject_call && data.msg_call.trim() == '') { + throw new BadRequestException('msg_call is required'); + } + + return this.settingsService.create(instance, data); } - return this.settingsService.create(instance, data); - } - - public async findSettings(instance: InstanceDto) { - logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.find(instance); - } + public async findSettings(instance: InstanceDto) { + logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); + return this.settingsService.find(instance); + } } diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index 327a209b..269ea7de 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -7,23 +7,20 @@ import { HttpStatus } from '../routers/index.router'; import { WAMonitoringService } from '../services/monitor.service'; export class ViewsController { - constructor( - private readonly waMonit: WAMonitoringService, - private readonly configService: ConfigService, - ) {} + constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} - public async qrcode(request: Request, response: Response) { - try { - const param = request.params as unknown as InstanceDto; - const instance = this.waMonit.waInstances[param.instanceName]; - if (instance.connectionStatus.state === 'open') { - throw new BadRequestException('The instance is already connected'); - } - const type = this.configService.get('AUTHENTICATION').TYPE; + public async qrcode(request: Request, response: Response) { + try { + const param = request.params as unknown as InstanceDto; + const instance = this.waMonit.waInstances[param.instanceName]; + if (instance.connectionStatus.state === 'open') { + throw new BadRequestException('The instance is already connected'); + } + const type = this.configService.get('AUTHENTICATION').TYPE; - return response.status(HttpStatus.OK).render('qrcode', { type, ...param }); - } catch (error) { - console.log('ERROR: ', error); + return response.status(HttpStatus.OK).render('qrcode', { type, ...param }); + } catch (error) { + console.log('ERROR: ', error); + } } - } } diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index 281147db..073a22fc 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -9,26 +9,26 @@ import { WebhookService } from '../services/webhook.service'; const logger = new Logger('WebhookController'); export class WebhookController { - constructor(private readonly webhookService: WebhookService) {} + constructor(private readonly webhookService: WebhookService) {} - public async createWebhook(instance: InstanceDto, data: WebhookDto) { - logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance'); + public async createWebhook(instance: InstanceDto, data: WebhookDto) { + logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance'); - if (data.enabled && !isURL(data.url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property'); + if (data.enabled && !isURL(data.url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property'); + } + + if (!data.enabled) { + logger.verbose('webhook disabled'); + data.url = ''; + data.events = []; + } + + return this.webhookService.create(instance, data); } - if (!data.enabled) { - logger.verbose('webhook disabled'); - data.url = ''; - data.events = []; + public async findWebhook(instance: InstanceDto) { + logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance'); + return this.webhookService.find(instance); } - - return this.webhookService.create(instance, data); - } - - public async findWebhook(instance: InstanceDto) { - logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance'); - return this.webhookService.find(instance); - } } diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 2800c6ff..38f17bf0 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,93 +1,84 @@ -import { - proto, - WAPrivacyOnlineValue, - WAPrivacyValue, - WAReadReceiptsValue, -} from '@whiskeysockets/baileys'; +import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; export class OnWhatsAppDto { - constructor( - public readonly jid: string, - public readonly exists: boolean, - public readonly name?: string, - ) {} + constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} } export class getBase64FromMediaMessageDto { - message: proto.WebMessageInfo; - convertToMp4?: boolean; + message: proto.WebMessageInfo; + convertToMp4?: boolean; } export class WhatsAppNumberDto { - numbers: string[]; + numbers: string[]; } export class NumberDto { - number: string; + number: string; } export class NumberBusiness { - wid?: string; - jid?: string; - exists?: boolean; - isBusiness: boolean; - name?: string; - message?: string; - description?: string; - email?: string; - website?: string[]; - address?: string; + wid?: string; + jid?: string; + exists?: boolean; + isBusiness: boolean; + name?: string; + message?: string; + description?: string; + email?: string; + website?: string[]; + address?: string; } export class ProfileNameDto { - name: string; + name: string; } export class ProfileStatusDto { - status: string; + status: string; } export class ProfilePictureDto { - number?: string; - // url or base64 - picture?: string; + number?: string; + // url or base64 + picture?: string; } class Key { - id: string; - fromMe: boolean; - remoteJid: string; + id: string; + fromMe: boolean; + remoteJid: string; } export class ReadMessageDto { - readMessages: Key[]; + readMessages: Key[]; } class LastMessage { - key: Key; - messageTimestamp?: number; + key: Key; + messageTimestamp?: number; } export class ArchiveChatDto { - lastMessage: LastMessage; - archive: boolean; + lastMessage: LastMessage; + archive: boolean; } class PrivacySetting { - readreceipts: WAReadReceiptsValue; - profile: WAPrivacyValue; - status: WAPrivacyValue; - online: WAPrivacyOnlineValue; - last: WAPrivacyValue; - groupadd: WAPrivacyValue; + readreceipts: WAReadReceiptsValue; + profile: WAPrivacyValue; + status: WAPrivacyValue; + online: WAPrivacyOnlineValue; + last: WAPrivacyValue; + groupadd: WAPrivacyValue; } export class PrivacySettingDto { - privacySettings: PrivacySetting; + privacySettings: PrivacySetting; } export class DeleteMessage { - id: string; - fromMe: boolean; - remoteJid: string; - participant?: string; + id: string; + fromMe: boolean; + remoteJid: string; + participant?: string; } diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index a5026a46..64a2f1b6 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -1,9 +1,9 @@ export class ChatwootDto { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; } diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index bc36e27f..ef47f9b8 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,51 +1,51 @@ export class CreateGroupDto { - subject: string; - description?: string; - participants: string[]; + subject: string; + description?: string; + participants: string[]; } export class GroupPictureDto { - groupJid: string; - image: string; + groupJid: string; + image: string; } export class GroupSubjectDto { - groupJid: string; - subject: string; + groupJid: string; + subject: string; } export class GroupDescriptionDto { - groupJid: string; - description: string; + groupJid: string; + description: string; } export class GroupJid { - groupJid: string; + groupJid: string; } export class GetParticipant { - getParticipants: string; + getParticipants: string; } export class GroupInvite { - inviteCode: string; + inviteCode: string; } export class GroupSendInvite { - groupJid: string; - description: string; - numbers: string[]; + groupJid: string; + description: string; + numbers: string[]; } export class GroupUpdateParticipantDto extends GroupJid { - action: 'add' | 'remove' | 'promote' | 'demote'; - participants: string[]; + action: 'add' | 'remove' | 'promote' | 'demote'; + participants: string[]; } export class GroupUpdateSettingDto extends GroupJid { - action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; + action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; } export class GroupToggleEphemeralDto extends GroupJid { - expiration: 0 | 86400 | 604800 | 7776000; + expiration: 0 | 86400 | 604800 | 7776000; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 9e8a7ec3..3fc780d1 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,13 +1,13 @@ export class InstanceDto { - instanceName: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; - qrcode?: boolean; - number?: string; - token?: string; - chatwoot_account_id?: string; - chatwoot_token?: string; - chatwoot_url?: string; - chatwoot_sign_msg?: boolean; + instanceName: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + qrcode?: boolean; + number?: string; + token?: string; + chatwoot_account_id?: string; + chatwoot_token?: string; + chatwoot_url?: string; + chatwoot_sign_msg?: boolean; } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index c2ddb3a2..754d66e2 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -1,150 +1,150 @@ import { proto, WAPresence } from '@whiskeysockets/baileys'; export class Quoted { - key: proto.IMessageKey; - message: proto.IMessage; + key: proto.IMessageKey; + message: proto.IMessage; } export class Mentions { - everyOne: boolean; - mentioned: string[]; + everyOne: boolean; + mentioned: string[]; } export class Options { - delay?: number; - presence?: WAPresence; - quoted?: Quoted; - mentions?: Mentions; - linkPreview?: boolean; - encoding?: boolean; + delay?: number; + presence?: WAPresence; + quoted?: Quoted; + mentions?: Mentions; + linkPreview?: boolean; + encoding?: boolean; } class OptionsMessage { - options: Options; + options: Options; } export class Metadata extends OptionsMessage { - number: string; + number: string; } class TextMessage { - text: string; + text: string; } export class StatusMessage { - type: string; - content: string; - statusJidList?: string[]; - allContacts?: boolean; - caption?: string; - backgroundColor?: string; - font?: number; + type: string; + content: string; + statusJidList?: string[]; + allContacts?: boolean; + caption?: string; + backgroundColor?: string; + font?: number; } class PollMessage { - name: string; - selectableCount: number; - values: string[]; - messageSecret?: Uint8Array; + name: string; + selectableCount: number; + values: string[]; + messageSecret?: Uint8Array; } export class SendTextDto extends Metadata { - textMessage: TextMessage; + textMessage: TextMessage; } export class SendStatusDto extends Metadata { - statusMessage: StatusMessage; + statusMessage: StatusMessage; } export class SendPollDto extends Metadata { - pollMessage: PollMessage; + pollMessage: PollMessage; } export type MediaType = 'image' | 'document' | 'video' | 'audio'; export class MediaMessage { - mediatype: MediaType; - caption?: string; - // for document - fileName?: string; - // url or base64 - media: string; + mediatype: MediaType; + caption?: string; + // for document + fileName?: string; + // url or base64 + media: string; } export class SendMediaDto extends Metadata { - mediaMessage: MediaMessage; + mediaMessage: MediaMessage; } class Sticker { - image: string; + image: string; } export class SendStickerDto extends Metadata { - stickerMessage: Sticker; + stickerMessage: Sticker; } class Audio { - audio: string; + audio: string; } export class SendAudioDto extends Metadata { - audioMessage: Audio; + audioMessage: Audio; } class Button { - buttonText: string; - buttonId: string; + buttonText: string; + buttonId: string; } class ButtonMessage { - title: string; - description: string; - footerText?: string; - buttons: Button[]; - mediaMessage?: MediaMessage; + title: string; + description: string; + footerText?: string; + buttons: Button[]; + mediaMessage?: MediaMessage; } export class SendButtonDto extends Metadata { - buttonMessage: ButtonMessage; + buttonMessage: ButtonMessage; } class LocationMessage { - latitude: number; - longitude: number; - name?: string; - address?: string; + latitude: number; + longitude: number; + name?: string; + address?: string; } export class SendLocationDto extends Metadata { - locationMessage: LocationMessage; + locationMessage: LocationMessage; } class Row { - title: string; - description: string; - rowId: string; + title: string; + description: string; + rowId: string; } class Section { - title: string; - rows: Row[]; + title: string; + rows: Row[]; } class ListMessage { - title: string; - description: string; - footerText?: string; - buttonText: string; - sections: Section[]; + title: string; + description: string; + footerText?: string; + buttonText: string; + sections: Section[]; } export class SendListDto extends Metadata { - listMessage: ListMessage; + listMessage: ListMessage; } export class ContactMessage { - fullName: string; - wuid: string; - phoneNumber: string; - organization?: string; - email?: string; - url?: string; + fullName: string; + wuid: string; + phoneNumber: string; + organization?: string; + email?: string; + url?: string; } export class SendContactDto extends Metadata { - contactMessage: ContactMessage[]; + contactMessage: ContactMessage[]; } class ReactionMessage { - key: proto.IMessageKey; - reaction: string; + key: proto.IMessageKey; + reaction: string; } export class SendReactionDto { - reactionMessage: ReactionMessage; + reactionMessage: ReactionMessage; } diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 20a6cba0..870a24d9 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -1,5 +1,5 @@ export class SettingsDto { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; } diff --git a/src/whatsapp/dto/webhook.dto.ts b/src/whatsapp/dto/webhook.dto.ts index 5203884d..b41ec0e6 100644 --- a/src/whatsapp/dto/webhook.dto.ts +++ b/src/whatsapp/dto/webhook.dto.ts @@ -1,6 +1,6 @@ export class WebhookDto { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; } diff --git a/src/whatsapp/guards/auth.guard.ts b/src/whatsapp/guards/auth.guard.ts index 6ddc297e..f4d30fc1 100644 --- a/src/whatsapp/guards/auth.guard.ts +++ b/src/whatsapp/guards/auth.guard.ts @@ -13,85 +13,77 @@ import { repository } from '../whatsapp.module'; const logger = new Logger('GUARD'); async function jwtGuard(req: Request, res: Response, next: NextFunction) { - const key = req.get('apikey'); + const key = req.get('apikey'); - if (key && configService.get('AUTHENTICATION').API_KEY.KEY !== key) { - throw new UnauthorizedException(); - } - - if (configService.get('AUTHENTICATION').API_KEY.KEY === key) { - return next(); - } - - if ( - (req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException( - 'Missing global api key', - 'The global api key must be set', - ); - } - - const jwtOpts = configService.get('AUTHENTICATION').JWT; - try { - const [bearer, token] = req.get('authorization').split(' '); - - if (bearer.toLowerCase() !== 'bearer') { - throw new UnauthorizedException(); + if (key && configService.get('AUTHENTICATION').API_KEY.KEY !== key) { + throw new UnauthorizedException(); } - if (!isJWT(token)) { - throw new UnauthorizedException(); + if (configService.get('AUTHENTICATION').API_KEY.KEY === key) { + return next(); } - const param = req.params as unknown as InstanceDto; - const decode = jwt.verify(token, jwtOpts.SECRET, { - ignoreExpiration: jwtOpts.EXPIRIN_IN === 0, - }) as JwtPayload; - - if (param.instanceName !== decode.instanceName || name !== decode.apiName) { - throw new UnauthorizedException(); + if ( + (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && + !key + ) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); } - return next(); - } catch (error) { - logger.error(error); - throw new UnauthorizedException(); - } + const jwtOpts = configService.get('AUTHENTICATION').JWT; + try { + const [bearer, token] = req.get('authorization').split(' '); + + if (bearer.toLowerCase() !== 'bearer') { + throw new UnauthorizedException(); + } + + if (!isJWT(token)) { + throw new UnauthorizedException(); + } + + const param = req.params as unknown as InstanceDto; + const decode = jwt.verify(token, jwtOpts.SECRET, { + ignoreExpiration: jwtOpts.EXPIRIN_IN === 0, + }) as JwtPayload; + + if (param.instanceName !== decode.instanceName || name !== decode.apiName) { + throw new UnauthorizedException(); + } + + return next(); + } catch (error) { + logger.error(error); + throw new UnauthorizedException(); + } } async function apikey(req: Request, res: Response, next: NextFunction) { - const env = configService.get('AUTHENTICATION').API_KEY; - const key = req.get('apikey'); + const env = configService.get('AUTHENTICATION').API_KEY; + const key = req.get('apikey'); - if (env.KEY === key) { - return next(); - } - - if ( - (req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException( - 'Missing global api key', - 'The global api key must be set', - ); - } - - try { - const param = req.params as unknown as InstanceDto; - const instanceKey = await repository.auth.find(param.instanceName); - if (instanceKey.apikey === key) { - return next(); + if (env.KEY === key) { + return next(); } - } catch (error) { - logger.error(error); - } - throw new UnauthorizedException(); + if ( + (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && + !key + ) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); + } + + try { + const param = req.params as unknown as InstanceDto; + const instanceKey = await repository.auth.find(param.instanceName); + if (instanceKey.apikey === key) { + return next(); + } + } catch (error) { + logger.error(error); + } + + throw new UnauthorizedException(); } export const authGuard = { jwt: jwtGuard, apikey }; diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 964b99b6..6d65c743 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -5,69 +5,60 @@ import { join } from 'path'; import { configService, Database, Redis } from '../../config/env.config'; import { INSTANCE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; -import { - BadRequestException, - ForbiddenException, - NotFoundException, -} from '../../exceptions'; +import { BadRequestException, ForbiddenException, NotFoundException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; async function getInstance(instanceName: string) { - const db = configService.get('DATABASE'); - const redisConf = configService.get('REDIS'); + const db = configService.get('DATABASE'); + const redisConf = configService.get('REDIS'); - const exists = !!waMonitor.waInstances[instanceName]; + const exists = !!waMonitor.waInstances[instanceName]; - if (redisConf.ENABLED) { - const keyExists = await cache.keyExists(); - return exists || keyExists; - } + if (redisConf.ENABLED) { + const keyExists = await cache.keyExists(); + return exists || keyExists; + } - if (db.ENABLED) { - const collection = dbserver - .getClient() - .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(instanceName); - return exists || (await collection.find({}).toArray()).length > 0; - } + if (db.ENABLED) { + const collection = dbserver + .getClient() + .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(instanceName); + return exists || (await collection.find({}).toArray()).length > 0; + } - return exists || existsSync(join(INSTANCE_DIR, instanceName)); + return exists || existsSync(join(INSTANCE_DIR, instanceName)); } export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) { - if ( - req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances') - ) { - return next(); - } + if (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) { + return next(); + } - const param = req.params as unknown as InstanceDto; - if (!param?.instanceName) { - throw new BadRequestException('"instanceName" not provided.'); - } + const param = req.params as unknown as InstanceDto; + if (!param?.instanceName) { + throw new BadRequestException('"instanceName" not provided.'); + } - if (!(await getInstance(param.instanceName))) { - throw new NotFoundException(`The "${param.instanceName}" instance does not exist`); - } + if (!(await getInstance(param.instanceName))) { + throw new NotFoundException(`The "${param.instanceName}" instance does not exist`); + } - next(); + next(); } export async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) { - if (req.originalUrl.includes('/instance/create')) { - const instance = req.body as InstanceDto; - if (await getInstance(instance.instanceName)) { - throw new ForbiddenException( - `This name "${instance.instanceName}" is already in use.`, - ); + if (req.originalUrl.includes('/instance/create')) { + const instance = req.body as InstanceDto; + if (await getInstance(instance.instanceName)) { + throw new ForbiddenException(`This name "${instance.instanceName}" is already in use.`); + } + + if (waMonitor.waInstances[instance.instanceName]) { + delete waMonitor.waInstances[instance.instanceName]; + } } - if (waMonitor.waInstances[instance.instanceName]) { - delete waMonitor.waInstances[instance.instanceName]; - } - } - - next(); + next(); } diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index 5c5b6a41..c9e48da1 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -3,15 +3,15 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class AuthRaw { - _id?: string; - jwt?: string; - apikey?: string; + _id?: string; + jwt?: string; + apikey?: string; } const authSchema = new Schema({ - _id: { type: String, _id: true }, - jwt: { type: String, minlength: 1 }, - apikey: { type: String, minlength: 1 }, + _id: { type: String, _id: true }, + jwt: { type: String, minlength: 1 }, + apikey: { type: String, minlength: 1 }, }); export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication'); diff --git a/src/whatsapp/models/chat.model.ts b/src/whatsapp/models/chat.model.ts index 20153603..d44a4673 100644 --- a/src/whatsapp/models/chat.model.ts +++ b/src/whatsapp/models/chat.model.ts @@ -3,16 +3,16 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ChatRaw { - _id?: string; - id?: string; - owner: string; - lastMsgTimestamp?: number; + _id?: string; + id?: string; + owner: string; + lastMsgTimestamp?: number; } const chatSchema = new Schema({ - _id: { type: String, _id: true }, - id: { type: String, required: true, minlength: 1 }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + id: { type: String, required: true, minlength: 1 }, + owner: { type: String, required: true, minlength: 1 }, }); export const ChatModel = dbserver?.model(ChatRaw.name, chatSchema, 'chats'); diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 307565eb..31e28894 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -3,30 +3,26 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { - _id?: string; - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; + _id?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; } const chatwootSchema = new Schema({ - _id: { type: String, _id: true }, - enabled: { type: Boolean, required: true }, - account_id: { type: String, required: true }, - token: { type: String, required: true }, - url: { type: String, required: true }, - name_inbox: { type: String, required: true }, - sign_msg: { type: Boolean, required: true }, - number: { type: String, required: true }, + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + account_id: { type: String, required: true }, + token: { type: String, required: true }, + url: { type: String, required: true }, + name_inbox: { type: String, required: true }, + sign_msg: { type: Boolean, required: true }, + number: { type: String, required: true }, }); -export const ChatwootModel = dbserver?.model( - ChatwootRaw.name, - chatwootSchema, - 'chatwoot', -); +export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot'); export type IChatwootModel = typeof ChatwootModel; diff --git a/src/whatsapp/models/contact.model.ts b/src/whatsapp/models/contact.model.ts index d9b51e1e..84749945 100644 --- a/src/whatsapp/models/contact.model.ts +++ b/src/whatsapp/models/contact.model.ts @@ -3,19 +3,19 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ContactRaw { - _id?: string; - pushName?: string; - id?: string; - profilePictureUrl?: string; - owner: string; + _id?: string; + pushName?: string; + id?: string; + profilePictureUrl?: string; + owner: string; } const contactSchema = new Schema({ - _id: { type: String, _id: true }, - pushName: { type: String, minlength: 1 }, - id: { type: String, required: true, minlength: 1 }, - profilePictureUrl: { type: String, minlength: 1 }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + pushName: { type: String, minlength: 1 }, + id: { type: String, required: true, minlength: 1 }, + profilePictureUrl: { type: String, minlength: 1 }, + owner: { type: String, required: true, minlength: 1 }, }); export const ContactModel = dbserver?.model(ContactRaw.name, contactSchema, 'contacts'); diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index c4f475ad..bfa048cf 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -4,70 +4,66 @@ import { dbserver } from '../../db/db.connect'; import { wa } from '../types/wa.types'; class Key { - id?: string; - remoteJid?: string; - fromMe?: boolean; - participant?: string; + id?: string; + remoteJid?: string; + fromMe?: boolean; + participant?: string; } export class MessageRaw { - _id?: string; - key?: Key; - pushName?: string; - participant?: string; - message?: object; - messageType?: string; - messageTimestamp?: number | Long.Long; - owner: string; - source?: 'android' | 'web' | 'ios'; + _id?: string; + key?: Key; + pushName?: string; + participant?: string; + message?: object; + messageType?: string; + messageTimestamp?: number | Long.Long; + owner: string; + source?: 'android' | 'web' | 'ios'; } const messageSchema = new Schema({ - _id: { type: String, _id: true }, - key: { - id: { type: String, required: true, minlength: 1 }, - remoteJid: { type: String, required: true, minlength: 1 }, - fromMe: { type: Boolean, required: true }, - participant: { type: String, minlength: 1 }, - }, - pushName: { type: String }, - participant: { type: String }, - messageType: { type: String }, - message: { type: Object }, - source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, - messageTimestamp: { type: Number, required: true }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + key: { + id: { type: String, required: true, minlength: 1 }, + remoteJid: { type: String, required: true, minlength: 1 }, + fromMe: { type: Boolean, required: true }, + participant: { type: String, minlength: 1 }, + }, + pushName: { type: String }, + participant: { type: String }, + messageType: { type: String }, + message: { type: Object }, + source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, + messageTimestamp: { type: Number, required: true }, + owner: { type: String, required: true, minlength: 1 }, }); export const MessageModel = dbserver?.model(MessageRaw.name, messageSchema, 'messages'); export type IMessageModel = typeof MessageModel; export class MessageUpdateRaw { - _id?: string; - remoteJid?: string; - id?: string; - fromMe?: boolean; - participant?: string; - datetime?: number; - status?: wa.StatusMessage; - owner: string; - pollUpdates?: any; + _id?: string; + remoteJid?: string; + id?: string; + fromMe?: boolean; + participant?: string; + datetime?: number; + status?: wa.StatusMessage; + owner: string; + pollUpdates?: any; } const messageUpdateSchema = new Schema({ - _id: { type: String, _id: true }, - remoteJid: { type: String, required: true, min: 1 }, - id: { type: String, required: true, min: 1 }, - fromMe: { type: Boolean, required: true }, - participant: { type: String, min: 1 }, - datetime: { type: Number, required: true, min: 1 }, - status: { type: String, required: true }, - owner: { type: String, required: true, min: 1 }, + _id: { type: String, _id: true }, + remoteJid: { type: String, required: true, min: 1 }, + id: { type: String, required: true, min: 1 }, + fromMe: { type: Boolean, required: true }, + participant: { type: String, min: 1 }, + datetime: { type: Number, required: true, min: 1 }, + status: { type: String, required: true }, + owner: { type: String, required: true, min: 1 }, }); -export const MessageUpModel = dbserver?.model( - MessageUpdateRaw.name, - messageUpdateSchema, - 'messageUpdate', -); +export const MessageUpModel = dbserver?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate'); export type IMessageUpModel = typeof MessageUpModel; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index e70605e4..283f44fd 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -3,22 +3,18 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class SettingsRaw { - _id?: string; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; + _id?: string; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; } const settingsSchema = new Schema({ - _id: { type: String, _id: true }, - reject_call: { type: Boolean, required: true }, - msg_call: { type: String, required: true }, - groups_ignore: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + reject_call: { type: Boolean, required: true }, + msg_call: { type: String, required: true }, + groups_ignore: { type: Boolean, required: true }, }); -export const SettingsModel = dbserver?.model( - SettingsRaw.name, - settingsSchema, - 'settings', -); +export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings'); export type ISettingsModel = typeof SettingsModel; diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index fa91326c..57d55a7b 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -3,19 +3,19 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class WebhookRaw { - _id?: string; - url?: string; - enabled?: boolean; - events?: string[]; - webhook_by_events?: boolean; + _id?: string; + url?: string; + enabled?: boolean; + events?: string[]; + webhook_by_events?: boolean; } const webhookSchema = new Schema({ - _id: { type: String, _id: true }, - url: { type: String, required: true }, - enabled: { type: Boolean, required: true }, - events: { type: [String], required: true }, - webhook_by_events: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + url: { type: String, required: true }, + enabled: { type: Boolean, required: true }, + events: { type: [String], required: true }, + webhook_by_events: { type: Boolean, required: true }, }); export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook'); diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 9949cec3..b93ea86d 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -1,74 +1,65 @@ import { readFileSync } from 'fs'; import { join } from 'path'; -import { Auth, ConfigService, Database } from '../../config/env.config'; +import { Auth, ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { AUTH_DIR } from '../../config/path.config'; import { IInsert, Repository } from '../abstract/abstract.repository'; import { AuthRaw, IAuthModel } from '../models'; export class AuthRepository extends Repository { - constructor( - private readonly authModel: IAuthModel, - readonly configService: ConfigService, - ) { - super(configService); - this.auth = configService.get('AUTHENTICATION'); - } - - private readonly auth: Auth; - private readonly logger = new Logger('AuthRepository'); - - public async create(data: AuthRaw, instance: string): Promise { - try { - this.logger.verbose('creating auth'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving auth to db'); - const insert = await this.authModel.replaceOne( - { _id: instance }, - { ...data }, - { upsert: true }, - ); - - this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving auth to store'); - - this.writeStore({ - path: join(AUTH_DIR, this.auth.TYPE), - fileName: instance, - data, - }); - this.logger.verbose( - 'auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance, - ); - - this.logger.verbose('auth created'); - return { insertCount: 1 }; - } catch (error) { - return { error } as any; + constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) { + super(configService); + this.auth = configService.get('AUTHENTICATION'); } - } - public async find(instance: string): Promise { - try { - this.logger.verbose('finding auth'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding auth in db'); - return await this.authModel.findOne({ _id: instance }); - } + private readonly auth: Auth; + private readonly logger = new Logger('AuthRepository'); - this.logger.verbose('finding auth in store'); + public async create(data: AuthRaw, instance: string): Promise { + try { + this.logger.verbose('creating auth'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving auth to db'); + const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - return JSON.parse( - readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), { - encoding: 'utf-8', - }), - ) as AuthRaw; - } catch (error) { - return {}; + this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving auth to store'); + + this.writeStore({ + path: join(AUTH_DIR, this.auth.TYPE), + fileName: instance, + data, + }); + this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance); + + this.logger.verbose('auth created'); + return { insertCount: 1 }; + } catch (error) { + return { error } as any; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding auth'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding auth in db'); + return await this.authModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding auth in store'); + + return JSON.parse( + readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), { + encoding: 'utf-8', + }), + ) as AuthRaw; + } catch (error) { + return {}; + } } - } } diff --git a/src/whatsapp/repository/chat.repository.ts b/src/whatsapp/repository/chat.repository.ts index 31e1764a..b3ff575a 100644 --- a/src/whatsapp/repository/chat.repository.ts +++ b/src/whatsapp/repository/chat.repository.ts @@ -7,122 +7,111 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ChatRaw, IChatModel } from '../models'; export class ChatQuery { - where: ChatRaw; + where: ChatRaw; } export class ChatRepository extends Repository { - constructor( - private readonly chatModel: IChatModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('ChatRepository'); - - public async insert( - data: ChatRaw[], - instanceName: string, - saveDb = false, - ): Promise { - this.logger.verbose('inserting chats'); - if (data.length === 0) { - this.logger.verbose('no chats to insert'); - return; + constructor(private readonly chatModel: IChatModel, private readonly configService: ConfigService) { + super(configService); } - try { - this.logger.verbose('saving chats to store'); - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving chats to db'); - const insert = await this.chatModel.insertMany([...data]); + private readonly logger = new Logger('ChatRepository'); - this.logger.verbose('chats saved to db: ' + insert.length + ' chats'); - return { insertCount: insert.length }; - } - - this.logger.verbose('saving chats to store'); - - const store = this.configService.get('STORE'); - - if (store.CHATS) { - this.logger.verbose('saving chats to store'); - data.forEach((chat) => { - this.writeStore({ - path: join(this.storePath, 'chats', instanceName), - fileName: chat.id, - data: chat, - }); - this.logger.verbose( - 'chats saved to store in path: ' + - join(this.storePath, 'chats', instanceName) + - '/' + - chat.id, - ); - }); - - this.logger.verbose('chats saved to store'); - return { insertCount: data.length }; - } - - this.logger.verbose('chats not saved to store'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } - } - - public async find(query: ChatQuery): Promise { - try { - this.logger.verbose('finding chats'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding chats in db'); - return await this.chatModel.find({ owner: query.where.owner }); - } - - this.logger.verbose('finding chats in store'); - - const chats: ChatRaw[] = []; - const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner)); - for await (const dirent of openDir) { - if (dirent.isFile()) { - chats.push( - JSON.parse( - readFileSync( - join(this.storePath, 'chats', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), - ), - ); + public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting chats'); + if (data.length === 0) { + this.logger.verbose('no chats to insert'); + return; } - } - this.logger.verbose('chats found in store: ' + chats.length + ' chats'); - return chats; - } catch (error) { - return []; + try { + this.logger.verbose('saving chats to store'); + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving chats to db'); + const insert = await this.chatModel.insertMany([...data]); + + this.logger.verbose('chats saved to db: ' + insert.length + ' chats'); + return { insertCount: insert.length }; + } + + this.logger.verbose('saving chats to store'); + + const store = this.configService.get('STORE'); + + if (store.CHATS) { + this.logger.verbose('saving chats to store'); + data.forEach((chat) => { + this.writeStore({ + path: join(this.storePath, 'chats', instanceName), + fileName: chat.id, + data: chat, + }); + this.logger.verbose( + 'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id, + ); + }); + + this.logger.verbose('chats saved to store'); + return { insertCount: data.length }; + } + + this.logger.verbose('chats not saved to store'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; + } } - } - public async delete(query: ChatQuery) { - try { - this.logger.verbose('deleting chats'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('deleting chats in db'); - return await this.chatModel.deleteOne({ ...query.where }); - } + public async find(query: ChatQuery): Promise { + try { + this.logger.verbose('finding chats'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding chats in db'); + return await this.chatModel.find({ owner: query.where.owner }); + } - this.logger.verbose('deleting chats in store'); - rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), { - force: true, - recursive: true, - }); + this.logger.verbose('finding chats in store'); - return { deleted: { chatId: query.where.id } }; - } catch (error) { - return { error: error?.toString() }; + const chats: ChatRaw[] = []; + const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner)); + for await (const dirent of openDir) { + if (dirent.isFile()) { + chats.push( + JSON.parse( + readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } + } + + this.logger.verbose('chats found in store: ' + chats.length + ' chats'); + return chats; + } catch (error) { + return []; + } + } + + public async delete(query: ChatQuery) { + try { + this.logger.verbose('deleting chats'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('deleting chats in db'); + return await this.chatModel.deleteOne({ ...query.where }); + } + + this.logger.verbose('deleting chats in store'); + rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), { + force: true, + recursive: true, + }); + + return { deleted: { chatId: query.where.id } }; + } catch (error) { + return { error: error?.toString() }; + } } - } } diff --git a/src/whatsapp/repository/chatwoot.repository.ts b/src/whatsapp/repository/chatwoot.repository.ts index bc722cd6..6cc3f631 100644 --- a/src/whatsapp/repository/chatwoot.repository.ts +++ b/src/whatsapp/repository/chatwoot.repository.ts @@ -7,70 +7,58 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ChatwootRaw, IChatwootModel } from '../models'; export class ChatwootRepository extends Repository { - constructor( - private readonly chatwootModel: IChatwootModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('ChatwootRepository'); - - public async create(data: ChatwootRaw, instance: string): Promise { - try { - this.logger.verbose('creating chatwoot'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving chatwoot to db'); - const insert = await this.chatwootModel.replaceOne( - { _id: instance }, - { ...data }, - { upsert: true }, - ); - - this.logger.verbose( - 'chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot', - ); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving chatwoot to store'); - - this.writeStore({ - path: join(this.storePath, 'chatwoot'), - fileName: instance, - data, - }); - - this.logger.verbose( - 'chatwoot saved to store in path: ' + - join(this.storePath, 'chatwoot') + - '/' + - instance, - ); - - this.logger.verbose('chatwoot created'); - return { insertCount: 1 }; - } catch (error) { - return error; + constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) { + super(configService); } - } - public async find(instance: string): Promise { - try { - this.logger.verbose('finding chatwoot'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding chatwoot in db'); - return await this.chatwootModel.findOne({ _id: instance }); - } + private readonly logger = new Logger('ChatwootRepository'); - this.logger.verbose('finding chatwoot in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), { - encoding: 'utf-8', - }), - ) as ChatwootRaw; - } catch (error) { - return {}; + public async create(data: ChatwootRaw, instance: string): Promise { + try { + this.logger.verbose('creating chatwoot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving chatwoot to db'); + const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving chatwoot to store'); + + this.writeStore({ + path: join(this.storePath, 'chatwoot'), + fileName: instance, + data, + }); + + this.logger.verbose( + 'chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance, + ); + + this.logger.verbose('chatwoot created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding chatwoot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding chatwoot in db'); + return await this.chatwootModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding chatwoot in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), { + encoding: 'utf-8', + }), + ) as ChatwootRaw; + } catch (error) { + return {}; + } } - } } diff --git a/src/whatsapp/repository/contact.repository.ts b/src/whatsapp/repository/contact.repository.ts index 6a16f2a1..ed96ff56 100644 --- a/src/whatsapp/repository/contact.repository.ts +++ b/src/whatsapp/repository/contact.repository.ts @@ -7,189 +7,171 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ContactRaw, IContactModel } from '../models'; export class ContactQuery { - where: ContactRaw; + where: ContactRaw; } export class ContactRepository extends Repository { - constructor( - private readonly contactModel: IContactModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('ContactRepository'); - - public async insert( - data: ContactRaw[], - instanceName: string, - saveDb = false, - ): Promise { - this.logger.verbose('inserting contacts'); - - if (data.length === 0) { - this.logger.verbose('no contacts to insert'); - return; + constructor(private readonly contactModel: IContactModel, private readonly configService: ConfigService) { + super(configService); } - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving contacts to db'); + private readonly logger = new Logger('ContactRepository'); - const insert = await this.contactModel.insertMany([...data]); + public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting contacts'); - this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts'); - return { insertCount: insert.length }; - } - - this.logger.verbose('saving contacts to store'); - - const store = this.configService.get('STORE'); - - if (store.CONTACTS) { - this.logger.verbose('saving contacts to store'); - data.forEach((contact) => { - this.writeStore({ - path: join(this.storePath, 'contacts', instanceName), - fileName: contact.id, - data: contact, - }); - this.logger.verbose( - 'contacts saved to store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, - ); - }); - - this.logger.verbose('contacts saved to store: ' + data.length + ' contacts'); - return { insertCount: data.length }; - } - - this.logger.verbose('contacts not saved'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } - } - - public async update( - data: ContactRaw[], - instanceName: string, - saveDb = false, - ): Promise { - try { - this.logger.verbose('updating contacts'); - - if (data.length === 0) { - this.logger.verbose('no contacts to update'); - return; - } - - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('updating contacts in db'); - - const contacts = data.map((contact) => { - return { - updateOne: { - filter: { id: contact.id }, - update: { ...contact }, - upsert: true, - }, - }; - }); - - const { nModified } = await this.contactModel.bulkWrite(contacts); - - this.logger.verbose('contacts updated in db: ' + nModified + ' contacts'); - return { insertCount: nModified }; - } - - this.logger.verbose('updating contacts in store'); - - const store = this.configService.get('STORE'); - - if (store.CONTACTS) { - this.logger.verbose('updating contacts in store'); - data.forEach((contact) => { - this.writeStore({ - path: join(this.storePath, 'contacts', instanceName), - fileName: contact.id, - data: contact, - }); - this.logger.verbose( - 'contacts updated in store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, - ); - }); - - this.logger.verbose('contacts updated in store: ' + data.length + ' contacts'); - - return { insertCount: data.length }; - } - - this.logger.verbose('contacts not updated'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } - } - - public async find(query: ContactQuery): Promise { - try { - this.logger.verbose('finding contacts'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding contacts in db'); - return await this.contactModel.find({ ...query.where }); - } - - this.logger.verbose('finding contacts in store'); - const contacts: ContactRaw[] = []; - if (query?.where?.id) { - this.logger.verbose('finding contacts in store by id'); - contacts.push( - JSON.parse( - readFileSync( - join( - this.storePath, - 'contacts', - query.where.owner, - query.where.id + '.json', - ), - { encoding: 'utf-8' }, - ), - ), - ); - } else { - this.logger.verbose('finding contacts in store by owner'); - - const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), { - encoding: 'utf-8', - }); - for await (const dirent of openDir) { - if (dirent.isFile()) { - contacts.push( - JSON.parse( - readFileSync( - join(this.storePath, 'contacts', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), - ), - ); - } + if (data.length === 0) { + this.logger.verbose('no contacts to insert'); + return; } - } - this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts'); - return contacts; - } catch (error) { - return []; + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving contacts to db'); + + const insert = await this.contactModel.insertMany([...data]); + + this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts'); + return { insertCount: insert.length }; + } + + this.logger.verbose('saving contacts to store'); + + const store = this.configService.get('STORE'); + + if (store.CONTACTS) { + this.logger.verbose('saving contacts to store'); + data.forEach((contact) => { + this.writeStore({ + path: join(this.storePath, 'contacts', instanceName), + fileName: contact.id, + data: contact, + }); + this.logger.verbose( + 'contacts saved to store in path: ' + + join(this.storePath, 'contacts', instanceName) + + '/' + + contact.id, + ); + }); + + this.logger.verbose('contacts saved to store: ' + data.length + ' contacts'); + return { insertCount: data.length }; + } + + this.logger.verbose('contacts not saved'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; + } + } + + public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise { + try { + this.logger.verbose('updating contacts'); + + if (data.length === 0) { + this.logger.verbose('no contacts to update'); + return; + } + + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('updating contacts in db'); + + const contacts = data.map((contact) => { + return { + updateOne: { + filter: { id: contact.id }, + update: { ...contact }, + upsert: true, + }, + }; + }); + + const { nModified } = await this.contactModel.bulkWrite(contacts); + + this.logger.verbose('contacts updated in db: ' + nModified + ' contacts'); + return { insertCount: nModified }; + } + + this.logger.verbose('updating contacts in store'); + + const store = this.configService.get('STORE'); + + if (store.CONTACTS) { + this.logger.verbose('updating contacts in store'); + data.forEach((contact) => { + this.writeStore({ + path: join(this.storePath, 'contacts', instanceName), + fileName: contact.id, + data: contact, + }); + this.logger.verbose( + 'contacts updated in store in path: ' + + join(this.storePath, 'contacts', instanceName) + + '/' + + contact.id, + ); + }); + + this.logger.verbose('contacts updated in store: ' + data.length + ' contacts'); + + return { insertCount: data.length }; + } + + this.logger.verbose('contacts not updated'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; + } + } + + public async find(query: ContactQuery): Promise { + try { + this.logger.verbose('finding contacts'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding contacts in db'); + return await this.contactModel.find({ ...query.where }); + } + + this.logger.verbose('finding contacts in store'); + const contacts: ContactRaw[] = []; + if (query?.where?.id) { + this.logger.verbose('finding contacts in store by id'); + contacts.push( + JSON.parse( + readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), { + encoding: 'utf-8', + }), + ), + ); + } else { + this.logger.verbose('finding contacts in store by owner'); + + const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), { + encoding: 'utf-8', + }); + for await (const dirent of openDir) { + if (dirent.isFile()) { + contacts.push( + JSON.parse( + readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } + } + } + + this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts'); + return contacts; + } catch (error) { + return []; + } } - } } diff --git a/src/whatsapp/repository/message.repository.ts b/src/whatsapp/repository/message.repository.ts index d9ccea99..efd57783 100644 --- a/src/whatsapp/repository/message.repository.ts +++ b/src/whatsapp/repository/message.repository.ts @@ -7,158 +7,145 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IMessageModel, MessageRaw } from '../models'; export class MessageQuery { - where: MessageRaw; - limit?: number; + where: MessageRaw; + limit?: number; } export class MessageRepository extends Repository { - constructor( - private readonly messageModel: IMessageModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('MessageRepository'); - - public async insert( - data: MessageRaw[], - instanceName: string, - saveDb = false, - ): Promise { - this.logger.verbose('inserting messages'); - - if (!Array.isArray(data) || data.length === 0) { - this.logger.verbose('no messages to insert'); - return; + constructor(private readonly messageModel: IMessageModel, private readonly configService: ConfigService) { + super(configService); } - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving messages to db'); - const cleanedData = data.map((obj) => { - const cleanedObj = { ...obj }; - if ('extendedTextMessage' in obj.message) { - const extendedTextMessage = obj.message.extendedTextMessage as { - contextInfo?: { - mentionedJid?: any; - }; - }; + private readonly logger = new Logger('MessageRepository'); - if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) { - if ('contextInfo' in extendedTextMessage) { - delete extendedTextMessage.contextInfo?.mentionedJid; - extendedTextMessage.contextInfo = {}; - } + public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting messages'); + + if (!Array.isArray(data) || data.length === 0) { + this.logger.verbose('no messages to insert'); + return; + } + + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving messages to db'); + const cleanedData = data.map((obj) => { + const cleanedObj = { ...obj }; + if ('extendedTextMessage' in obj.message) { + const extendedTextMessage = obj.message.extendedTextMessage as { + contextInfo?: { + mentionedJid?: any; + }; + }; + + if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) { + if ('contextInfo' in extendedTextMessage) { + delete extendedTextMessage.contextInfo?.mentionedJid; + extendedTextMessage.contextInfo = {}; + } + } + } + return cleanedObj; + }); + + const insert = await this.messageModel.insertMany([...cleanedData]); + + this.logger.verbose('messages saved to db: ' + insert.length + ' messages'); + return { insertCount: insert.length }; } - } - return cleanedObj; - }); - const insert = await this.messageModel.insertMany([...cleanedData]); + this.logger.verbose('saving messages to store'); - this.logger.verbose('messages saved to db: ' + insert.length + ' messages'); - return { insertCount: insert.length }; - } + const store = this.configService.get('STORE'); - this.logger.verbose('saving messages to store'); + if (store.MESSAGES) { + this.logger.verbose('saving messages to store'); - const store = this.configService.get('STORE'); + data.forEach((message) => { + this.writeStore({ + path: join(this.storePath, 'messages', instanceName), + fileName: message.key.id, + data: message, + }); + this.logger.verbose( + 'messages saved to store in path: ' + + join(this.storePath, 'messages', instanceName) + + '/' + + message.key.id, + ); + }); - if (store.MESSAGES) { - this.logger.verbose('saving messages to store'); + this.logger.verbose('messages saved to store: ' + data.length + ' messages'); + return { insertCount: data.length }; + } - data.forEach((message) => { - this.writeStore({ - path: join(this.storePath, 'messages', instanceName), - fileName: message.key.id, - data: message, - }); - this.logger.verbose( - 'messages saved to store in path: ' + - join(this.storePath, 'messages', instanceName) + - '/' + - message.key.id, - ); - }); - - this.logger.verbose('messages saved to store: ' + data.length + ' messages'); - return { insertCount: data.length }; - } - - this.logger.verbose('messages not saved to store'); - return { insertCount: 0 }; - } catch (error) { - console.log('ERROR: ', error); - return error; - } finally { - data = undefined; - } - } - - public async find(query: MessageQuery) { - try { - this.logger.verbose('finding messages'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding messages in db'); - if (query?.where?.key) { - for (const [k, v] of Object.entries(query.where.key)) { - query.where['key.' + k] = v; - } - delete query?.where?.key; + this.logger.verbose('messages not saved to store'); + return { insertCount: 0 }; + } catch (error) { + console.log('ERROR: ', error); + return error; + } finally { + data = undefined; + } + } + + public async find(query: MessageQuery) { + try { + this.logger.verbose('finding messages'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding messages in db'); + if (query?.where?.key) { + for (const [k, v] of Object.entries(query.where.key)) { + query.where['key.' + k] = v; + } + delete query?.where?.key; + } + + return await this.messageModel + .find({ ...query.where }) + .sort({ messageTimestamp: -1 }) + .limit(query?.limit ?? 0); + } + + this.logger.verbose('finding messages in store'); + const messages: MessageRaw[] = []; + if (query?.where?.key?.id) { + this.logger.verbose('finding messages in store by id'); + messages.push( + JSON.parse( + readFileSync( + join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), + { encoding: 'utf-8' }, + ), + ), + ); + } else { + this.logger.verbose('finding messages in store by owner'); + const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), { + encoding: 'utf-8', + }); + + for await (const dirent of openDir) { + if (dirent.isFile()) { + messages.push( + JSON.parse( + readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } + } + } + + this.logger.verbose('messages found in store: ' + messages.length + ' messages'); + return messages + .sort((x, y) => { + return (y.messageTimestamp as number) - (x.messageTimestamp as number); + }) + .splice(0, query?.limit ?? messages.length); + } catch (error) { + return []; } - - return await this.messageModel - .find({ ...query.where }) - .sort({ messageTimestamp: -1 }) - .limit(query?.limit ?? 0); - } - - this.logger.verbose('finding messages in store'); - const messages: MessageRaw[] = []; - if (query?.where?.key?.id) { - this.logger.verbose('finding messages in store by id'); - messages.push( - JSON.parse( - readFileSync( - join( - this.storePath, - 'messages', - query.where.owner, - query.where.key.id + '.json', - ), - { encoding: 'utf-8' }, - ), - ), - ); - } else { - this.logger.verbose('finding messages in store by owner'); - const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), { - encoding: 'utf-8', - }); - - for await (const dirent of openDir) { - if (dirent.isFile()) { - messages.push( - JSON.parse( - readFileSync( - join(this.storePath, 'messages', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), - ), - ); - } - } - } - - this.logger.verbose('messages found in store: ' + messages.length + ' messages'); - return messages - .sort((x, y) => { - return (y.messageTimestamp as number) - (x.messageTimestamp as number); - }) - .splice(0, query?.limit ?? messages.length); - } catch (error) { - return []; } - } } diff --git a/src/whatsapp/repository/messageUp.repository.ts b/src/whatsapp/repository/messageUp.repository.ts index fe2f623b..7a25467f 100644 --- a/src/whatsapp/repository/messageUp.repository.ts +++ b/src/whatsapp/repository/messageUp.repository.ts @@ -7,134 +7,117 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IMessageUpModel, MessageUpdateRaw } from '../models'; export class MessageUpQuery { - where: MessageUpdateRaw; - limit?: number; + where: MessageUpdateRaw; + limit?: number; } export class MessageUpRepository extends Repository { - constructor( - private readonly messageUpModel: IMessageUpModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('MessageUpRepository'); - - public async insert( - data: MessageUpdateRaw[], - instanceName: string, - saveDb?: boolean, - ): Promise { - this.logger.verbose('inserting message up'); - - if (data.length === 0) { - this.logger.verbose('no message up to insert'); - return; + constructor(private readonly messageUpModel: IMessageUpModel, private readonly configService: ConfigService) { + super(configService); } - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving message up to db'); - const insert = await this.messageUpModel.insertMany([...data]); + private readonly logger = new Logger('MessageUpRepository'); - this.logger.verbose('message up saved to db: ' + insert.length + ' message up'); - return { insertCount: insert.length }; - } + public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise { + this.logger.verbose('inserting message up'); - this.logger.verbose('saving message up to store'); - - const store = this.configService.get('STORE'); - - if (store.MESSAGE_UP) { - this.logger.verbose('saving message up to store'); - data.forEach((update) => { - this.writeStore({ - path: join(this.storePath, 'message-up', instanceName), - fileName: update.id, - data: update, - }); - this.logger.verbose( - 'message up saved to store in path: ' + - join(this.storePath, 'message-up', instanceName) + - '/' + - update.id, - ); - }); - - this.logger.verbose('message up saved to store: ' + data.length + ' message up'); - return { insertCount: data.length }; - } - - this.logger.verbose('message up not saved to store'); - return { insertCount: 0 }; - } catch (error) { - return error; - } - } - - public async find(query: MessageUpQuery) { - try { - this.logger.verbose('finding message up'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding message up in db'); - return await this.messageUpModel - .find({ ...query.where }) - .sort({ datetime: -1 }) - .limit(query?.limit ?? 0); - } - - this.logger.verbose('finding message up in store'); - - const messageUpdate: MessageUpdateRaw[] = []; - if (query?.where?.id) { - this.logger.verbose('finding message up in store by id'); - - messageUpdate.push( - JSON.parse( - readFileSync( - join( - this.storePath, - 'message-up', - query.where.owner, - query.where.id + '.json', - ), - { encoding: 'utf-8' }, - ), - ), - ); - } else { - this.logger.verbose('finding message up in store by owner'); - - const openDir = opendirSync( - join(this.storePath, 'message-up', query.where.owner), - { encoding: 'utf-8' }, - ); - - for await (const dirent of openDir) { - if (dirent.isFile()) { - messageUpdate.push( - JSON.parse( - readFileSync( - join(this.storePath, 'message-up', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), - ), - ); - } + if (data.length === 0) { + this.logger.verbose('no message up to insert'); + return; } - } - this.logger.verbose( - 'message up found in store: ' + messageUpdate.length + ' message up', - ); - return messageUpdate - .sort((x, y) => { - return y.datetime - x.datetime; - }) - .splice(0, query?.limit ?? messageUpdate.length); - } catch (error) { - return []; + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving message up to db'); + const insert = await this.messageUpModel.insertMany([...data]); + + this.logger.verbose('message up saved to db: ' + insert.length + ' message up'); + return { insertCount: insert.length }; + } + + this.logger.verbose('saving message up to store'); + + const store = this.configService.get('STORE'); + + if (store.MESSAGE_UP) { + this.logger.verbose('saving message up to store'); + data.forEach((update) => { + this.writeStore({ + path: join(this.storePath, 'message-up', instanceName), + fileName: update.id, + data: update, + }); + this.logger.verbose( + 'message up saved to store in path: ' + + join(this.storePath, 'message-up', instanceName) + + '/' + + update.id, + ); + }); + + this.logger.verbose('message up saved to store: ' + data.length + ' message up'); + return { insertCount: data.length }; + } + + this.logger.verbose('message up not saved to store'); + return { insertCount: 0 }; + } catch (error) { + return error; + } + } + + public async find(query: MessageUpQuery) { + try { + this.logger.verbose('finding message up'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding message up in db'); + return await this.messageUpModel + .find({ ...query.where }) + .sort({ datetime: -1 }) + .limit(query?.limit ?? 0); + } + + this.logger.verbose('finding message up in store'); + + const messageUpdate: MessageUpdateRaw[] = []; + if (query?.where?.id) { + this.logger.verbose('finding message up in store by id'); + + messageUpdate.push( + JSON.parse( + readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), { + encoding: 'utf-8', + }), + ), + ); + } else { + this.logger.verbose('finding message up in store by owner'); + + const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), { + encoding: 'utf-8', + }); + + for await (const dirent of openDir) { + if (dirent.isFile()) { + messageUpdate.push( + JSON.parse( + readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } + } + } + + this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up'); + return messageUpdate + .sort((x, y) => { + return y.datetime - x.datetime; + }) + .splice(0, query?.limit ?? messageUpdate.length); + } catch (error) { + return []; + } } - } } diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index eea039a9..57a206b8 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -13,104 +13,100 @@ import { MessageUpRepository } from './messageUp.repository'; import { SettingsRepository } from './settings.repository'; import { WebhookRepository } from './webhook.repository'; export class RepositoryBroker { - constructor( - public readonly message: MessageRepository, - public readonly chat: ChatRepository, - public readonly contact: ContactRepository, - public readonly messageUpdate: MessageUpRepository, - public readonly webhook: WebhookRepository, - public readonly chatwoot: ChatwootRepository, - public readonly settings: SettingsRepository, - public readonly auth: AuthRepository, - private configService: ConfigService, - dbServer?: MongoClient, - ) { - this.dbClient = dbServer; - this.__init_repo_without_db__(); - } - - private dbClient?: MongoClient; - private readonly logger = new Logger('RepositoryBroker'); - - public get dbServer() { - return this.dbClient; - } - - private __init_repo_without_db__() { - this.logger.verbose('initializing repository without db'); - if (!this.configService.get('DATABASE').ENABLED) { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - try { - const authDir = join( - storePath, - 'auth', - this.configService.get('AUTHENTICATION').TYPE, - ); - const chatsDir = join(storePath, 'chats'); - const contactsDir = join(storePath, 'contacts'); - const messagesDir = join(storePath, 'messages'); - const messageUpDir = join(storePath, 'message-up'); - const webhookDir = join(storePath, 'webhook'); - const chatwootDir = join(storePath, 'chatwoot'); - const settingsDir = join(storePath, 'settings'); - const tempDir = join(storePath, 'temp'); - - if (!fs.existsSync(authDir)) { - this.logger.verbose('creating auth dir: ' + authDir); - fs.mkdirSync(authDir, { recursive: true }); - } - if (!fs.existsSync(chatsDir)) { - this.logger.verbose('creating chats dir: ' + chatsDir); - fs.mkdirSync(chatsDir, { recursive: true }); - } - if (!fs.existsSync(contactsDir)) { - this.logger.verbose('creating contacts dir: ' + contactsDir); - fs.mkdirSync(contactsDir, { recursive: true }); - } - if (!fs.existsSync(messagesDir)) { - this.logger.verbose('creating messages dir: ' + messagesDir); - fs.mkdirSync(messagesDir, { recursive: true }); - } - if (!fs.existsSync(messageUpDir)) { - this.logger.verbose('creating message-up dir: ' + messageUpDir); - fs.mkdirSync(messageUpDir, { recursive: true }); - } - if (!fs.existsSync(webhookDir)) { - this.logger.verbose('creating webhook dir: ' + webhookDir); - fs.mkdirSync(webhookDir, { recursive: true }); - } - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(settingsDir)) { - this.logger.verbose('creating settings dir: ' + settingsDir); - fs.mkdirSync(settingsDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } - } else { - try { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - - const tempDir = join(storePath, 'temp'); - - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } + constructor( + public readonly message: MessageRepository, + public readonly chat: ChatRepository, + public readonly contact: ContactRepository, + public readonly messageUpdate: MessageUpRepository, + public readonly webhook: WebhookRepository, + public readonly chatwoot: ChatwootRepository, + public readonly settings: SettingsRepository, + public readonly auth: AuthRepository, + private configService: ConfigService, + dbServer?: MongoClient, + ) { + this.dbClient = dbServer; + this.__init_repo_without_db__(); + } + + private dbClient?: MongoClient; + private readonly logger = new Logger('RepositoryBroker'); + + public get dbServer() { + return this.dbClient; + } + + private __init_repo_without_db__() { + this.logger.verbose('initializing repository without db'); + if (!this.configService.get('DATABASE').ENABLED) { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + try { + const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); + const chatsDir = join(storePath, 'chats'); + const contactsDir = join(storePath, 'contacts'); + const messagesDir = join(storePath, 'messages'); + const messageUpDir = join(storePath, 'message-up'); + const webhookDir = join(storePath, 'webhook'); + const chatwootDir = join(storePath, 'chatwoot'); + const settingsDir = join(storePath, 'settings'); + const tempDir = join(storePath, 'temp'); + + if (!fs.existsSync(authDir)) { + this.logger.verbose('creating auth dir: ' + authDir); + fs.mkdirSync(authDir, { recursive: true }); + } + if (!fs.existsSync(chatsDir)) { + this.logger.verbose('creating chats dir: ' + chatsDir); + fs.mkdirSync(chatsDir, { recursive: true }); + } + if (!fs.existsSync(contactsDir)) { + this.logger.verbose('creating contacts dir: ' + contactsDir); + fs.mkdirSync(contactsDir, { recursive: true }); + } + if (!fs.existsSync(messagesDir)) { + this.logger.verbose('creating messages dir: ' + messagesDir); + fs.mkdirSync(messagesDir, { recursive: true }); + } + if (!fs.existsSync(messageUpDir)) { + this.logger.verbose('creating message-up dir: ' + messageUpDir); + fs.mkdirSync(messageUpDir, { recursive: true }); + } + if (!fs.existsSync(webhookDir)) { + this.logger.verbose('creating webhook dir: ' + webhookDir); + fs.mkdirSync(webhookDir, { recursive: true }); + } + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(settingsDir)) { + this.logger.verbose('creating settings dir: ' + settingsDir); + fs.mkdirSync(settingsDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } else { + try { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } } - } } diff --git a/src/whatsapp/repository/settings.repository.ts b/src/whatsapp/repository/settings.repository.ts index 704a3d7d..96003d69 100644 --- a/src/whatsapp/repository/settings.repository.ts +++ b/src/whatsapp/repository/settings.repository.ts @@ -7,70 +7,58 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ISettingsModel, SettingsRaw } from '../models'; export class SettingsRepository extends Repository { - constructor( - private readonly settingsModel: ISettingsModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('SettingsRepository'); - - public async create(data: SettingsRaw, instance: string): Promise { - try { - this.logger.verbose('creating settings'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving settings to db'); - const insert = await this.settingsModel.replaceOne( - { _id: instance }, - { ...data }, - { upsert: true }, - ); - - this.logger.verbose( - 'settings saved to db: ' + insert.modifiedCount + ' settings', - ); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving settings to store'); - - this.writeStore({ - path: join(this.storePath, 'settings'), - fileName: instance, - data, - }); - - this.logger.verbose( - 'settings saved to store in path: ' + - join(this.storePath, 'settings') + - '/' + - instance, - ); - - this.logger.verbose('settings created'); - return { insertCount: 1 }; - } catch (error) { - return error; + constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) { + super(configService); } - } - public async find(instance: string): Promise { - try { - this.logger.verbose('finding settings'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding settings in db'); - return await this.settingsModel.findOne({ _id: instance }); - } + private readonly logger = new Logger('SettingsRepository'); - this.logger.verbose('finding settings in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'settings', instance + '.json'), { - encoding: 'utf-8', - }), - ) as SettingsRaw; - } catch (error) { - return {}; + public async create(data: SettingsRaw, instance: string): Promise { + try { + this.logger.verbose('creating settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving settings to db'); + const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving settings to store'); + + this.writeStore({ + path: join(this.storePath, 'settings'), + fileName: instance, + data, + }); + + this.logger.verbose( + 'settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance, + ); + + this.logger.verbose('settings created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding settings in db'); + return await this.settingsModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding settings in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'settings', instance + '.json'), { + encoding: 'utf-8', + }), + ) as SettingsRaw; + } catch (error) { + return {}; + } } - } } diff --git a/src/whatsapp/repository/webhook.repository.ts b/src/whatsapp/repository/webhook.repository.ts index dc6d9154..f3e9d12f 100644 --- a/src/whatsapp/repository/webhook.repository.ts +++ b/src/whatsapp/repository/webhook.repository.ts @@ -7,68 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IWebhookModel, WebhookRaw } from '../models'; export class WebhookRepository extends Repository { - constructor( - private readonly webhookModel: IWebhookModel, - private readonly configService: ConfigService, - ) { - super(configService); - } - - private readonly logger = new Logger('WebhookRepository'); - - public async create(data: WebhookRaw, instance: string): Promise { - try { - this.logger.verbose('creating webhook'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving webhook to db'); - const insert = await this.webhookModel.replaceOne( - { _id: instance }, - { ...data }, - { upsert: true }, - ); - - this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving webhook to store'); - - this.writeStore({ - path: join(this.storePath, 'webhook'), - fileName: instance, - data, - }); - - this.logger.verbose( - 'webhook saved to store in path: ' + - join(this.storePath, 'webhook') + - '/' + - instance, - ); - - this.logger.verbose('webhook created'); - return { insertCount: 1 }; - } catch (error) { - return error; + constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) { + super(configService); } - } - public async find(instance: string): Promise { - try { - this.logger.verbose('finding webhook'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding webhook in db'); - return await this.webhookModel.findOne({ _id: instance }); - } + private readonly logger = new Logger('WebhookRepository'); - this.logger.verbose('finding webhook in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'webhook', instance + '.json'), { - encoding: 'utf-8', - }), - ) as WebhookRaw; - } catch (error) { - return {}; + public async create(data: WebhookRaw, instance: string): Promise { + try { + this.logger.verbose('creating webhook'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving webhook to db'); + const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving webhook to store'); + + this.writeStore({ + path: join(this.storePath, 'webhook'), + fileName: instance, + data, + }); + + this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance); + + this.logger.verbose('webhook created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding webhook'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding webhook in db'); + return await this.webhookModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding webhook in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'webhook', instance + '.json'), { + encoding: 'utf-8', + }), + ) as WebhookRaw; + } catch (error) { + return {}; + } } - } } diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index ecc8ebb6..ee7e972f 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -1,33 +1,32 @@ -import { proto } from '@whiskeysockets/baileys'; import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - archiveChatSchema, - contactValidateSchema, - deleteMessageSchema, - messageUpSchema, - messageValidateSchema, - privacySettingsSchema, - profileNameSchema, - profilePictureSchema, - profileSchema, - profileStatusSchema, - readMessageSchema, - whatsappNumberSchema, + archiveChatSchema, + contactValidateSchema, + deleteMessageSchema, + messageUpSchema, + messageValidateSchema, + privacySettingsSchema, + profileNameSchema, + profilePictureSchema, + profileSchema, + profileStatusSchema, + readMessageSchema, + whatsappNumberSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberDto, - PrivacySettingDto, - ProfileNameDto, - ProfilePictureDto, - ProfileStatusDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberDto, + PrivacySettingDto, + ProfileNameDto, + ProfilePictureDto, + ProfileStatusDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; @@ -39,326 +38,317 @@ import { HttpStatus } from './index.router'; const logger = new Logger('ChatRouter'); export class ChatRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => { - logger.verbose('request received in whatsappNumbers'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => { + logger.verbose('request received in whatsappNumbers'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: whatsappNumberSchema, - ClassRef: WhatsAppNumberDto, - execute: (instance, data) => chatController.whatsappNumber(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: whatsappNumberSchema, + ClassRef: WhatsAppNumberDto, + execute: (instance, data) => chatController.whatsappNumber(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => { - logger.verbose('request received in markMessageAsRead'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => { + logger.verbose('request received in markMessageAsRead'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: readMessageSchema, - ClassRef: ReadMessageDto, - execute: (instance, data) => chatController.readMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: readMessageSchema, + ClassRef: ReadMessageDto, + execute: (instance, data) => chatController.readMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('archiveChat'), ...guards, async (req, res) => { - logger.verbose('request received in archiveChat'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('archiveChat'), ...guards, async (req, res) => { + logger.verbose('request received in archiveChat'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: archiveChatSchema, - ClassRef: ArchiveChatDto, - execute: (instance, data) => chatController.archiveChat(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: archiveChatSchema, + ClassRef: ArchiveChatDto, + execute: (instance, data) => chatController.archiveChat(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .delete( - this.routerPath('deleteMessageForEveryone'), - ...guards, - async (req, res) => { - logger.verbose('request received in deleteMessageForEveryone'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => { + logger.verbose('request received in deleteMessageForEveryone'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: deleteMessageSchema, - ClassRef: DeleteMessage, - execute: (instance, data) => chatController.deleteMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: deleteMessageSchema, + ClassRef: DeleteMessage, + execute: (instance, data) => chatController.deleteMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }, - ) - .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => { - logger.verbose('request received in fetchProfilePictureUrl'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => { + logger.verbose('request received in fetchProfilePictureUrl'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: NumberDto, - execute: (instance, data) => chatController.fetchProfilePicture(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: NumberDto, + execute: (instance, data) => chatController.fetchProfilePicture(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { - logger.verbose('request received in fetchProfile'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { + logger.verbose('request received in fetchProfile'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileSchema, - ClassRef: NumberDto, - execute: (instance, data) => chatController.fetchProfile(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileSchema, + ClassRef: NumberDto, + execute: (instance, data) => chatController.fetchProfile(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('findContacts'), ...guards, async (req, res) => { - logger.verbose('request received in findContacts'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('findContacts'), ...guards, async (req, res) => { + logger.verbose('request received in findContacts'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: contactValidateSchema, - ClassRef: ContactQuery, - execute: (instance, data) => chatController.fetchContacts(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: contactValidateSchema, + ClassRef: ContactQuery, + execute: (instance, data) => chatController.fetchContacts(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => { - logger.verbose('request received in getBase64FromMediaMessage'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => { + logger.verbose('request received in getBase64FromMediaMessage'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: getBase64FromMediaMessageDto, - execute: (instance, data) => - chatController.getBase64FromMediaMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: getBase64FromMediaMessageDto, + execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('findMessages'), ...guards, async (req, res) => { - logger.verbose('request received in findMessages'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('findMessages'), ...guards, async (req, res) => { + logger.verbose('request received in findMessages'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: messageValidateSchema, - ClassRef: MessageQuery, - execute: (instance, data) => chatController.fetchMessages(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: messageValidateSchema, + ClassRef: MessageQuery, + execute: (instance, data) => chatController.fetchMessages(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => { - logger.verbose('request received in findStatusMessage'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => { + logger.verbose('request received in findStatusMessage'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: messageUpSchema, - ClassRef: MessageUpQuery, - execute: (instance, data) => chatController.fetchStatusMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: messageUpSchema, + ClassRef: MessageUpQuery, + execute: (instance, data) => chatController.fetchStatusMessage(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('findChats'), ...guards, async (req, res) => { - logger.verbose('request received in findChats'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('findChats'), ...guards, async (req, res) => { + logger.verbose('request received in findChats'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => chatController.fetchChats(instance), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => chatController.fetchChats(instance), + }); - return res.status(HttpStatus.OK).json(response); - }) - // Profile routes - .get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => { - logger.verbose('request received in fetchPrivacySettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + // Profile routes + .get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => { + logger.verbose('request received in fetchPrivacySettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => chatController.fetchPrivacySettings(instance), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => chatController.fetchPrivacySettings(instance), + }); - return res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => { - logger.verbose('request received in updatePrivacySettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => { + logger.verbose('request received in updatePrivacySettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: privacySettingsSchema, - ClassRef: PrivacySettingDto, - execute: (instance, data) => - chatController.updatePrivacySettings(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: privacySettingsSchema, + ClassRef: PrivacySettingDto, + execute: (instance, data) => chatController.updatePrivacySettings(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => { - logger.verbose('request received in fetchBusinessProfile'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => { + logger.verbose('request received in fetchBusinessProfile'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.fetchBusinessProfile(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance, data) => chatController.fetchBusinessProfile(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('updateProfileName'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfileName'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('updateProfileName'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfileName'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileNameSchema, - ClassRef: ProfileNameDto, - execute: (instance, data) => chatController.updateProfileName(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileNameSchema, + ClassRef: ProfileNameDto, + execute: (instance, data) => chatController.updateProfileName(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfileStatus'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfileStatus'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileStatusSchema, - ClassRef: ProfileStatusDto, - execute: (instance, data) => chatController.updateProfileStatus(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileStatusSchema, + ClassRef: ProfileStatusDto, + execute: (instance, data) => chatController.updateProfileStatus(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfilePicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfilePicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.updateProfilePicture(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance, data) => chatController.updateProfilePicture(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => { - logger.verbose('request received in removeProfilePicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => { + logger.verbose('request received in removeProfilePicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.removeProfilePicture(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance) => chatController.removeProfilePicture(instance), + }); - return res.status(HttpStatus.OK).json(response); - }); - } + return res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/chatwoot.router.ts b/src/whatsapp/routers/chatwoot.router.ts index 74e47552..6527099e 100644 --- a/src/whatsapp/routers/chatwoot.router.ts +++ b/src/whatsapp/routers/chatwoot.router.ts @@ -12,58 +12,58 @@ import { HttpStatus } from './index.router'; const logger = new Logger('ChatwootRouter'); export class ChatwootRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: chatwootSchema, - ClassRef: ChatwootDto, - execute: (instance, data) => chatwootController.createChatwoot(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: chatwootSchema, + ClassRef: ChatwootDto, + execute: (instance, data) => chatwootController.createChatwoot(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => chatwootController.findChatwoot(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => chatwootController.findChatwoot(instance), + }); - res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('webhook'), async (req, res) => { - logger.verbose('request received in findChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('webhook'), async (req, res) => { + logger.verbose('request received in findChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance, data) => chatwootController.receiveWebhook(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance, data) => chatwootController.receiveWebhook(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/group.router.ts b/src/whatsapp/routers/group.router.ts index 7d95ef10..33c22f9b 100644 --- a/src/whatsapp/routers/group.router.ts +++ b/src/whatsapp/routers/group.router.ts @@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - createGroupSchema, - getParticipantsSchema, - groupInviteSchema, - groupJidSchema, - groupSendInviteSchema, - toggleEphemeralSchema, - updateGroupDescriptionSchema, - updateGroupPictureSchema, - updateGroupSubjectSchema, - updateParticipantsSchema, - updateSettingsSchema, + createGroupSchema, + getParticipantsSchema, + groupInviteSchema, + groupJidSchema, + groupSendInviteSchema, + toggleEphemeralSchema, + updateGroupDescriptionSchema, + updateGroupPictureSchema, + updateGroupSubjectSchema, + updateParticipantsSchema, + updateSettingsSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { groupController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; @@ -34,252 +34,251 @@ import { HttpStatus } from './index.router'; const logger = new Logger('GroupRouter'); export class GroupRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('create'), ...guards, async (req, res) => { - logger.verbose('request received in createGroup'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('create'), ...guards, async (req, res) => { + logger.verbose('request received in createGroup'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: createGroupSchema, - ClassRef: CreateGroupDto, - execute: (instance, data) => groupController.createGroup(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: createGroupSchema, + ClassRef: CreateGroupDto, + execute: (instance, data) => groupController.createGroup(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupSubject'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupSubject'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupSubjectSchema, - ClassRef: GroupSubjectDto, - execute: (instance, data) => groupController.updateGroupSubject(instance, data), - }); + const response = await this.groupValidate({ + request: req, + schema: updateGroupSubjectSchema, + ClassRef: GroupSubjectDto, + execute: (instance, data) => groupController.updateGroupSubject(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupPicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupPicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupPictureSchema, - ClassRef: GroupPictureDto, - execute: (instance, data) => groupController.updateGroupPicture(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateGroupPictureSchema, + ClassRef: GroupPictureDto, + execute: (instance, data) => groupController.updateGroupPicture(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupDescription'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupDescription'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupDescriptionSchema, - ClassRef: GroupDescriptionDto, - execute: (instance, data) => - groupController.updateGroupDescription(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateGroupDescriptionSchema, + ClassRef: GroupDescriptionDto, + execute: (instance, data) => groupController.updateGroupDescription(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => { - logger.verbose('request received in findGroupInfos'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => { + logger.verbose('request received in findGroupInfos'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.findGroupInfo(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.findGroupInfo(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => { - logger.verbose('request received in fetchAllGroups'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => { + logger.verbose('request received in fetchAllGroups'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.getParticipantsValidate({ - request: req, - schema: getParticipantsSchema, - ClassRef: GetParticipant, - execute: (instance, data) => groupController.fetchAllGroups(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.getParticipantsValidate({ + request: req, + schema: getParticipantsSchema, + ClassRef: GetParticipant, + execute: (instance, data) => groupController.fetchAllGroups(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('participants'), ...guards, async (req, res) => { - logger.verbose('request received in participants'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('participants'), ...guards, async (req, res) => { + logger.verbose('request received in participants'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.findParticipants(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.findParticipants(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('inviteCode'), ...guards, async (req, res) => { - logger.verbose('request received in inviteCode'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('inviteCode'), ...guards, async (req, res) => { + logger.verbose('request received in inviteCode'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.inviteCode(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.inviteCode(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('inviteInfo'), ...guards, async (req, res) => { - logger.verbose('request received in inviteInfo'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('inviteInfo'), ...guards, async (req, res) => { + logger.verbose('request received in inviteInfo'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.inviteCodeValidate({ - request: req, - schema: groupInviteSchema, - ClassRef: GroupInvite, - execute: (instance, data) => groupController.inviteInfo(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.inviteCodeValidate({ + request: req, + schema: groupInviteSchema, + ClassRef: GroupInvite, + execute: (instance, data) => groupController.inviteInfo(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('sendInvite'), ...guards, async (req, res) => { - logger.verbose('request received in sendInvite'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('sendInvite'), ...guards, async (req, res) => { + logger.verbose('request received in sendInvite'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupNoValidate({ - request: req, - schema: groupSendInviteSchema, - ClassRef: GroupSendInvite, - execute: (instance, data) => groupController.sendInvite(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupNoValidate({ + request: req, + schema: groupSendInviteSchema, + ClassRef: GroupSendInvite, + execute: (instance, data) => groupController.sendInvite(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => { - logger.verbose('request received in revokeInviteCode'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => { + logger.verbose('request received in revokeInviteCode'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.revokeInviteCode(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.revokeInviteCode(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateParticipant'), ...guards, async (req, res) => { - logger.verbose('request received in updateParticipant'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateParticipant'), ...guards, async (req, res) => { + logger.verbose('request received in updateParticipant'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateParticipantsSchema, - ClassRef: GroupUpdateParticipantDto, - execute: (instance, data) => groupController.updateGParticipate(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateParticipantsSchema, + ClassRef: GroupUpdateParticipantDto, + execute: (instance, data) => groupController.updateGParticipate(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateSetting'), ...guards, async (req, res) => { - logger.verbose('request received in updateSetting'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateSetting'), ...guards, async (req, res) => { + logger.verbose('request received in updateSetting'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateSettingsSchema, - ClassRef: GroupUpdateSettingDto, - execute: (instance, data) => groupController.updateGSetting(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateSettingsSchema, + ClassRef: GroupUpdateSettingDto, + execute: (instance, data) => groupController.updateGSetting(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => { - logger.verbose('request received in toggleEphemeral'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => { + logger.verbose('request received in toggleEphemeral'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: toggleEphemeralSchema, - ClassRef: GroupToggleEphemeralDto, - execute: (instance, data) => groupController.toggleEphemeral(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: toggleEphemeralSchema, + ClassRef: GroupToggleEphemeralDto, + execute: (instance, data) => groupController.toggleEphemeral(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => { - logger.verbose('request received in leaveGroup'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => { + logger.verbose('request received in leaveGroup'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: {}, - ClassRef: GroupJid, - execute: (instance, data) => groupController.leaveGroup(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: {}, + ClassRef: GroupJid, + execute: (instance, data) => groupController.leaveGroup(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 3cdcced7..941efeda 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -14,13 +14,13 @@ import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; enum HttpStatus { - OK = 200, - CREATED = 201, - NOT_FOUND = 404, - FORBIDDEN = 403, - BAD_REQUEST = 400, - UNAUTHORIZED = 401, - INTERNAL_SERVER_ERROR = 500, + OK = 200, + CREATED = 201, + NOT_FOUND = 404, + FORBIDDEN = 403, + BAD_REQUEST = 400, + UNAUTHORIZED = 401, + INTERNAL_SERVER_ERROR = 500, } const router = Router(); @@ -30,23 +30,19 @@ const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]]; const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); router - .get('/', (req, res) => { - res.status(HttpStatus.OK).json({ - status: HttpStatus.OK, - message: 'Welcome to the Evolution API, it is working!', - version: packageJson.version, - }); - }) - .use( - '/instance', - new InstanceRouter(configService, ...guards).router, - new ViewsRouter(instanceExistsGuard).router, - ) - .use('/message', new MessageRouter(...guards).router) - .use('/chat', new ChatRouter(...guards).router) - .use('/group', new GroupRouter(...guards).router) - .use('/webhook', new WebhookRouter(...guards).router) - .use('/chatwoot', new ChatwootRouter(...guards).router) - .use('/settings', new SettingsRouter(...guards).router); + .get('/', (req, res) => { + res.status(HttpStatus.OK).json({ + status: HttpStatus.OK, + message: 'Welcome to the Evolution API, it is working!', + version: packageJson.version, + }); + }) + .use('/instance', new InstanceRouter(configService, ...guards).router, new ViewsRouter(instanceExistsGuard).router) + .use('/message', new MessageRouter(...guards).router) + .use('/chat', new ChatRouter(...guards).router) + .use('/group', new GroupRouter(...guards).router) + .use('/webhook', new WebhookRouter(...guards).router) + .use('/chatwoot', new ChatwootRouter(...guards).router) + .use('/settings', new SettingsRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index e3dbd4a9..2c0f6a38 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -13,169 +13,165 @@ import { HttpStatus } from './index.router'; const logger = new Logger('InstanceRouter'); export class InstanceRouter extends RouterBroker { - constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) { - super(); - const auth = configService.get('AUTHENTICATION'); - this.router - .post('/create', ...guards, async (req, res) => { - logger.verbose('request received in createInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) { + super(); + const auth = configService.get('AUTHENTICATION'); + this.router + .post('/create', ...guards, async (req, res) => { + logger.verbose('request received in createInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.createInstance(instance), + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.createInstance(instance), + }); + + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('restart'), ...guards, async (req, res) => { + logger.verbose('request received in restartInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.restartInstance(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('connect'), ...guards, async (req, res) => { + logger.verbose('request received in connectInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.connectToWhatsapp(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('connectionState'), ...guards, async (req, res) => { + logger.verbose('request received in connectionState'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.connectionState(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => { + logger.verbose('request received in fetchInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => instanceController.fetchInstances(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('logout'), ...guards, async (req, res) => { + logger.verbose('request received in logoutInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.logout(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('delete'), ...guards, async (req, res) => { + logger.verbose('request received in deleteInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.deleteInstance(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }); + + if (auth.TYPE === 'jwt') { + this.router.put('/refreshToken', async (req, res) => { + logger.verbose('request received in refreshToken'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: oldTokenSchema, + ClassRef: OldToken, + execute: (_, data) => instanceController.refreshToken(_, data), + }); + + return res.status(HttpStatus.CREATED).json(response); + }); + } + + this.router.delete('/deleteDatabase', async (req, res) => { + logger.verbose('request received in deleteDatabase'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const db = this.configService.get('DATABASE'); + if (db.ENABLED) { + try { + await dbserver.dropDatabase(); + return res.status(HttpStatus.CREATED).json({ error: false, message: 'Database deleted' }); + } catch (error) { + return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message }); + } + } + + return res + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .json({ error: true, message: 'Database is not enabled' }); }); - - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('restart'), ...guards, async (req, res) => { - logger.verbose('request received in restartInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.restartInstance(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('connect'), ...guards, async (req, res) => { - logger.verbose('request received in connectInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.connectToWhatsapp(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('connectionState'), ...guards, async (req, res) => { - logger.verbose('request received in connectionState'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.connectionState(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => { - logger.verbose('request received in fetchInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => instanceController.fetchInstances(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('logout'), ...guards, async (req, res) => { - logger.verbose('request received in logoutInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.logout(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('delete'), ...guards, async (req, res) => { - logger.verbose('request received in deleteInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.deleteInstance(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }); - - if (auth.TYPE === 'jwt') { - this.router.put('/refreshToken', async (req, res) => { - logger.verbose('request received in refreshToken'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: oldTokenSchema, - ClassRef: OldToken, - execute: (_, data) => instanceController.refreshToken(_, data), - }); - - return res.status(HttpStatus.CREATED).json(response); - }); } - this.router.delete('/deleteDatabase', async (req, res) => { - logger.verbose('request received in deleteDatabase'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const db = this.configService.get('DATABASE'); - if (db.ENABLED) { - try { - await dbserver.dropDatabase(); - return res - .status(HttpStatus.CREATED) - .json({ error: false, message: 'Database deleted' }); - } catch (error) { - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ error: true, message: error.message }); - } - } - - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ error: true, message: 'Database is not enabled' }); - }); - } - - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index ae79d387..4550ff8b 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - audioMessageSchema, - buttonMessageSchema, - contactMessageSchema, - listMessageSchema, - locationMessageSchema, - mediaMessageSchema, - pollMessageSchema, - reactionMessageSchema, - statusMessageSchema, - stickerMessageSchema, - textMessageSchema, + audioMessageSchema, + buttonMessageSchema, + contactMessageSchema, + listMessageSchema, + locationMessageSchema, + mediaMessageSchema, + pollMessageSchema, + reactionMessageSchema, + statusMessageSchema, + stickerMessageSchema, + textMessageSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, } from '../dto/sendMessage.dto'; import { sendMessageController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; @@ -34,187 +34,186 @@ import { HttpStatus } from './index.router'; const logger = new Logger('MessageRouter'); export class MessageRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('sendText'), ...guards, async (req, res) => { - logger.verbose('request received in sendText'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('sendText'), ...guards, async (req, res) => { + logger.verbose('request received in sendText'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: textMessageSchema, - ClassRef: SendTextDto, - execute: (instance, data) => sendMessageController.sendText(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: textMessageSchema, + ClassRef: SendTextDto, + execute: (instance, data) => sendMessageController.sendText(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendMedia'), ...guards, async (req, res) => { - logger.verbose('request received in sendMedia'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendMedia'), ...guards, async (req, res) => { + logger.verbose('request received in sendMedia'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: mediaMessageSchema, - ClassRef: SendMediaDto, - execute: (instance, data) => sendMessageController.sendMedia(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: mediaMessageSchema, + ClassRef: SendMediaDto, + execute: (instance, data) => sendMessageController.sendMedia(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => { - logger.verbose('request received in sendWhatsAppAudio'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => { + logger.verbose('request received in sendWhatsAppAudio'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: audioMessageSchema, - ClassRef: SendMediaDto, - execute: (instance, data) => - sendMessageController.sendWhatsAppAudio(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: audioMessageSchema, + ClassRef: SendMediaDto, + execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendButtons'), ...guards, async (req, res) => { - logger.verbose('request received in sendButtons'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendButtons'), ...guards, async (req, res) => { + logger.verbose('request received in sendButtons'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: buttonMessageSchema, - ClassRef: SendButtonDto, - execute: (instance, data) => sendMessageController.sendButtons(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: buttonMessageSchema, + ClassRef: SendButtonDto, + execute: (instance, data) => sendMessageController.sendButtons(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendLocation'), ...guards, async (req, res) => { - logger.verbose('request received in sendLocation'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendLocation'), ...guards, async (req, res) => { + logger.verbose('request received in sendLocation'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: locationMessageSchema, - ClassRef: SendLocationDto, - execute: (instance, data) => sendMessageController.sendLocation(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: locationMessageSchema, + ClassRef: SendLocationDto, + execute: (instance, data) => sendMessageController.sendLocation(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendList'), ...guards, async (req, res) => { - logger.verbose('request received in sendList'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendList'), ...guards, async (req, res) => { + logger.verbose('request received in sendList'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: listMessageSchema, - ClassRef: SendListDto, - execute: (instance, data) => sendMessageController.sendList(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: listMessageSchema, + ClassRef: SendListDto, + execute: (instance, data) => sendMessageController.sendList(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendContact'), ...guards, async (req, res) => { - logger.verbose('request received in sendContact'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendContact'), ...guards, async (req, res) => { + logger.verbose('request received in sendContact'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: contactMessageSchema, - ClassRef: SendContactDto, - execute: (instance, data) => sendMessageController.sendContact(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: contactMessageSchema, + ClassRef: SendContactDto, + execute: (instance, data) => sendMessageController.sendContact(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendReaction'), ...guards, async (req, res) => { - logger.verbose('request received in sendReaction'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendReaction'), ...guards, async (req, res) => { + logger.verbose('request received in sendReaction'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: reactionMessageSchema, - ClassRef: SendReactionDto, - execute: (instance, data) => sendMessageController.sendReaction(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: reactionMessageSchema, + ClassRef: SendReactionDto, + execute: (instance, data) => sendMessageController.sendReaction(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendPoll'), ...guards, async (req, res) => { - logger.verbose('request received in sendPoll'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendPoll'), ...guards, async (req, res) => { + logger.verbose('request received in sendPoll'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: pollMessageSchema, - ClassRef: SendPollDto, - execute: (instance, data) => sendMessageController.sendPoll(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: pollMessageSchema, + ClassRef: SendPollDto, + execute: (instance, data) => sendMessageController.sendPoll(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendStatus'), ...guards, async (req, res) => { - logger.verbose('request received in sendStatus'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendStatus'), ...guards, async (req, res) => { + logger.verbose('request received in sendStatus'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: statusMessageSchema, - ClassRef: SendStatusDto, - execute: (instance, data) => sendMessageController.sendStatus(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: statusMessageSchema, + ClassRef: SendStatusDto, + execute: (instance, data) => sendMessageController.sendStatus(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendSticker'), ...guards, async (req, res) => { - logger.verbose('request received in sendSticker'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendSticker'), ...guards, async (req, res) => { + logger.verbose('request received in sendSticker'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: stickerMessageSchema, - ClassRef: SendStickerDto, - execute: (instance, data) => sendMessageController.sendSticker(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: stickerMessageSchema, + ClassRef: SendStickerDto, + execute: (instance, data) => sendMessageController.sendSticker(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }); - } + return res.status(HttpStatus.CREATED).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts index c45dd49b..feb37cd0 100644 --- a/src/whatsapp/routers/settings.router.ts +++ b/src/whatsapp/routers/settings.router.ts @@ -12,42 +12,42 @@ import { HttpStatus } from './index.router'; const logger = new Logger('SettingsRouter'); export class SettingsRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setSettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: settingsSchema, - ClassRef: SettingsDto, - execute: (instance, data) => settingsController.createSettings(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: settingsSchema, + ClassRef: SettingsDto, + execute: (instance, data) => settingsController.createSettings(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findSettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => settingsController.findSettings(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => settingsController.findSettings(instance), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/view.router.ts b/src/whatsapp/routers/view.router.ts index c5e18129..297f0125 100644 --- a/src/whatsapp/routers/view.router.ts +++ b/src/whatsapp/routers/view.router.ts @@ -4,13 +4,13 @@ import { RouterBroker } from '../abstract/abstract.router'; import { viewsController } from '../whatsapp.module'; export class ViewsRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); + constructor(...guards: RequestHandler[]) { + super(); - this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => { - return viewsController.qrcode(req, res); - }); - } + this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => { + return viewsController.qrcode(req, res); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/webhook.router.ts b/src/whatsapp/routers/webhook.router.ts index 835d6014..ef95e5a2 100644 --- a/src/whatsapp/routers/webhook.router.ts +++ b/src/whatsapp/routers/webhook.router.ts @@ -11,42 +11,42 @@ import { HttpStatus } from './index.router'; const logger = new Logger('WebhookRouter'); export class WebhookRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setWebhook'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setWebhook'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: webhookSchema, - ClassRef: WebhookDto, - execute: (instance, data) => webhookController.createWebhook(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: webhookSchema, + ClassRef: WebhookDto, + execute: (instance, data) => webhookController.createWebhook(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findWebhook'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findWebhook'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => webhookController.findWebhook(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => webhookController.findWebhook(instance), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/services/auth.service.ts b/src/whatsapp/services/auth.service.ts index 3854e148..f5cd0c38 100644 --- a/src/whatsapp/services/auth.service.ts +++ b/src/whatsapp/services/auth.service.ts @@ -12,175 +12,166 @@ import { RepositoryBroker } from '../repository/repository.manager'; import { WAMonitoringService } from './monitor.service'; export type JwtPayload = { - instanceName: string; - apiName: string; - jwt?: string; - apikey?: string; - tokenId: string; + instanceName: string; + apiName: string; + jwt?: string; + apikey?: string; + tokenId: string; }; export class OldToken { - oldToken: string; + oldToken: string; } export class AuthService { - constructor( - private readonly configService: ConfigService, - private readonly waMonitor: WAMonitoringService, - private readonly repository: RepositoryBroker, - ) {} + constructor( + private readonly configService: ConfigService, + private readonly waMonitor: WAMonitoringService, + private readonly repository: RepositoryBroker, + ) {} - private readonly logger = new Logger(AuthService.name); + private readonly logger = new Logger(AuthService.name); - private async jwt(instance: InstanceDto) { - const jwtOpts = this.configService.get('AUTHENTICATION').JWT; - const token = sign( - { - instanceName: instance.instanceName, - apiName, - tokenId: v4(), - }, - jwtOpts.SECRET, - { expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' }, - ); - - this.logger.verbose('JWT token created: ' + token); - - const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName); - - this.logger.verbose('JWT token saved in database'); - - if (auth['error']) { - this.logger.error({ - localError: AuthService.name + '.jwt', - error: auth['error'], - }); - throw new BadRequestException('Authentication error', auth['error']?.toString()); - } - - return { jwt: token }; - } - - private async apikey(instance: InstanceDto, token?: string) { - const apikey = token ? token : v4().toUpperCase(); - - this.logger.verbose( - token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey, - ); - - const auth = await this.repository.auth.create({ apikey }, instance.instanceName); - - this.logger.verbose('APIKEY saved in database'); - - if (auth['error']) { - this.logger.error({ - localError: AuthService.name + '.apikey', - error: auth['error'], - }); - throw new BadRequestException('Authentication error', auth['error']?.toString()); - } - - return { apikey }; - } - - public async checkDuplicateToken(token: string) { - const instances = await this.waMonitor.instanceInfo(); - - this.logger.verbose('checking duplicate token'); - - const instance = instances.find((instance) => instance.instance.apikey === token); - - if (instance) { - throw new BadRequestException('Token already exists'); - } - - this.logger.verbose('available token'); - - return true; - } - - public async generateHash(instance: InstanceDto, token?: string) { - const options = this.configService.get('AUTHENTICATION'); - - this.logger.verbose( - 'generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName, - ); - - return (await this[options.TYPE](instance, token)) as - | { jwt: string } - | { apikey: string }; - } - - public async refreshToken({ oldToken }: OldToken) { - this.logger.verbose('refreshing token'); - - if (!isJWT(oldToken)) { - throw new BadRequestException('Invalid "oldToken"'); - } - - try { - const jwtOpts = this.configService.get('AUTHENTICATION').JWT; - - this.logger.verbose('checking oldToken'); - - const decode = verify(oldToken, jwtOpts.SECRET, { - ignoreExpiration: true, - }) as Pick; - - this.logger.verbose('checking token in database'); - - const tokenStore = await this.repository.auth.find(decode.instanceName); - - const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, { - ignoreExpiration: true, - }) as Pick; - - this.logger.verbose('checking tokenId'); - - if (decode.tokenId !== decodeTokenStore.tokenId) { - throw new BadRequestException('Invalid "oldToken"'); - } - - this.logger.verbose('generating new token'); - - const token = { - jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt, - instanceName: decode.instanceName, - }; - - try { - this.logger.verbose('checking webhook'); - const webhook = await this.repository.webhook.find(decode.instanceName); - if ( - webhook?.enabled && - this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN - ) { - this.logger.verbose('sending webhook'); - - const httpService = axios.create({ baseURL: webhook.url }); - await httpService.post( - '', + private async jwt(instance: InstanceDto) { + const jwtOpts = this.configService.get('AUTHENTICATION').JWT; + const token = sign( { - event: 'new.jwt', - instance: decode.instanceName, - data: token, + instanceName: instance.instanceName, + apiName, + tokenId: v4(), }, - { params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } }, - ); + jwtOpts.SECRET, + { expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' }, + ); + + this.logger.verbose('JWT token created: ' + token); + + const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName); + + this.logger.verbose('JWT token saved in database'); + + if (auth['error']) { + this.logger.error({ + localError: AuthService.name + '.jwt', + error: auth['error'], + }); + throw new BadRequestException('Authentication error', auth['error']?.toString()); } - } catch (error) { - this.logger.error(error); - } - this.logger.verbose('token refreshed'); - - return token; - } catch (error) { - this.logger.error({ - localError: AuthService.name + '.refreshToken', - error, - }); - throw new BadRequestException('Invalid "oldToken"'); + return { jwt: token }; + } + + private async apikey(instance: InstanceDto, token?: string) { + const apikey = token ? token : v4().toUpperCase(); + + this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey); + + const auth = await this.repository.auth.create({ apikey }, instance.instanceName); + + this.logger.verbose('APIKEY saved in database'); + + if (auth['error']) { + this.logger.error({ + localError: AuthService.name + '.apikey', + error: auth['error'], + }); + throw new BadRequestException('Authentication error', auth['error']?.toString()); + } + + return { apikey }; + } + + public async checkDuplicateToken(token: string) { + const instances = await this.waMonitor.instanceInfo(); + + this.logger.verbose('checking duplicate token'); + + const instance = instances.find((instance) => instance.instance.apikey === token); + + if (instance) { + throw new BadRequestException('Token already exists'); + } + + this.logger.verbose('available token'); + + return true; + } + + public async generateHash(instance: InstanceDto, token?: string) { + const options = this.configService.get('AUTHENTICATION'); + + this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName); + + return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string }; + } + + public async refreshToken({ oldToken }: OldToken) { + this.logger.verbose('refreshing token'); + + if (!isJWT(oldToken)) { + throw new BadRequestException('Invalid "oldToken"'); + } + + try { + const jwtOpts = this.configService.get('AUTHENTICATION').JWT; + + this.logger.verbose('checking oldToken'); + + const decode = verify(oldToken, jwtOpts.SECRET, { + ignoreExpiration: true, + }) as Pick; + + this.logger.verbose('checking token in database'); + + const tokenStore = await this.repository.auth.find(decode.instanceName); + + const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, { + ignoreExpiration: true, + }) as Pick; + + this.logger.verbose('checking tokenId'); + + if (decode.tokenId !== decodeTokenStore.tokenId) { + throw new BadRequestException('Invalid "oldToken"'); + } + + this.logger.verbose('generating new token'); + + const token = { + jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt, + instanceName: decode.instanceName, + }; + + try { + this.logger.verbose('checking webhook'); + const webhook = await this.repository.webhook.find(decode.instanceName); + if (webhook?.enabled && this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN) { + this.logger.verbose('sending webhook'); + + const httpService = axios.create({ baseURL: webhook.url }); + await httpService.post( + '', + { + event: 'new.jwt', + instance: decode.instanceName, + data: token, + }, + { params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } }, + ); + } + } catch (error) { + this.logger.error(error); + } + + this.logger.verbose('token refreshed'); + + return token; + } catch (error) { + this.logger.error({ + localError: AuthService.name + '.refreshToken', + error, + }); + throw new BadRequestException('Invalid "oldToken"'); + } } - } } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 11a2a78f..48368cb9 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -14,1622 +14,1536 @@ import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto' import { WAMonitoringService } from './monitor.service'; export class ChatwootService { - private messageCacheFile: string; - private messageCache: Set; + private messageCacheFile: string; + private messageCache: Set; - private readonly logger = new Logger(ChatwootService.name); + private readonly logger = new Logger(ChatwootService.name); - private provider: any; + private provider: any; - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - ) { - this.messageCache = new Set(); - } - - private loadMessageCache(): Set { - this.logger.verbose('load message cache'); - try { - const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); - const cacheArray = cacheData.split('\n'); - return new Set(cacheArray); - } catch (error) { - return new Set(); - } - } - - private saveMessageCache() { - this.logger.verbose('save message cache'); - const cacheData = Array.from(this.messageCache).join('\n'); - writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); - this.logger.verbose('message cache saved'); - } - - private clearMessageCache() { - this.logger.verbose('clear message cache'); - this.messageCache.clear(); - this.saveMessageCache(); - } - - private async getProvider(instance: InstanceDto) { - this.logger.verbose('get provider to instance: ' + instance.instanceName); - try { - const provider = await this.waMonitor.waInstances[ - instance.instanceName - ].findChatwoot(); - - if (!provider) { - this.logger.warn('provider not found'); - return null; - } - - this.logger.verbose('provider found'); - - return provider; - } catch (error) { - this.logger.error('provider not found'); - return null; - } - } - - private async clientCw(instance: InstanceDto) { - this.logger.verbose('get client to instance: ' + instance.instanceName); - const provider = await this.getProvider(instance); - - if (!provider) { - this.logger.error('provider not found'); - return null; + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { + this.messageCache = new Set(); } - this.logger.verbose('provider found'); - - this.provider = provider; - - this.logger.verbose('create client to instance: ' + instance.instanceName); - const client = new ChatwootClient({ - config: { - basePath: provider.url, - with_credentials: true, - credentials: 'include', - token: provider.token, - }, - }); - - this.logger.verbose('client created'); - - return client; - } - - public create(instance: InstanceDto, data: ChatwootDto) { - this.logger.verbose('create chatwoot: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); - - this.logger.verbose('chatwoot created'); - return data; - } - - public async find(instance: InstanceDto): Promise { - this.logger.verbose('find chatwoot: ' + instance.instanceName); - try { - return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); - } catch (error) { - this.logger.error('chatwoot not found'); - return { enabled: null, url: '' }; - } - } - - public async getContact(instance: InstanceDto, id: number) { - this.logger.verbose('get contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await client.contact.getContactable({ - accountId: this.provider.account_id, - id, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact found'); - return contact; - } - - public async initInstanceChatwoot( - instance: InstanceDto, - inboxName: string, - webhookUrl: string, - qrcode: boolean, - number: string, - ) { - this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inbox in chatwoot'); - const findInbox: any = await client.inboxes.list({ - accountId: this.provider.account_id, - }); - - this.logger.verbose('check duplicate inbox'); - const checkDuplicate = findInbox.payload - .map((inbox) => inbox.name) - .includes(inboxName); - - let inboxId: number; - - if (!checkDuplicate) { - this.logger.verbose('create inbox in chatwoot'); - const data = { - type: 'api', - webhook_url: webhookUrl, - }; - - const inbox = await client.inboxes.create({ - accountId: this.provider.account_id, - data: { - name: inboxName, - channel: data as any, - }, - }); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } else { - this.logger.verbose('find inbox in chatwoot'); - const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } - - this.logger.verbose('find contact in chatwoot and create if not exists'); - const contact = - (await this.findContact(instance, '123456')) || - ((await this.createContact( - instance, - '123456', - inboxId, - false, - 'EvolutionAPI', - )) as any); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact.id || contact.payload.contact.id; - - if (qrcode) { - this.logger.verbose('create conversation in chatwoot'); - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data: { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('create message for init instance in chatwoot'); - - let contentMsg = '/init'; - - if (number) { - contentMsg = `/init:${number}`; - } - - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: contentMsg, - message_type: 'outgoing', - }, - }); - - if (!message) { - this.logger.warn('conversation not found'); - return null; - } - } - - this.logger.verbose('instance chatwoot initialized'); - return true; - } - - public async createContact( - instance: InstanceDto, - phoneNumber: string, - inboxId: number, - isGroup: boolean, - name?: string, - avatar_url?: string, - ) { - this.logger.verbose('create contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let data: any = {}; - if (!isGroup) { - this.logger.verbose('create contact in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - phone_number: `+${phoneNumber}`, - avatar_url: avatar_url, - }; - } else { - this.logger.verbose('create contact group in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - identifier: phoneNumber, - avatar_url: avatar_url, - }; - } - - this.logger.verbose('create contact in chatwoot'); - const contact = await client.contacts.create({ - accountId: this.provider.account_id, - data, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact created'); - return contact; - } - - public async updateContact(instance: InstanceDto, id: number, data: any) { - this.logger.verbose('update contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('update contact in chatwoot'); - const contact = await client.contacts.update({ - accountId: this.provider.account_id, - id, - data, - }); - - this.logger.verbose('contact updated'); - return contact; - } - - public async findContact(instance: InstanceDto, phoneNumber: string) { - this.logger.verbose('find contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let query: any; - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('format phone number'); - query = `+${phoneNumber}`; - } else { - this.logger.verbose('format group id'); - query = phoneNumber; - } - - this.logger.verbose('find contact in chatwoot'); - const contact: any = await client.contacts.search({ - accountId: this.provider.account_id, - q: query, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('return contact'); - return contact.payload.find((contact) => contact.phone_number === query); - } else { - this.logger.verbose('return group'); - return contact.payload.find((contact) => contact.identifier === query); - } - } - - public async createConversation(instance: InstanceDto, body: any) { - this.logger.verbose('create conversation to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const isGroup = body.key.remoteJid.includes('@g.us'); - - this.logger.verbose('is group: ' + isGroup); - - const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - - this.logger.verbose('chat id: ' + chatId); - - let nameContact: string; - - nameContact = !body.key.fromMe ? body.pushName : chatId; - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - if (isGroup) { - this.logger.verbose('get group name'); - const group = await this.waMonitor.waInstances[ - instance.instanceName - ].client.groupMetadata(chatId); - - nameContact = `${group.subject} (GROUP)`; - - this.logger.verbose('find or create participant in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(body.key.participant.split('@')[0]); - - const findParticipant = await this.findContact( - instance, - body.key.participant.split('@')[0], - ); - - if (findParticipant) { - if (!findParticipant.name || findParticipant.name === chatId) { - await this.updateContact(instance, findParticipant.id, { - name: body.pushName, - avatar_url: picture_url.profilePictureUrl || null, - }); - } - } else { - await this.createContact( - instance, - body.key.participant.split('@')[0], - filterInbox.id, - false, - body.pushName, - picture_url.profilePictureUrl || null, - ); + private loadMessageCache(): Set { + this.logger.verbose('load message cache'); + try { + const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); + const cacheArray = cacheData.split('\n'); + return new Set(cacheArray); + } catch (error) { + return new Set(); } - } - - this.logger.verbose('find or create contact in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(chatId); - - const findContact = await this.findContact(instance, chatId); - - let contact: any; - if (body.key.fromMe) { - if (findContact) { - contact = findContact; - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } else { - if (findContact) { - if (!findContact.name || findContact.name === chatId) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); - } else { - contact = findContact; - } - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = - contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; - - if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { - this.logger.verbose('update contact name in chatwoot'); - await this.updateContact(instance, contactId, { - name: nameContact, - }); - } - - this.logger.verbose('get contact conversations in chatwoot'); - const contactConversations = (await client.contacts.listConversations({ - accountId: this.provider.account_id, - id: contactId, - })) as any; - - if (contactConversations) { - this.logger.verbose('return conversation if exists'); - const conversation = contactConversations.payload.find( - (conversation) => - conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, - ); - if (conversation) { - this.logger.verbose('conversation found'); - return conversation.id; - } - } - - this.logger.verbose('create conversation in chatwoot'); - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data: { - contact_id: `${contactId}`, - inbox_id: `${filterInbox.id}`, - }, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('conversation created'); - return conversation.id; - } catch (error) { - this.logger.error(error); - } - } - - public async getInbox(instance: InstanceDto) { - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; } - this.logger.verbose('find inboxes in chatwoot'); - const inbox = (await client.inboxes.list({ - accountId: this.provider.account_id, - })) as any; - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; + private saveMessageCache() { + this.logger.verbose('save message cache'); + const cacheData = Array.from(this.messageCache).join('\n'); + writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); + this.logger.verbose('message cache saved'); } - this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find( - (inbox) => inbox.name === instance.instanceName, - ); - - if (!findByName) { - this.logger.warn('inbox not found'); - return null; + private clearMessageCache() { + this.logger.verbose('clear message cache'); + this.messageCache.clear(); + this.saveMessageCache(); } - this.logger.verbose('return inbox'); - return findByName; - } - - public async createMessage( - instance: InstanceDto, - conversationId: number, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - privateMessage?: boolean, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create message to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversationId, - data: { - content: content, - message_type: messageType, - attachments: attachments, - private: privateMessage || false, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('message created'); - - return message; - } - - public async createBotMessage( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create bot message to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); - - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', - ); - - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: content, - message_type: messageType, - attachments: attachments, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('bot message created'); - - return message; - } - - private async sendData( - conversationId: number, - file: string, - messageType: 'incoming' | 'outgoing' | undefined, - content?: string, - ) { - this.logger.verbose('send data to chatwoot'); - - const data = new FormData(); - - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } - - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); - - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, - }; - - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - unlinkSync(file); - } - } - - public async createBotQr( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - file?: string, - ) { - this.logger.verbose('create bot qr to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); - - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', - ); - - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } - - this.logger.verbose('send data to chatwoot'); - const data = new FormData(); - - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } - - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); - - if (file) { - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - } - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, - }; - - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - } - } - - public async sendAttachment( - waInstance: any, - number: string, - media: any, - caption?: string, - ) { - this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); - - try { - this.logger.verbose('get media type'); - const parts = media.split('/'); - - const fileName = decodeURIComponent(parts[parts.length - 1]); - this.logger.verbose('file name: ' + fileName); - - const mimeType = mimeTypes.lookup(fileName).toString(); - this.logger.verbose('mime type: ' + mimeType); - - let type = 'document'; - - switch (mimeType.split('/')[0]) { - case 'image': - type = 'image'; - break; - case 'video': - type = 'video'; - break; - case 'audio': - type = 'audio'; - break; - default: - type = 'document'; - break; - } - - this.logger.verbose('type: ' + type); - - if (type === 'audio') { - this.logger.verbose('send audio to instance: ' + waInstance.instanceName); - const data: SendAudioDto = { - number: number, - audioMessage: { - audio: media, - }, - options: { - delay: 1200, - presence: 'recording', - }, - }; - - await waInstance?.audioWhatsapp(data); - - this.logger.verbose('audio sent'); - return; - } - - this.logger.verbose('send media to instance: ' + waInstance.instanceName); - const data: SendMediaDto = { - number: number, - mediaMessage: { - mediatype: type as any, - fileName: fileName, - media: media, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - if (caption) { - this.logger.verbose('caption found'); - data.mediaMessage.caption = caption; - } - - await waInstance?.mediaMessage(data); - - this.logger.verbose('media sent'); - return; - } catch (error) { - this.logger.error(error); - } - } - - public async receiveWebhook(instance: InstanceDto, body: any) { - try { - this.logger.verbose( - 'receive webhook to chatwoot instance: ' + instance.instanceName, - ); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('check if is bot'); - if (!body?.conversation || body.private) return { message: 'bot' }; - - this.logger.verbose('check if is group'); - const chatId = - body.conversation.meta.sender?.phone_number?.replace('+', '') || - body.conversation.meta.sender?.identifier; - const messageReceived = body.content; - const senderName = body?.sender?.name; - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (chatId === '123456' && body.message_type === 'outgoing') { - this.logger.verbose('check if is command'); - - const command = messageReceived.replace('/', ''); - - if (command.includes('init') || command.includes('iniciar')) { - this.logger.verbose('command init found'); - const state = waInstance?.connectionStatus?.state; - - if (state !== 'open') { - this.logger.verbose('connect to whatsapp'); - const number = command.split(':')[1]; - await waInstance.connectToWhatsapp(number); - } else { - this.logger.verbose('whatsapp already connected'); - await this.createBotMessage( - instance, - `🚨 ${body.inbox.name} instance is connected.`, - 'incoming', - ); - } - } - - if (command === 'status') { - this.logger.verbose('command status found'); - - const state = waInstance?.connectionStatus?.state; - - if (!state) { - this.logger.verbose('state not found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance not found.`, - 'incoming', - ); - } - - if (state) { - this.logger.verbose('state: ' + state + ' found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance status: *${state}*`, - 'incoming', - ); - } - } - - if (command === 'disconnect' || command === 'desconectar') { - this.logger.verbose('command disconnect found'); - - const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgLogout, 'incoming'); - - this.logger.verbose('disconnect to whatsapp'); - await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); - await waInstance?.client?.ws?.close(); - } - - if (command.includes('new_instance')) { - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const data = { - instanceName: command.split(':')[1], - qrcode: true, - chatwoot_account_id: this.provider.account_id, - chatwoot_token: this.provider.token, - chatwoot_url: this.provider.url, - chatwoot_sign_msg: this.provider.sign_msg, - }; - - if (command.split(':')[2]) { - data['number'] = command.split(':')[2]; - } - - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: data, - }; - - await axios.request(config); - } - } - - if ( - body.message_type === 'outgoing' && - body?.conversation?.messages?.length && - chatId !== '123456' - ) { - this.logger.verbose('check if is group'); - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - this.logger.verbose('cache file path: ' + this.messageCacheFile); - - this.messageCache = this.loadMessageCache(); - this.logger.verbose('cache file loaded'); - this.logger.verbose(this.messageCache); - - this.logger.verbose('check if message is cached'); - if (this.messageCache.has(body.id.toString())) { - this.logger.verbose('message is cached'); - return { message: 'bot' }; - } - - this.logger.verbose('clear cache'); - this.clearMessageCache(); - - this.logger.verbose('Format message to send'); - let formatText: string; - if (senderName === null || senderName === undefined) { - formatText = messageReceived; - } else { - formatText = this.provider.sign_msg - ? `*${senderName}:*\n\n${messageReceived}` - : messageReceived; - } - - for (const message of body.conversation.messages) { - this.logger.verbose('check if message is media'); - if (message.attachments && message.attachments.length > 0) { - this.logger.verbose('message is media'); - for (const attachment of message.attachments) { - this.logger.verbose('send media to whatsapp'); - if (!messageReceived) { - this.logger.verbose('message do not have text'); - formatText = null; - } - - await this.sendAttachment( - waInstance, - chatId, - attachment.data_url, - formatText, - ); + private async getProvider(instance: InstanceDto) { + this.logger.verbose('get provider to instance: ' + instance.instanceName); + try { + const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + + if (!provider) { + this.logger.warn('provider not found'); + return null; } - } else { - this.logger.verbose('message is text'); - this.logger.verbose('send text to whatsapp'); - const data: SendTextDto = { - number: chatId, - textMessage: { - text: formatText, - }, - options: { - delay: 1200, - presence: 'composing', - }, + this.logger.verbose('provider found'); + + return provider; + } catch (error) { + this.logger.error('provider not found'); + return null; + } + } + + private async clientCw(instance: InstanceDto) { + this.logger.verbose('get client to instance: ' + instance.instanceName); + const provider = await this.getProvider(instance); + + if (!provider) { + this.logger.error('provider not found'); + return null; + } + + this.logger.verbose('provider found'); + + this.provider = provider; + + this.logger.verbose('create client to instance: ' + instance.instanceName); + const client = new ChatwootClient({ + config: { + basePath: provider.url, + with_credentials: true, + credentials: 'include', + token: provider.token, + }, + }); + + this.logger.verbose('client created'); + + return client; + } + + public create(instance: InstanceDto, data: ChatwootDto) { + this.logger.verbose('create chatwoot: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + + this.logger.verbose('chatwoot created'); + return data; + } + + public async find(instance: InstanceDto): Promise { + this.logger.verbose('find chatwoot: ' + instance.instanceName); + try { + return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + } catch (error) { + this.logger.error('chatwoot not found'); + return { enabled: null, url: '' }; + } + } + + public async getContact(instance: InstanceDto, id: number) { + this.logger.verbose('get contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + if (!id) { + this.logger.warn('id is required'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await client.contact.getContactable({ + accountId: this.provider.account_id, + id, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('contact found'); + return contact; + } + + public async initInstanceChatwoot( + instance: InstanceDto, + inboxName: string, + webhookUrl: string, + qrcode: boolean, + number: string, + ) { + this.logger.verbose('init instance chatwoot: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find inbox in chatwoot'); + const findInbox: any = await client.inboxes.list({ + accountId: this.provider.account_id, + }); + + this.logger.verbose('check duplicate inbox'); + const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); + + let inboxId: number; + + if (!checkDuplicate) { + this.logger.verbose('create inbox in chatwoot'); + const data = { + type: 'api', + webhook_url: webhookUrl, }; - await waInstance?.textMessage(data); - } - } - } + const inbox = await client.inboxes.create({ + accountId: this.provider.account_id, + data: { + name: inboxName, + channel: data as any, + }, + }); - if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is csat'); - - const data: SendTextDto = { - number: chatId, - textMessage: { - text: body.content, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - this.logger.verbose('send text to whatsapp'); - - await waInstance?.textMessage(data); - } - - return { message: 'bot' }; - } catch (error) { - this.logger.error(error); - - return { message: 'bot' }; - } - } - - private isMediaMessage(message: any) { - this.logger.verbose('check if is media message'); - const media = [ - 'imageMessage', - 'documentMessage', - 'documentWithCaptionMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', - ]; - - const messageKeys = Object.keys(message); - - const result = messageKeys.some((key) => media.includes(key)); - - this.logger.verbose('is media message: ' + result); - return result; - } - - private getTypeMessage(msg: any) { - this.logger.verbose('get type message'); - - const types = { - conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, - extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: msg.stickerMessage?.fileSha256.toString('base64'), - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: - msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, - }; - - this.logger.verbose('type message: ' + types); - - return types; - } - - private getMessageContent(types: any) { - this.logger.verbose('get message content'); - const typeKey = Object.keys(types).find((key) => types[key] !== undefined); - - const result = typeKey ? types[typeKey] : undefined; - - if (typeKey === 'stickerMessage') { - return null; - } - - if (typeKey === 'contactMessage') { - const vCardData = result.split('\n'); - const contactInfo = {}; - - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); - - let formattedContact = `**Contact:** - **name:** ${contactInfo['FN']}`; - - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); - - this.logger.verbose('message content: ' + formattedContact); - return formattedContact; - } - - if (typeKey === 'contactsArrayMessage') { - const formattedContacts = result.contacts.map((contact) => { - const vCardData = contact.vcard.split('\n'); - const contactInfo = {}; - - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); - - let formattedContact = `**Contact:** - **name:** ${contact.displayName}`; - - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); - - return formattedContact; - }); - - const formattedContactsArray = formattedContacts.join('\n\n'); - - this.logger.verbose('formatted contacts: ' + formattedContactsArray); - - return formattedContactsArray; - } - - this.logger.verbose('message content: ' + result); - - return result; - } - - private getConversationMessage(msg: any) { - this.logger.verbose('get conversation message'); - - const types = this.getTypeMessage(msg); - - const messageContent = this.getMessageContent(types); - - this.logger.verbose('conversation message: ' + messageContent); - - return messageContent; - } - - public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { - this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (!waInstance) { - this.logger.warn('wa instance not found'); - return null; - } - - if (event === 'messages.upsert') { - this.logger.verbose('event messages.upsert'); - - if (body.key.remoteJid === 'status@broadcast') { - this.logger.verbose('status broadcast found'); - return; - } - - this.logger.verbose('get conversation message'); - const bodyMessage = await this.getConversationMessage(body.message); - - const isMedia = this.isMediaMessage(body.message); - - if (!bodyMessage && !isMedia) { - this.logger.warn('no body message found'); - return; - } - - this.logger.verbose('get conversation in chatwoot'); - const getConversion = await this.createConversation(instance, body); - - if (!getConversion) { - this.logger.warn('conversation not found'); - return; - } - - const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; - - this.logger.verbose('message type: ' + messageType); - - this.logger.verbose('is media: ' + isMedia); - - this.logger.verbose('check if is media'); - if (isMedia) { - this.logger.verbose('message is media'); - - this.logger.verbose('get base64 from media message'); - const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ - message: { - ...body, - }, - }); - - const random = Math.random().toString(36).substring(7); - const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; - - const fileData = Buffer.from(downloadBase64.base64, 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; - - this.logger.verbose('temp file name: ' + nameFile); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; + if (!inbox) { + this.logger.warn('inbox not found'); + return null; } - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - content, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - bodyMessage, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - content, - messageType, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; + inboxId = inbox.id; } else { - this.logger.verbose('message is not group'); + this.logger.verbose('find inbox in chatwoot'); + const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - bodyMessage, - messageType, - ); + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; + inboxId = inbox.id; } - } - if (event === 'status.instance') { - this.logger.verbose('event status.instance'); - const data = body; - const inbox = await this.getInbox(instance); + this.logger.verbose('find contact in chatwoot and create if not exists'); + const contact = + (await this.findContact(instance, '123456')) || + ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = contact.id || contact.payload.contact.id; + + if (qrcode) { + this.logger.verbose('create conversation in chatwoot'); + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data: { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('create message for init instance in chatwoot'); + + let contentMsg = '/init'; + + if (number) { + contentMsg = `/init:${number}`; + } + + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: contentMsg, + message_type: 'outgoing', + }, + }); + + if (!message) { + this.logger.warn('conversation not found'); + return null; + } + } + + this.logger.verbose('instance chatwoot initialized'); + return true; + } + + public async createContact( + instance: InstanceDto, + phoneNumber: string, + inboxId: number, + isGroup: boolean, + name?: string, + avatar_url?: string, + ) { + this.logger.verbose('create contact to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + let data: any = {}; + if (!isGroup) { + this.logger.verbose('create contact in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + phone_number: `+${phoneNumber}`, + avatar_url: avatar_url, + }; + } else { + this.logger.verbose('create contact group in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + identifier: phoneNumber, + avatar_url: avatar_url, + }; + } + + this.logger.verbose('create contact in chatwoot'); + const contact = await client.contacts.create({ + accountId: this.provider.account_id, + data, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('contact created'); + return contact; + } + + public async updateContact(instance: InstanceDto, id: number, data: any) { + this.logger.verbose('update contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + if (!id) { + this.logger.warn('id is required'); + return null; + } + + this.logger.verbose('update contact in chatwoot'); + const contact = await client.contacts.update({ + accountId: this.provider.account_id, + id, + data, + }); + + this.logger.verbose('contact updated'); + return contact; + } + + public async findContact(instance: InstanceDto, phoneNumber: string) { + this.logger.verbose('find contact to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + let query: any; + + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('format phone number'); + query = `+${phoneNumber}`; + } else { + this.logger.verbose('format group id'); + query = phoneNumber; + } + + this.logger.verbose('find contact in chatwoot'); + const contact: any = await client.contacts.search({ + accountId: this.provider.account_id, + q: query, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('return contact'); + return contact.payload.find((contact) => contact.phone_number === query); + } else { + this.logger.verbose('return group'); + return contact.payload.find((contact) => contact.identifier === query); + } + } + + public async createConversation(instance: InstanceDto, body: any) { + this.logger.verbose('create conversation to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + const isGroup = body.key.remoteJid.includes('@g.us'); + + this.logger.verbose('is group: ' + isGroup); + + const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; + + this.logger.verbose('chat id: ' + chatId); + + let nameContact: string; + + nameContact = !body.key.fromMe ? body.pushName : chatId; + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + if (isGroup) { + this.logger.verbose('get group name'); + const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); + + nameContact = `${group.subject} (GROUP)`; + + this.logger.verbose('find or create participant in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( + body.key.participant.split('@')[0], + ); + + const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); + + if (findParticipant) { + if (!findParticipant.name || findParticipant.name === chatId) { + await this.updateContact(instance, findParticipant.id, { + name: body.pushName, + avatar_url: picture_url.profilePictureUrl || null, + }); + } + } else { + await this.createContact( + instance, + body.key.participant.split('@')[0], + filterInbox.id, + false, + body.pushName, + picture_url.profilePictureUrl || null, + ); + } + } + + this.logger.verbose('find or create contact in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); + + const findContact = await this.findContact(instance, chatId); + + let contact: any; + if (body.key.fromMe) { + if (findContact) { + contact = findContact; + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } else { + if (findContact) { + if (!findContact.name || findContact.name === chatId) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = findContact; + } + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; + + if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { + this.logger.verbose('update contact name in chatwoot'); + await this.updateContact(instance, contactId, { + name: nameContact, + }); + } + + this.logger.verbose('get contact conversations in chatwoot'); + const contactConversations = (await client.contacts.listConversations({ + accountId: this.provider.account_id, + id: contactId, + })) as any; + + if (contactConversations) { + this.logger.verbose('return conversation if exists'); + const conversation = contactConversations.payload.find( + (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, + ); + if (conversation) { + this.logger.verbose('conversation found'); + return conversation.id; + } + } + + this.logger.verbose('create conversation in chatwoot'); + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data: { + contact_id: `${contactId}`, + inbox_id: `${filterInbox.id}`, + }, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('conversation created'); + return conversation.id; + } catch (error) { + this.logger.error(error); + } + } + + public async getInbox(instance: InstanceDto) { + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find inboxes in chatwoot'); + const inbox = (await client.inboxes.list({ + accountId: this.provider.account_id, + })) as any; if (!inbox) { - this.logger.warn('inbox not found'); - return; + this.logger.warn('inbox not found'); + return null; } - const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; + this.logger.verbose('find inbox by name'); + const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgStatus, 'incoming'); - } - - if (event === 'connection.update') { - this.logger.verbose('event connection.update'); - - if (body.status === 'open') { - const msgConnection = `🚀 Connection successfully established!`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgConnection, 'incoming'); + if (!findByName) { + this.logger.warn('inbox not found'); + return null; } - } - if (event === 'qrcode.updated') { - this.logger.verbose('event qrcode.updated'); - if (body.statusCode === 500) { - this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; - - this.logger.verbose('send message to chatwoot'); - return await this.createBotMessage(instance, erroQRcode, 'incoming'); - } else { - this.logger.verbose('qrcode success'); - const fileData = Buffer.from( - body?.qrcode.base64.replace('data:image/png;base64,', ''), - 'base64', - ); - - const fileName = `${path.join( - waInstance?.storePath, - 'temp', - `${`${instance}.png`}`, - )}`; - - this.logger.verbose('temp file name: ' + fileName); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr( - instance, - 'QRCode successfully generated!', - 'incoming', - fileName, - ); - - let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; - - if (body?.qrcode?.pairingCode) { - msgQrCode = - msgQrCode + - `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( - 0, - 4, - )}-${body.qrcode.pairingCode.substring(4, 8)}`; - } - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgQrCode, 'incoming'); - } - } - } catch (error) { - this.logger.error(error); + this.logger.verbose('return inbox'); + return findByName; } - } - public async newInstance(data: any) { - try { - const instanceName = data.instanceName; - const qrcode = true; - const number = data.number; - const accountId = data.accountId; - const chatwootToken = data.token; - const chatwootUrl = data.url; - const signMsg = true; - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + public async createMessage( + instance: InstanceDto, + conversationId: number, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + privateMessage?: boolean, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create message to instance: ' + instance.instanceName); - const requestData = { - instanceName, - qrcode, - chatwoot_account_id: accountId, - chatwoot_token: chatwootToken, - chatwoot_url: chatwootUrl, - chatwoot_sign_msg: signMsg, - }; + const client = await this.clientCw(instance); - if (number) { - requestData['number'] = number; - } + if (!client) { + this.logger.warn('client not found'); + return null; + } - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: requestData, - }; + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversationId, + data: { + content: content, + message_type: messageType, + attachments: attachments, + private: privateMessage || false, + }, + }); - // await axios.request(config); + if (!message) { + this.logger.warn('message not found'); + return null; + } - return true; - } catch (error) { - this.logger.error(error); - return null; + this.logger.verbose('message created'); + + return message; + } + + public async createBotMessage( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create bot message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: content, + message_type: messageType, + attachments: attachments, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('bot message created'); + + return message; + } + + private async sendData( + conversationId: number, + file: string, + messageType: 'incoming' | 'outgoing' | undefined, + content?: string, + ) { + this.logger.verbose('send data to chatwoot'); + + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + unlinkSync(file); + } + } + + public async createBotQr( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + file?: string, + ) { + this.logger.verbose('create bot qr to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('send data to chatwoot'); + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + if (file) { + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + } + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + } + } + + public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { + this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); + + try { + this.logger.verbose('get media type'); + const parts = media.split('/'); + + const fileName = decodeURIComponent(parts[parts.length - 1]); + this.logger.verbose('file name: ' + fileName); + + const mimeType = mimeTypes.lookup(fileName).toString(); + this.logger.verbose('mime type: ' + mimeType); + + let type = 'document'; + + switch (mimeType.split('/')[0]) { + case 'image': + type = 'image'; + break; + case 'video': + type = 'video'; + break; + case 'audio': + type = 'audio'; + break; + default: + type = 'document'; + break; + } + + this.logger.verbose('type: ' + type); + + if (type === 'audio') { + this.logger.verbose('send audio to instance: ' + waInstance.instanceName); + const data: SendAudioDto = { + number: number, + audioMessage: { + audio: media, + }, + options: { + delay: 1200, + presence: 'recording', + }, + }; + + await waInstance?.audioWhatsapp(data); + + this.logger.verbose('audio sent'); + return; + } + + this.logger.verbose('send media to instance: ' + waInstance.instanceName); + const data: SendMediaDto = { + number: number, + mediaMessage: { + mediatype: type as any, + fileName: fileName, + media: media, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + if (caption) { + this.logger.verbose('caption found'); + data.mediaMessage.caption = caption; + } + + await waInstance?.mediaMessage(data); + + this.logger.verbose('media sent'); + return; + } catch (error) { + this.logger.error(error); + } + } + + public async receiveWebhook(instance: InstanceDto, body: any) { + try { + this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('check if is bot'); + if (!body?.conversation || body.private) return { message: 'bot' }; + + this.logger.verbose('check if is group'); + const chatId = + body.conversation.meta.sender?.phone_number?.replace('+', '') || + body.conversation.meta.sender?.identifier; + const messageReceived = body.content; + const senderName = body?.sender?.name; + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (chatId === '123456' && body.message_type === 'outgoing') { + this.logger.verbose('check if is command'); + + const command = messageReceived.replace('/', ''); + + if (command.includes('init') || command.includes('iniciar')) { + this.logger.verbose('command init found'); + const state = waInstance?.connectionStatus?.state; + + if (state !== 'open') { + this.logger.verbose('connect to whatsapp'); + const number = command.split(':')[1]; + await waInstance.connectToWhatsapp(number); + } else { + this.logger.verbose('whatsapp already connected'); + await this.createBotMessage( + instance, + `🚨 ${body.inbox.name} instance is connected.`, + 'incoming', + ); + } + } + + if (command === 'status') { + this.logger.verbose('command status found'); + + const state = waInstance?.connectionStatus?.state; + + if (!state) { + this.logger.verbose('state not found'); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); + } + + if (state) { + this.logger.verbose('state: ' + state + ' found'); + await this.createBotMessage( + instance, + `⚠️ ${body.inbox.name} instance status: *${state}*`, + 'incoming', + ); + } + } + + if (command === 'disconnect' || command === 'desconectar') { + this.logger.verbose('command disconnect found'); + + const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgLogout, 'incoming'); + + this.logger.verbose('disconnect to whatsapp'); + await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); + await waInstance?.client?.ws?.close(); + } + + if (command.includes('new_instance')) { + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const data = { + instanceName: command.split(':')[1], + qrcode: true, + chatwoot_account_id: this.provider.account_id, + chatwoot_token: this.provider.token, + chatwoot_url: this.provider.url, + chatwoot_sign_msg: this.provider.sign_msg, + }; + + if (command.split(':')[2]) { + data['number'] = command.split(':')[2]; + } + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: data, + }; + + await axios.request(config); + } + } + + if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { + this.logger.verbose('check if is group'); + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + this.logger.verbose('cache file path: ' + this.messageCacheFile); + + this.messageCache = this.loadMessageCache(); + this.logger.verbose('cache file loaded'); + this.logger.verbose(this.messageCache); + + this.logger.verbose('check if message is cached'); + if (this.messageCache.has(body.id.toString())) { + this.logger.verbose('message is cached'); + return { message: 'bot' }; + } + + this.logger.verbose('clear cache'); + this.clearMessageCache(); + + this.logger.verbose('Format message to send'); + let formatText: string; + if (senderName === null || senderName === undefined) { + formatText = messageReceived; + } else { + formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; + } + + for (const message of body.conversation.messages) { + this.logger.verbose('check if message is media'); + if (message.attachments && message.attachments.length > 0) { + this.logger.verbose('message is media'); + for (const attachment of message.attachments) { + this.logger.verbose('send media to whatsapp'); + if (!messageReceived) { + this.logger.verbose('message do not have text'); + formatText = null; + } + + await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); + } + } else { + this.logger.verbose('message is text'); + + this.logger.verbose('send text to whatsapp'); + const data: SendTextDto = { + number: chatId, + textMessage: { + text: formatText, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + await waInstance?.textMessage(data); + } + } + } + + if (body.message_type === 'template' && body.event === 'message_created') { + this.logger.verbose('check if is csat'); + + const data: SendTextDto = { + number: chatId, + textMessage: { + text: body.content, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + this.logger.verbose('send text to whatsapp'); + + await waInstance?.textMessage(data); + } + + return { message: 'bot' }; + } catch (error) { + this.logger.error(error); + + return { message: 'bot' }; + } + } + + private isMediaMessage(message: any) { + this.logger.verbose('check if is media message'); + const media = [ + 'imageMessage', + 'documentMessage', + 'documentWithCaptionMessage', + 'audioMessage', + 'videoMessage', + 'stickerMessage', + ]; + + const messageKeys = Object.keys(message); + + const result = messageKeys.some((key) => media.includes(key)); + + this.logger.verbose('is media message: ' + result); + return result; + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + imageMessage: msg.imageMessage?.caption, + videoMessage: msg.videoMessage?.caption, + extendedTextMessage: msg.extendedTextMessage?.text, + messageContextInfo: msg.messageContextInfo?.stanzaId, + stickerMessage: msg.stickerMessage?.fileSha256.toString('base64'), + documentMessage: msg.documentMessage?.caption, + documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + if (typeKey === 'stickerMessage') { + return null; + } + + if (typeKey === 'contactMessage') { + const vCardData = result.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + let formattedContact = `**Contact:** + **name:** ${contactInfo['FN']}`; + + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); + + this.logger.verbose('message content: ' + formattedContact); + return formattedContact; + } + + if (typeKey === 'contactsArrayMessage') { + const formattedContacts = result.contacts.map((contact) => { + const vCardData = contact.vcard.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + let formattedContact = `**Contact:** + **name:** ${contact.displayName}`; + + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); + + return formattedContact; + }); + + const formattedContactsArray = formattedContacts.join('\n\n'); + + this.logger.verbose('formatted contacts: ' + formattedContactsArray); + + return formattedContactsArray; + } + + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { + this.logger.verbose('get conversation message'); + + const types = this.getTypeMessage(msg); + + const messageContent = this.getMessageContent(types); + + this.logger.verbose('conversation message: ' + messageContent); + + return messageContent; + } + + public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { + this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (!waInstance) { + this.logger.warn('wa instance not found'); + return null; + } + + if (event === 'messages.upsert') { + this.logger.verbose('event messages.upsert'); + + if (body.key.remoteJid === 'status@broadcast') { + this.logger.verbose('status broadcast found'); + return; + } + + this.logger.verbose('get conversation message'); + const bodyMessage = await this.getConversationMessage(body.message); + + const isMedia = this.isMediaMessage(body.message); + + if (!bodyMessage && !isMedia) { + this.logger.warn('no body message found'); + return; + } + + this.logger.verbose('get conversation in chatwoot'); + const getConversion = await this.createConversation(instance, body); + + if (!getConversion) { + this.logger.warn('conversation not found'); + return; + } + + const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; + + this.logger.verbose('message type: ' + messageType); + + this.logger.verbose('is media: ' + isMedia); + + this.logger.verbose('check if is media'); + if (isMedia) { + this.logger.verbose('message is media'); + + this.logger.verbose('get base64 from media message'); + const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ + message: { + ...body, + }, + }); + + const random = Math.random().toString(36).substring(7); + const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; + + const fileData = Buffer.from(downloadBase64.base64, 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; + + this.logger.verbose('temp file name: ' + nameFile); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, content); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, content, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + if (event === 'status.instance') { + this.logger.verbose('event status.instance'); + const data = body; + const inbox = await this.getInbox(instance); + + if (!inbox) { + this.logger.warn('inbox not found'); + return; + } + + const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgStatus, 'incoming'); + } + + if (event === 'connection.update') { + this.logger.verbose('event connection.update'); + + if (body.status === 'open') { + const msgConnection = `🚀 Connection successfully established!`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgConnection, 'incoming'); + } + } + + if (event === 'qrcode.updated') { + this.logger.verbose('event qrcode.updated'); + if (body.statusCode === 500) { + this.logger.verbose('qrcode error'); + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; + + this.logger.verbose('send message to chatwoot'); + return await this.createBotMessage(instance, erroQRcode, 'incoming'); + } else { + this.logger.verbose('qrcode success'); + const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; + + this.logger.verbose('temp file name: ' + fileName); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('send qrcode to chatwoot'); + await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); + + let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + + if (body?.qrcode?.pairingCode) { + msgQrCode = + msgQrCode + + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( + 0, + 4, + )}-${body.qrcode.pairingCode.substring(4, 8)}`; + } + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgQrCode, 'incoming'); + } + } + } catch (error) { + this.logger.error(error); + } + } + + public async newInstance(data: any) { + try { + const instanceName = data.instanceName; + const qrcode = true; + const number = data.number; + const accountId = data.accountId; + const chatwootToken = data.token; + const chatwootUrl = data.url; + const signMsg = true; + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const requestData = { + instanceName, + qrcode, + chatwoot_account_id: accountId, + chatwoot_token: chatwootToken, + chatwoot_url: chatwootUrl, + chatwoot_sign_msg: signMsg, + }; + + if (number) { + requestData['number'] = number; + } + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: requestData, + }; + + // await axios.request(config); + + return true; + } catch (error) { + this.logger.error(error); + return null; + } } - } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index afeeb872..1108d77c 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -5,380 +5,351 @@ import { Db } from 'mongodb'; import mongoose from 'mongoose'; import { join } from 'path'; -import { - Auth, - ConfigService, - Database, - DelInstance, - HttpServer, - Redis, -} from '../../config/env.config'; +import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; import { RedisCache } from '../../db/redis.client'; import { NotFoundException } from '../../exceptions'; import { - AuthModel, - ChatwootModel, - ContactModel, - MessageModel, - MessageUpModel, - SettingsModel, - WebhookModel, + AuthModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + SettingsModel, + WebhookModel, } from '../models'; import { RepositoryBroker } from '../repository/repository.manager'; import { WAStartupService } from './whatsapp.service'; export class WAMonitoringService { - constructor( - private readonly eventEmitter: EventEmitter2, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('instance created'); + constructor( + private readonly eventEmitter: EventEmitter2, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('instance created'); - this.removeInstance(); - this.noConnection(); - this.delInstanceFiles(); + this.removeInstance(); + this.noConnection(); + this.delInstanceFiles(); - Object.assign(this.db, configService.get('DATABASE')); - Object.assign(this.redis, configService.get('REDIS')); + Object.assign(this.db, configService.get('DATABASE')); + Object.assign(this.redis, configService.get('REDIS')); - this.dbInstance = this.db.ENABLED - ? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances') - : undefined; - } - - private readonly db: Partial = {}; - private readonly redis: Partial = {}; - - private dbInstance: Db; - - private dbStore = dbserver; - - private readonly logger = new Logger(WAMonitoringService.name); - public readonly waInstances: Record = {}; - - public delInstanceTime(instance: string) { - const time = this.configService.get('DEL_INSTANCE'); - if (typeof time === 'number' && time > 0) { - this.logger.verbose( - `Instance "${instance}" don't have connection, will be removed in ${time} minutes`, - ); - - setTimeout(async () => { - if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { - if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { - await this.waInstances[instance]?.client?.logout( - 'Log out instance: ' + instance, - ); - this.waInstances[instance]?.client?.ws?.close(); - this.waInstances[instance]?.client?.end(undefined); - delete this.waInstances[instance]; - } else { - delete this.waInstances[instance]; - this.eventEmitter.emit('remove.instance', instance, 'inner'); - } - } - }, 1000 * 60 * time); - } - } - - public async instanceInfo(instanceName?: string) { - this.logger.verbose('get instance info'); - if (instanceName && !this.waInstances[instanceName]) { - throw new NotFoundException(`Instance "${instanceName}" not found`); + this.dbInstance = this.db.ENABLED + ? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances') + : undefined; } - const instances: any[] = []; + private readonly db: Partial = {}; + private readonly redis: Partial = {}; - for await (const [key, value] of Object.entries(this.waInstances)) { - if (value) { - this.logger.verbose('get instance info: ' + key); - let chatwoot: any; + private dbInstance: Db; - const urlServer = this.configService.get('SERVER').URL; + private dbStore = dbserver; - const findChatwoot = await this.waInstances[key].findChatwoot(); + private readonly logger = new Logger(WAMonitoringService.name); + public readonly waInstances: Record = {}; - if (findChatwoot && findChatwoot.enabled) { - chatwoot = { - ...findChatwoot, - webhook_url: `${urlServer}/chatwoot/webhook/${key}`, - }; + public delInstanceTime(instance: string) { + const time = this.configService.get('DEL_INSTANCE'); + if (typeof time === 'number' && time > 0) { + this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`); + + setTimeout(async () => { + if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { + if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { + await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance); + this.waInstances[instance]?.client?.ws?.close(); + this.waInstances[instance]?.client?.end(undefined); + delete this.waInstances[instance]; + } else { + delete this.waInstances[instance]; + this.eventEmitter.emit('remove.instance', instance, 'inner'); + } + } + }, 1000 * 60 * time); } - - if (value.connectionStatus.state === 'open') { - this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); - - const instanceData = { - instance: { - instanceName: key, - owner: value.wuid, - profileName: (await value.getProfileName()) || 'not loaded', - profilePictureUrl: value.profilePictureUrl, - profileStatus: (await value.getProfileStatus()) || '', - status: value.connectionStatus.state, - }, - }; - - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = - this.configService.get('SERVER').URL; - - instanceData.instance['apikey'] = ( - await this.repository.auth.find(key) - ).apikey; - - instanceData.instance['chatwoot'] = chatwoot; - } - - instances.push(instanceData); - } else { - this.logger.verbose( - 'instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state, - ); - - const instanceData = { - instance: { - instanceName: key, - status: value.connectionStatus.state, - }, - }; - - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = - this.configService.get('SERVER').URL; - - instanceData.instance['apikey'] = ( - await this.repository.auth.find(key) - ).apikey; - - instanceData.instance['chatwoot'] = chatwoot; - } - - instances.push(instanceData); - } - } } - this.logger.verbose('return instance info: ' + instances.length); + public async instanceInfo(instanceName?: string) { + this.logger.verbose('get instance info'); + if (instanceName && !this.waInstances[instanceName]) { + throw new NotFoundException(`Instance "${instanceName}" not found`); + } - return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; - } + const instances: any[] = []; - private delInstanceFiles() { - this.logger.verbose('cron to delete instance files started'); - setInterval(async () => { - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - const collections = await this.dbInstance.collections(); - collections.forEach(async (collection) => { - const name = collection.namespace.replace(/^[\w-]+./, ''); - await this.dbInstance.collection(name).deleteMany({ - $or: [ - { _id: { $regex: /^app.state.*/ } }, - { _id: { $regex: /^session-.*/ } }, - ], - }); - this.logger.verbose('instance files deleted: ' + name); - }); - // } else if (this.redis.ENABLED) { - } else { - const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); - for await (const dirent of dir) { - if (dirent.isDirectory()) { - const files = readdirSync(join(INSTANCE_DIR, dirent.name), { - encoding: 'utf-8', - }); - files.forEach(async (file) => { - if (file.match(/^app.state.*/) || file.match(/^session-.*/)) { - rmSync(join(INSTANCE_DIR, dirent.name, file), { - recursive: true, - force: true, + for await (const [key, value] of Object.entries(this.waInstances)) { + if (value) { + this.logger.verbose('get instance info: ' + key); + let chatwoot: any; + + const urlServer = this.configService.get('SERVER').URL; + + const findChatwoot = await this.waInstances[key].findChatwoot(); + + if (findChatwoot && findChatwoot.enabled) { + chatwoot = { + ...findChatwoot, + webhook_url: `${urlServer}/chatwoot/webhook/${key}`, + }; + } + + if (value.connectionStatus.state === 'open') { + this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); + + const instanceData = { + instance: { + instanceName: key, + owner: value.wuid, + profileName: (await value.getProfileName()) || 'not loaded', + profilePictureUrl: value.profilePictureUrl, + profileStatus: (await value.getProfileStatus()) || '', + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } else { + this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state); + + const instanceData = { + instance: { + instanceName: key, + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } + } + } + + this.logger.verbose('return instance info: ' + instances.length); + + return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; + } + + private delInstanceFiles() { + this.logger.verbose('cron to delete instance files started'); + setInterval(async () => { + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + const collections = await this.dbInstance.collections(); + collections.forEach(async (collection) => { + const name = collection.namespace.replace(/^[\w-]+./, ''); + await this.dbInstance.collection(name).deleteMany({ + $or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }], + }); + this.logger.verbose('instance files deleted: ' + name); }); - } - }); - this.logger.verbose('instance files deleted: ' + dirent.name); - } + // } else if (this.redis.ENABLED) { + } else { + const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); + for await (const dirent of dir) { + if (dirent.isDirectory()) { + const files = readdirSync(join(INSTANCE_DIR, dirent.name), { + encoding: 'utf-8', + }); + files.forEach(async (file) => { + if (file.match(/^app.state.*/) || file.match(/^session-.*/)) { + rmSync(join(INSTANCE_DIR, dirent.name, file), { + recursive: true, + force: true, + }); + } + }); + this.logger.verbose('instance files deleted: ' + dirent.name); + } + } + } + }, 3600 * 1000 * 2); + } + + public async cleaningUp(instanceName: string) { + this.logger.verbose('cleaning up instance: ' + instanceName); + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + this.logger.verbose('cleaning up instance in database: ' + instanceName); + await this.repository.dbServer.connect(); + const collections: any[] = await this.dbInstance.collections(); + if (collections.length > 0) { + await this.dbInstance.dropCollection(instanceName); + } + return; } - } - }, 3600 * 1000 * 2); - } - public async cleaningUp(instanceName: string) { - this.logger.verbose('cleaning up instance: ' + instanceName); - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - this.logger.verbose('cleaning up instance in database: ' + instanceName); - await this.repository.dbServer.connect(); - const collections: any[] = await this.dbInstance.collections(); - if (collections.length > 0) { - await this.dbInstance.dropCollection(instanceName); - } - return; - } - - if (this.redis.ENABLED) { - this.logger.verbose('cleaning up instance in redis: ' + instanceName); - this.cache.reference = instanceName; - await this.cache.delAll(); - return; - } - - this.logger.verbose('cleaning up instance in files: ' + instanceName); - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); - } - - public async cleaningStoreFiles(instanceName: string) { - if (!this.db.ENABLED) { - this.logger.verbose('cleaning store files instance: ' + instanceName); - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); - - execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`); - - execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); - - return; - } - - this.logger.verbose('cleaning store database instance: ' + instanceName); - - await AuthModel.deleteMany({ owner: instanceName }); - await ContactModel.deleteMany({ owner: instanceName }); - await MessageModel.deleteMany({ owner: instanceName }); - await MessageUpModel.deleteMany({ owner: instanceName }); - await AuthModel.deleteMany({ _id: instanceName }); - await WebhookModel.deleteMany({ _id: instanceName }); - await ChatwootModel.deleteMany({ _id: instanceName }); - await SettingsModel.deleteMany({ _id: instanceName }); - - return; - } - - public async loadInstance() { - this.logger.verbose('load instances'); - const set = async (name: string) => { - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = name; - this.logger.verbose('instance loaded: ' + name); - - await instance.connectToWhatsapp(); - this.logger.verbose('connectToWhatsapp: ' + name); - - this.waInstances[name] = instance; - }; - - try { - if (this.redis.ENABLED) { - this.logger.verbose('redis enabled'); - await this.cache.connect(this.redis as Redis); - const keys = await this.cache.instanceKeys(); - if (keys?.length > 0) { - this.logger.verbose('reading instance keys and setting instances'); - keys.forEach(async (k) => await set(k.split(':')[1])); - } else { - this.logger.verbose('no instance keys found'); + if (this.redis.ENABLED) { + this.logger.verbose('cleaning up instance in redis: ' + instanceName); + this.cache.reference = instanceName; + await this.cache.delAll(); + return; } + + this.logger.verbose('cleaning up instance in files: ' + instanceName); + rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + } + + public async cleaningStoreFiles(instanceName: string) { + if (!this.db.ENABLED) { + this.logger.verbose('cleaning store files instance: ' + instanceName); + rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + + execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`); + + execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); + execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); + execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); + + return; + } + + this.logger.verbose('cleaning store database instance: ' + instanceName); + + await AuthModel.deleteMany({ owner: instanceName }); + await ContactModel.deleteMany({ owner: instanceName }); + await MessageModel.deleteMany({ owner: instanceName }); + await MessageUpModel.deleteMany({ owner: instanceName }); + await AuthModel.deleteMany({ _id: instanceName }); + await WebhookModel.deleteMany({ _id: instanceName }); + await ChatwootModel.deleteMany({ _id: instanceName }); + await SettingsModel.deleteMany({ _id: instanceName }); + return; - } - - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - this.logger.verbose('database enabled'); - await this.repository.dbServer.connect(); - const collections: any[] = await this.dbInstance.collections(); - if (collections.length > 0) { - this.logger.verbose('reading collections and setting instances'); - collections.forEach( - async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, '')), - ); - } else { - this.logger.verbose('no collections found'); - } - return; - } - - this.logger.verbose('store in files enabled'); - const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); - for await (const dirent of dir) { - if (dirent.isDirectory()) { - this.logger.verbose('reading instance files and setting instances'); - const files = readdirSync(join(INSTANCE_DIR, dirent.name), { - encoding: 'utf-8', - }); - if (files.length === 0) { - rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true }); - break; - } - - await set(dirent.name); - } else { - this.logger.verbose('no instance files found'); - } - } - } catch (error) { - this.logger.error(error); } - } - private removeInstance() { - this.eventEmitter.on('remove.instance', async (instanceName: string) => { - this.logger.verbose('remove instance: ' + instanceName); - try { - this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); - this.waInstances[instanceName] = undefined; - } catch (error) { - this.logger.error(error); - } + public async loadInstance() { + this.logger.verbose('load instances'); + const set = async (name: string) => { + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); + instance.instanceName = name; + this.logger.verbose('instance loaded: ' + name); - try { - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - this.cleaningStoreFiles(instanceName); - } finally { - this.logger.warn(`Instance "${instanceName}" - REMOVED`); - } - }); - this.eventEmitter.on('logout.instance', async (instanceName: string) => { - this.logger.verbose('logout instance: ' + instanceName); - try { - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - } finally { - this.logger.warn(`Instance "${instanceName}" - LOGOUT`); - } - }); - } + await instance.connectToWhatsapp(); + this.logger.verbose('connectToWhatsapp: ' + name); - private noConnection() { - this.logger.verbose('checking instances without connection'); - this.eventEmitter.on('no.connection', async (instanceName) => { - try { - this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); - this.waInstances[instanceName] = undefined; + this.waInstances[name] = instance; + }; - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - } catch (error) { - this.logger.error({ - localError: 'noConnection', - warn: 'Error deleting instance from memory.', - error, + try { + if (this.redis.ENABLED) { + this.logger.verbose('redis enabled'); + await this.cache.connect(this.redis as Redis); + const keys = await this.cache.instanceKeys(); + if (keys?.length > 0) { + this.logger.verbose('reading instance keys and setting instances'); + keys.forEach(async (k) => await set(k.split(':')[1])); + } else { + this.logger.verbose('no instance keys found'); + } + return; + } + + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + this.logger.verbose('database enabled'); + await this.repository.dbServer.connect(); + const collections: any[] = await this.dbInstance.collections(); + if (collections.length > 0) { + this.logger.verbose('reading collections and setting instances'); + collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, ''))); + } else { + this.logger.verbose('no collections found'); + } + return; + } + + this.logger.verbose('store in files enabled'); + const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); + for await (const dirent of dir) { + if (dirent.isDirectory()) { + this.logger.verbose('reading instance files and setting instances'); + const files = readdirSync(join(INSTANCE_DIR, dirent.name), { + encoding: 'utf-8', + }); + if (files.length === 0) { + rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true }); + break; + } + + await set(dirent.name); + } else { + this.logger.verbose('no instance files found'); + } + } + } catch (error) { + this.logger.error(error); + } + } + + private removeInstance() { + this.eventEmitter.on('remove.instance', async (instanceName: string) => { + this.logger.verbose('remove instance: ' + instanceName); + try { + this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); + this.waInstances[instanceName] = undefined; + } catch (error) { + this.logger.error(error); + } + + try { + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + this.cleaningStoreFiles(instanceName); + } finally { + this.logger.warn(`Instance "${instanceName}" - REMOVED`); + } }); - } finally { - this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`); - } - }); - } + this.eventEmitter.on('logout.instance', async (instanceName: string) => { + this.logger.verbose('logout instance: ' + instanceName); + try { + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + } finally { + this.logger.warn(`Instance "${instanceName}" - LOGOUT`); + } + }); + } + + private noConnection() { + this.logger.verbose('checking instances without connection'); + this.eventEmitter.on('no.connection', async (instanceName) => { + try { + this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); + this.waInstances[instanceName] = undefined; + + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + } catch (error) { + this.logger.error({ + localError: 'noConnection', + warn: 'Error deleting instance from memory.', + error, + }); + } finally { + this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`); + } + }); + } } diff --git a/src/whatsapp/services/settings.service.ts b/src/whatsapp/services/settings.service.ts index f00138e1..bbd5076f 100644 --- a/src/whatsapp/services/settings.service.ts +++ b/src/whatsapp/services/settings.service.ts @@ -4,31 +4,29 @@ import { SettingsDto } from '../dto/settings.dto'; import { WAMonitoringService } from './monitor.service'; export class SettingsService { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - private readonly logger = new Logger(SettingsService.name); + private readonly logger = new Logger(SettingsService.name); - public create(instance: InstanceDto, data: SettingsDto) { - this.logger.verbose('create settings: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setSettings(data); + public create(instance: InstanceDto, data: SettingsDto) { + this.logger.verbose('create settings: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setSettings(data); - return { settings: { ...instance, settings: data } }; - } - - public async find(instance: InstanceDto): Promise { - try { - this.logger.verbose('find settings: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[ - instance.instanceName - ].findSettings(); - - if (Object.keys(result).length === 0) { - throw new Error('Settings not found'); - } - - return result; - } catch (error) { - return { reject_call: false, msg_call: '', groups_ignore: false }; + return { settings: { ...instance, settings: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find settings: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findSettings(); + + if (Object.keys(result).length === 0) { + throw new Error('Settings not found'); + } + + return result; + } catch (error) { + return { reject_call: false, msg_call: '', groups_ignore: false }; + } } - } } diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index 1ffdce6f..36233f1f 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -4,31 +4,29 @@ import { WebhookDto } from '../dto/webhook.dto'; import { WAMonitoringService } from './monitor.service'; export class WebhookService { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - private readonly logger = new Logger(WebhookService.name); + private readonly logger = new Logger(WebhookService.name); - public create(instance: InstanceDto, data: WebhookDto) { - this.logger.verbose('create webhook: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setWebhook(data); + public create(instance: InstanceDto, data: WebhookDto) { + this.logger.verbose('create webhook: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setWebhook(data); - return { webhook: { ...instance, webhook: data } }; - } - - public async find(instance: InstanceDto): Promise { - try { - this.logger.verbose('find webhook: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[ - instance.instanceName - ].findWebhook(); - - if (Object.keys(result).length === 0) { - throw new Error('Webhook not found'); - } - - return result; - } catch (error) { - return { enabled: false, url: '', events: [], webhook_by_events: false }; + return { webhook: { ...instance, webhook: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find webhook: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findWebhook(); + + if (Object.keys(result).length === 0) { + throw new Error('Webhook not found'); + } + + return result; + } catch (error) { + return { enabled: false, url: '', events: [], webhook_by_events: false }; + } } - } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 17c654da..d1bae31e 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,37 +1,37 @@ import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { Boom } from '@hapi/boom'; import makeWASocket, { - AnyMessageContent, - BufferedEventData, - BufferJSON, - CacheStore, - Chat, - ConnectionState, - Contact, - delay, - DisconnectReason, - downloadMediaMessage, - fetchLatestBaileysVersion, - generateWAMessageFromContent, - getAggregateVotesInPollMessage, - getContentType, - getDevice, - GroupMetadata, - isJidGroup, - isJidUser, - makeCacheableSignalKeyStore, - MessageUpsertType, - MiscMessageGenerationOptions, - ParticipantAction, - prepareWAMessageMedia, - proto, - useMultiFileAuthState, - UserFacingSocketConfig, - WABrowserDescription, - WAMediaUpload, - WAMessage, - WAMessageUpdate, - WASocket, + AnyMessageContent, + BufferedEventData, + BufferJSON, + CacheStore, + Chat, + ConnectionState, + Contact, + delay, + DisconnectReason, + downloadMediaMessage, + fetchLatestBaileysVersion, + generateWAMessageFromContent, + getAggregateVotesInPollMessage, + getContentType, + getDevice, + GroupMetadata, + isJidGroup, + isJidUser, + makeCacheableSignalKeyStore, + MessageUpsertType, + MiscMessageGenerationOptions, + ParticipantAction, + prepareWAMessageMedia, + proto, + useMultiFileAuthState, + UserFacingSocketConfig, + WABrowserDescription, + WAMediaUpload, + WAMessage, + WAMessageUpdate, + WASocket, } from '@whiskeysockets/baileys'; import axios from 'axios'; import { exec, execSync } from 'child_process'; @@ -51,67 +51,63 @@ import sharp from 'sharp'; import { v4 } from 'uuid'; import { - Auth, - CleanStoreConf, - ConfigService, - ConfigSessionPhone, - Database, - HttpServer, - Log, - QrCode, - Redis, - Webhook, + Auth, + CleanStoreConf, + ConfigService, + ConfigSessionPhone, + Database, + HttpServer, + Log, + QrCode, + Redis, + Webhook, } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; import { RedisCache } from '../../db/redis.client'; -import { - BadRequestException, - InternalServerErrorException, - NotFoundException, -} from '../../exceptions'; +import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { - ContactMessage, - MediaMessage, - Options, - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, - StatusMessage, + ContactMessage, + MediaMessage, + Options, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, + StatusMessage, } from '../dto/sendMessage.dto'; import { SettingsRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; @@ -128,2894 +124,2764 @@ import { waMonitor } from '../whatsapp.module'; import { ChatwootService } from './chatwoot.service'; export class WAStartupService { - constructor( - private readonly configService: ConfigService, - private readonly eventEmitter: EventEmitter2, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('WAStartupService initialized'); - this.cleanStore(); - this.instance.qrcode = { count: 0 }; - } - - private readonly logger = new Logger(WAStartupService.name); - private readonly instance: wa.Instance = {}; - public client: WASocket; - private readonly localWebhook: wa.LocalWebHook = {}; - private readonly localChatwoot: wa.LocalChatwoot = {}; - private readonly localSettings: wa.LocalSettings = {}; - private stateConnection: wa.StateConnection = { state: 'close' }; - public readonly storePath = join(ROOT_DIR, 'store'); - private readonly msgRetryCounterCache: CacheStore = new NodeCache(); - private readonly userDevicesCache: CacheStore = new NodeCache(); - private endSession = false; - private logBaileys = this.configService.get('LOG').BAILEYS; - - private phoneNumber: string; - - private chatwootService = new ChatwootService(waMonitor, this.configService); - - public set instanceName(name: string) { - this.logger.verbose(`Initializing instance '${name}'`); - if (!name) { - this.logger.verbose('Instance name not found, generating random name with uuid'); - this.instance.name = v4(); - return; + constructor( + private readonly configService: ConfigService, + private readonly eventEmitter: EventEmitter2, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('WAStartupService initialized'); + this.cleanStore(); + this.instance.qrcode = { count: 0 }; } - this.instance.name = name; - this.logger.verbose(`Instance '${this.instance.name}' initialized`); - this.logger.verbose('Sending instance status to webhook'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'created', - }); - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'created', - }, - ); - } - } + private readonly logger = new Logger(WAStartupService.name); + private readonly instance: wa.Instance = {}; + public client: WASocket; + private readonly localWebhook: wa.LocalWebHook = {}; + private readonly localChatwoot: wa.LocalChatwoot = {}; + private readonly localSettings: wa.LocalSettings = {}; + private stateConnection: wa.StateConnection = { state: 'close' }; + public readonly storePath = join(ROOT_DIR, 'store'); + private readonly msgRetryCounterCache: CacheStore = new NodeCache(); + private readonly userDevicesCache: CacheStore = new NodeCache(); + private endSession = false; + private logBaileys = this.configService.get('LOG').BAILEYS; - public get instanceName() { - this.logger.verbose('Getting instance name'); - return this.instance.name; - } + private phoneNumber: string; - public get wuid() { - this.logger.verbose('Getting remoteJid of instance'); - return this.instance.wuid; - } + private chatwootService = new ChatwootService(waMonitor, this.configService); - public async getProfileName() { - this.logger.verbose('Getting profile name'); - let profileName = this.client.user?.name ?? this.client.user?.verifiedName; - if (!profileName) { - this.logger.verbose('Profile name not found, trying to get from database'); - if (this.configService.get('DATABASE').ENABLED) { - this.logger.verbose('Database enabled, trying to get from database'); - const collection = dbserver - .getClient() - .db( - this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + - '-instances', - ) - .collection(this.instanceName); - const data = await collection.findOne({ _id: 'creds' }); - if (data) { - this.logger.verbose('Profile name found in database'); - const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); - profileName = creds.me?.name || creds.me?.verifiedName; + public set instanceName(name: string) { + this.logger.verbose(`Initializing instance '${name}'`); + if (!name) { + this.logger.verbose('Instance name not found, generating random name with uuid'); + this.instance.name = v4(); + return; } - } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { - this.logger.verbose('Profile name found in file'); - const creds = JSON.parse( - readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { - encoding: 'utf-8', - }), - ); - profileName = creds.me?.name || creds.me?.verifiedName; - } - } - - this.logger.verbose(`Profile name: ${profileName}`); - return profileName; - } - - public async getProfileStatus() { - this.logger.verbose('Getting profile status'); - const status = await this.client.fetchStatus(this.instance.wuid); - - this.logger.verbose(`Profile status: ${status.status}`); - return status.status; - } - - public get profilePictureUrl() { - this.logger.verbose('Getting profile picture url'); - return this.instance.profilePictureUrl; - } - - public get qrCode(): wa.QrCode { - this.logger.verbose('Getting qrcode'); - if (this.instance.qrcode?.pairingCode) { - return { - pairingCode: this.instance.qrcode?.pairingCode, - }; - } - - return { - code: this.instance.qrcode?.code, - base64: this.instance.qrcode?.base64, - }; - } - - private async loadWebhook() { - this.logger.verbose('Loading webhook'); - const data = await this.repository.webhook.find(this.instanceName); - this.localWebhook.url = data?.url; - this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); - - this.localWebhook.enabled = data?.enabled; - this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); - - this.localWebhook.events = data?.events; - this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); - - this.localWebhook.webhook_by_events = data?.webhook_by_events; - this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); - - this.logger.verbose('Webhook loaded'); - } - - public async setWebhook(data: WebhookRaw) { - this.logger.verbose('Setting webhook'); - await this.repository.webhook.create(data, this.instanceName); - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - Object.assign(this.localWebhook, data); - this.logger.verbose('Webhook set'); - } - - public async findWebhook() { - this.logger.verbose('Finding webhook'); - const data = await this.repository.webhook.find(this.instanceName); - - if (!data) { - this.logger.verbose('Webhook not found'); - throw new NotFoundException('Webhook not found'); - } - - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - return data; - } - - private async loadChatwoot() { - this.logger.verbose('Loading chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - this.localChatwoot.enabled = data?.enabled; - this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); - - this.localChatwoot.account_id = data?.account_id; - this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); - - this.localChatwoot.token = data?.token; - this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); - - this.localChatwoot.url = data?.url; - this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); - - this.localChatwoot.name_inbox = data?.name_inbox; - this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); - - this.localChatwoot.sign_msg = data?.sign_msg; - this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); - - this.logger.verbose('Chatwoot loaded'); - } - - public async setChatwoot(data: ChatwootRaw) { - this.logger.verbose('Setting chatwoot'); - await this.repository.chatwoot.create(data, this.instanceName); - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - - Object.assign(this.localChatwoot, data); - this.logger.verbose('Chatwoot set'); - } - - public async findChatwoot() { - this.logger.verbose('Finding chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - - if (!data) { - this.logger.verbose('Chatwoot not found'); - return null; - } - - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - - return data; - } - - private async loadSettings() { - this.logger.verbose('Loading settings'); - const data = await this.repository.settings.find(this.instanceName); - this.localSettings.reject_call = data?.reject_call; - this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); - - this.localSettings.msg_call = data?.msg_call; - this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); - - this.localSettings.groups_ignore = data?.groups_ignore; - this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); - - this.logger.verbose('Settings loaded'); - } - - public async setSettings(data: SettingsRaw) { - this.logger.verbose('Setting settings'); - await this.repository.settings.create(data, this.instanceName); - this.logger.verbose(`Settings reject_call: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - Object.assign(this.localSettings, data); - this.logger.verbose('Settings set'); - } - - public async findSettings() { - this.logger.verbose('Finding settings'); - const data = await this.repository.settings.find(this.instanceName); - - if (!data) { - this.logger.verbose('Settings not found'); - throw new NotFoundException('Settings not found'); - } - - this.logger.verbose(`Settings url: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - return data; - } - - public async sendDataWebhook(event: Events, data: T, local = true) { - const webhookGlobal = this.configService.get('WEBHOOK'); - const webhookLocal = this.localWebhook.events; - const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[.-]/gm, '_').toUpperCase(); - const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - - const expose = - this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; - const tokenStore = await this.repository.auth.find(this.instanceName); - const instanceApikey = tokenStore?.apikey || 'Apikey not found'; - - const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - if (local) { - if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { - this.logger.verbose('Sending data to webhook local'); - let baseURL; - - if (this.localWebhook.webhook_by_events) { - baseURL = `${this.localWebhook.url}/${transformedWe}`; - } else { - baseURL = this.localWebhook.url; - } - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-local', - url: baseURL, - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - apikey: (expose && instanceApikey) || null, - }; - - if (expose && instanceApikey) { - logData['apikey'] = instanceApikey; - } - - this.logger.log(logData); - } - - try { - if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { - const httpService = axios.create({ baseURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - }; - - if (expose && instanceApikey) { - postData['apikey'] = instanceApikey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-local', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: baseURL, - server_url: serverUrl, - }); - } - } - } - - if (webhookGlobal.GLOBAL?.ENABLED) { - if (webhookGlobal.EVENTS[we]) { - this.logger.verbose('Sending data to webhook global'); - const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; - - let globalURL; - - if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { - globalURL = `${globalWebhook.URL}/${transformedWe}`; - } else { - globalURL = globalWebhook.URL; - } - - const localUrl = this.localWebhook.url; - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-global', - url: globalURL, - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - logData['apikey'] = globalApiKey; - } - - this.logger.log(logData); - } - - try { - if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { - const httpService = axios.create({ baseURL: globalURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - postData['apikey'] = globalApiKey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-global', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: globalURL, - server_url: serverUrl, - }); - } - } - } - } - - private async connectionUpdate({ - qr, - connection, - lastDisconnect, - }: Partial) { - this.logger.verbose('Connection update'); - if (qr) { - this.logger.verbose('QR code found'); - if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { - this.logger.verbose('QR code limit reached'); - - this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); - this.sendDataWebhook(Events.QRCODE_UPDATED, { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }, - ); - } - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - state: 'refused', - statusReason: DisconnectReason.connectionClosed, - }); - - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.instance.name = name; + this.logger.verbose(`Instance '${this.instance.name}' initialized`); + this.logger.verbose('Sending instance status to webhook'); this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('endSession defined as true'); - this.endSession = true; - - this.logger.verbose('Emmiting event logout.instance'); - return this.eventEmitter.emit('no.connection', this.instance.name); - } - - this.logger.verbose('Incrementing QR code count'); - this.instance.qrcode.count++; - - const optsQrcode: QRCodeToDataURLOptions = { - margin: 3, - scale: 4, - errorCorrectionLevel: 'H', - color: { light: '#ffffff', dark: '#198754' }, - }; - - console.log(this.phoneNumber); - if (this.phoneNumber) { - await delay(2000); - this.instance.qrcode.pairingCode = await this.client.requestPairingCode( - this.phoneNumber, - ); - } else { - this.instance.qrcode.pairingCode = null; - } - - this.logger.verbose('Generating QR code'); - qrcode.toDataURL(qr, optsQrcode, (error, base64) => { - if (error) { - this.logger.error('Qrcode generate failed:' + error.toString()); - return; - } - - this.instance.qrcode.base64 = base64; - this.instance.qrcode.code = qr; - - this.sendDataWebhook(Events.QRCODE_UPDATED, { - qrcode: { instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, + status: 'created', }); if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - qrcode: { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'created', + }, + ); + } + } + + public get instanceName() { + this.logger.verbose('Getting instance name'); + return this.instance.name; + } + + public get wuid() { + this.logger.verbose('Getting remoteJid of instance'); + return this.instance.wuid; + } + + public async getProfileName() { + this.logger.verbose('Getting profile name'); + let profileName = this.client.user?.name ?? this.client.user?.verifiedName; + if (!profileName) { + this.logger.verbose('Profile name not found, trying to get from database'); + if (this.configService.get('DATABASE').ENABLED) { + this.logger.verbose('Database enabled, trying to get from database'); + const collection = dbserver + .getClient() + .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(this.instanceName); + const data = await collection.findOne({ _id: 'creds' }); + if (data) { + this.logger.verbose('Profile name found in database'); + const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); + profileName = creds.me?.name || creds.me?.verifiedName; + } + } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { + this.logger.verbose('Profile name found in file'); + const creds = JSON.parse( + readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { + encoding: 'utf-8', + }), + ); + profileName = creds.me?.name || creds.me?.verifiedName; + } + } + + this.logger.verbose(`Profile name: ${profileName}`); + return profileName; + } + + public async getProfileStatus() { + this.logger.verbose('Getting profile status'); + const status = await this.client.fetchStatus(this.instance.wuid); + + this.logger.verbose(`Profile status: ${status.status}`); + return status.status; + } + + public get profilePictureUrl() { + this.logger.verbose('Getting profile picture url'); + return this.instance.profilePictureUrl; + } + + public get qrCode(): wa.QrCode { + this.logger.verbose('Getting qrcode'); + if (this.instance.qrcode?.pairingCode) { + return { + pairingCode: this.instance.qrcode?.pairingCode, + }; + } + + return { + code: this.instance.qrcode?.code, + base64: this.instance.qrcode?.base64, + }; + } + + private async loadWebhook() { + this.logger.verbose('Loading webhook'); + const data = await this.repository.webhook.find(this.instanceName); + this.localWebhook.url = data?.url; + this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + + this.localWebhook.enabled = data?.enabled; + this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + + this.localWebhook.events = data?.events; + this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); + + this.localWebhook.webhook_by_events = data?.webhook_by_events; + this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + + this.logger.verbose('Webhook loaded'); + } + + public async setWebhook(data: WebhookRaw) { + this.logger.verbose('Setting webhook'); + await this.repository.webhook.create(data, this.instanceName); + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + Object.assign(this.localWebhook, data); + this.logger.verbose('Webhook set'); + } + + public async findWebhook() { + this.logger.verbose('Finding webhook'); + const data = await this.repository.webhook.find(this.instanceName); + + if (!data) { + this.logger.verbose('Webhook not found'); + throw new NotFoundException('Webhook not found'); + } + + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + return data; + } + + private async loadChatwoot() { + this.logger.verbose('Loading chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + this.localChatwoot.enabled = data?.enabled; + this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + + this.localChatwoot.account_id = data?.account_id; + this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); + + this.localChatwoot.token = data?.token; + this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); + + this.localChatwoot.url = data?.url; + this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); + + this.localChatwoot.name_inbox = data?.name_inbox; + this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); + + this.localChatwoot.sign_msg = data?.sign_msg; + this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + + this.logger.verbose('Chatwoot loaded'); + } + + public async setChatwoot(data: ChatwootRaw) { + this.logger.verbose('Setting chatwoot'); + await this.repository.chatwoot.create(data, this.instanceName); + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + + Object.assign(this.localChatwoot, data); + this.logger.verbose('Chatwoot set'); + } + + public async findChatwoot() { + this.logger.verbose('Finding chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + + if (!data) { + this.logger.verbose('Chatwoot not found'); + return null; + } + + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + + return data; + } + + private async loadSettings() { + this.logger.verbose('Loading settings'); + const data = await this.repository.settings.find(this.instanceName); + this.localSettings.reject_call = data?.reject_call; + this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); + + this.localSettings.msg_call = data?.msg_call; + this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); + + this.localSettings.groups_ignore = data?.groups_ignore; + this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + + this.logger.verbose('Settings loaded'); + } + + public async setSettings(data: SettingsRaw) { + this.logger.verbose('Setting settings'); + await this.repository.settings.create(data, this.instanceName); + this.logger.verbose(`Settings reject_call: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + Object.assign(this.localSettings, data); + this.logger.verbose('Settings set'); + } + + public async findSettings() { + this.logger.verbose('Finding settings'); + const data = await this.repository.settings.find(this.instanceName); + + if (!data) { + this.logger.verbose('Settings not found'); + throw new NotFoundException('Settings not found'); + } + + this.logger.verbose(`Settings url: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + return data; + } + + public async sendDataWebhook(event: Events, data: T, local = true) { + const webhookGlobal = this.configService.get('WEBHOOK'); + const webhookLocal = this.localWebhook.events; + const serverUrl = this.configService.get('SERVER').URL; + const we = event.replace(/[.-]/gm, '_').toUpperCase(); + const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + + const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const tokenStore = await this.repository.auth.find(this.instanceName); + const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + + const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + if (local) { + if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { + this.logger.verbose('Sending data to webhook local'); + let baseURL; + + if (this.localWebhook.webhook_by_events) { + baseURL = `${this.localWebhook.url}/${transformedWe}`; + } else { + baseURL = this.localWebhook.url; + } + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-local', + url: baseURL, + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } + + try { + if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { + const httpService = axios.create({ baseURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + postData['apikey'] = instanceApikey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-local', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: baseURL, + server_url: serverUrl, + }); + } + } + } + + if (webhookGlobal.GLOBAL?.ENABLED) { + if (webhookGlobal.EVENTS[we]) { + this.logger.verbose('Sending data to webhook global'); + const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; + + let globalURL; + + if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { + globalURL = `${globalWebhook.URL}/${transformedWe}`; + } else { + globalURL = globalWebhook.URL; + } + + const localUrl = this.localWebhook.url; + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-global', + url: globalURL, + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + logData['apikey'] = globalApiKey; + } + + this.logger.log(logData); + } + + try { + if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { + const httpService = axios.create({ baseURL: globalURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + postData['apikey'] = globalApiKey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-global', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: globalURL, + server_url: serverUrl, + }); + } + } + } + } + + private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { + this.logger.verbose('Connection update'); + if (qr) { + this.logger.verbose('QR code found'); + if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { + this.logger.verbose('QR code limit reached'); + + this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); + this.sendDataWebhook(Events.QRCODE_UPDATED, { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }, + ); + } + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + state: 'refused', + statusReason: DisconnectReason.connectionClosed, + }); + + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); + } + + this.logger.verbose('endSession defined as true'); + this.endSession = true; + + this.logger.verbose('Emmiting event logout.instance'); + return this.eventEmitter.emit('no.connection', this.instance.name); + } + + this.logger.verbose('Incrementing QR code count'); + this.instance.qrcode.count++; + + const optsQrcode: QRCodeToDataURLOptions = { + margin: 3, + scale: 4, + errorCorrectionLevel: 'H', + color: { light: '#ffffff', dark: '#198754' }, + }; + + console.log(this.phoneNumber); + if (this.phoneNumber) { + await delay(2000); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); + } else { + this.instance.qrcode.pairingCode = null; + } + + this.logger.verbose('Generating QR code'); + qrcode.toDataURL(qr, optsQrcode, (error, base64) => { + if (error) { + this.logger.error('Qrcode generate failed:' + error.toString()); + return; + } + + this.instance.qrcode.base64 = base64; + this.instance.qrcode.code = qr; + + this.sendDataWebhook(Events.QRCODE_UPDATED, { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }, + ); + } + }); + + this.logger.verbose('Generating QR code in terminal'); + qrcodeTerminal.generate(qr, { small: true }, (qrcode) => + this.logger.log( + `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + + qrcode, + ), + ); + } + + if (connection) { + this.logger.verbose('Connection found'); + this.stateConnection = { + state: connection, + statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, + }; + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }, - ); - } - }); - - this.logger.verbose('Generating QR code in terminal'); - qrcodeTerminal.generate(qr, { small: true }, (qrcode) => - this.logger.log( - `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + - qrcode, - ), - ); - } - - if (connection) { - this.logger.verbose('Connection found'); - this.stateConnection = { - state: connection, - statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, - }; - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - ...this.stateConnection, - }); - } - - if (connection === 'close') { - this.logger.verbose('Connection closed'); - const shouldReconnect = - (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; - if (shouldReconnect) { - this.logger.verbose('Reconnecting to whatsapp'); - await this.connectToWhatsapp(); - } else { - this.logger.verbose('Do not reconnect to whatsapp'); - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); + ...this.stateConnection, + }); } - this.logger.verbose('Emittin event logout.instance'); - this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); - this.client?.ws?.close(); - this.client.end(new Error('Close connection')); - this.logger.verbose('Connection closed'); - } - } + if (connection === 'close') { + this.logger.verbose('Connection closed'); + const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; + if (shouldReconnect) { + this.logger.verbose('Reconnecting to whatsapp'); + await this.connectToWhatsapp(); + } else { + this.logger.verbose('Do not reconnect to whatsapp'); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); - if (connection === 'open') { - this.logger.verbose('Connection opened'); - this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); - this.instance.profilePictureUrl = ( - await this.profilePicture(this.instance.wuid) - ).profilePictureUrl; - this.logger.info( - ` + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); + } + + this.logger.verbose('Emittin event logout.instance'); + this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); + this.client?.ws?.close(); + this.client.end(new Error('Close connection')); + this.logger.verbose('Connection closed'); + } + } + + if (connection === 'open') { + this.logger.verbose('Connection opened'); + this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); + this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; + this.logger.info( + ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ └──────────────────────────────┘`.replace(/^ +/gm, ' '), - ); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.CONNECTION_UPDATE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'open', - }, - ); - } - } - } - - private async getMessage(key: proto.IMessageKey, full = false) { - this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); - try { - const webMessageInfo = (await this.repository.message.find({ - where: { owner: this.instance.name, key: { id: key.id } }, - })) as unknown as proto.IWebMessageInfo[]; - if (full) { - this.logger.verbose('Returning full message'); - return webMessageInfo[0]; - } - if (webMessageInfo[0].message?.pollCreationMessage) { - this.logger.verbose('Returning poll message'); - const messageSecretBase64 = - webMessageInfo[0].message?.messageContextInfo?.messageSecret; - - if (typeof messageSecretBase64 === 'string') { - const messageSecret = Buffer.from(messageSecretBase64, 'base64'); - - const msg = { - messageContextInfo: { - messageSecret, - }, - pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, - }; - - return msg; - } - } - - this.logger.verbose('Returning message'); - return webMessageInfo[0].message; - } catch (error) { - return { conversation: '' }; - } - } - - private cleanStore() { - this.logger.verbose('Cronjob to clean store initialized'); - const cleanStore = this.configService.get('CLEAN_STORE'); - const database = this.configService.get('DATABASE'); - if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { - this.logger.verbose('Cronjob to clean store enabled'); - setInterval(() => { - try { - for (const [key, value] of Object.entries(cleanStore)) { - if (value === true) { - execSync( - `rm -rf ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - this.logger.verbose( - `Cleaned ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - } - } - } catch (error) { - this.logger.error(error); - } - }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); - } - } - - private async defineAuthState() { - this.logger.verbose('Defining auth state'); - const db = this.configService.get('DATABASE'); - const redis = this.configService.get('REDIS'); - - if (redis?.ENABLED) { - this.logger.verbose('Redis enabled'); - this.cache.reference = this.instance.name; - return await useMultiFileAuthStateRedisDb(this.cache); - } - - if (db.SAVE_DATA.INSTANCE && db.ENABLED) { - this.logger.verbose('Database enabled'); - return await useMultiFileAuthStateDb(this.instance.name); - } - - this.logger.verbose('Store file enabled'); - return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); - } - - public async connectToWhatsapp(number?: string): Promise { - this.logger.verbose('Connecting to whatsapp'); - try { - this.loadWebhook(); - this.loadChatwoot(); - this.loadSettings(); - - this.instance.authState = await this.defineAuthState(); - - const { version } = await fetchLatestBaileysVersion(); - this.logger.verbose('Baileys version: ' + version); - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - this.logger.verbose('Browser: ' + JSON.stringify(browser)); - - const socketConfig: UserFacingSocketConfig = { - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore( - this.instance.authState.state.keys, - P({ level: 'error' }), - ), - }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - browser, - version, - connectTimeoutMs: 60_000, - qrTimeout: 40_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => - (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: true, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, - patchMessageBeforeSending: (message) => { - const requiresPatch = !!( - message.buttonsMessage || - message.listMessage || - message.templateMessage - ); - if (requiresPatch) { - message = { - viewOnceMessageV2: { - message: { - messageContextInfo: { - deviceListMetadataVersion: 2, - deviceListMetadata: {}, - }, - ...message, - }, - }, - }; - } - - return message; - }, - }; - - this.endSession = false; - - this.logger.verbose('Creating socket'); - - this.client = makeWASocket(socketConfig); - - this.logger.verbose('Socket created'); - - this.eventHandler(); - - this.logger.verbose('Socket event handler initialized'); - - this.phoneNumber = number; - - return this.client; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString()); - } - } - - private readonly chatHandle = { - 'chats.upsert': async (chats: Chat[], database: Database) => { - this.logger.verbose('Event received: chats.upsert'); - - this.logger.verbose('Finding chats in database'); - const chatsRepository = await this.repository.chat.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if chats exists in database to insert'); - const chatsRaw: ChatRaw[] = []; - for await (const chat of chats) { - if (chatsRepository.find((cr) => cr.id === chat.id)) { - continue; - } - - chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); - } - - this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); - await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); - }, - - 'chats.update': async ( - chats: Partial< - proto.IConversation & { - lastMessageRecvTimestamp?: number; - } & { - conditional: (bufferedData: BufferedEventData) => boolean; - } - >[], - ) => { - this.logger.verbose('Event received: chats.update'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { id: chat.id, owner: this.instance.wuid }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); - await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); - }, - - 'chats.delete': async (chats: string[]) => { - this.logger.verbose('Event received: chats.delete'); - - this.logger.verbose('Deleting chats in database'); - chats.forEach( - async (chat) => - await this.repository.chat.delete({ - where: { owner: this.instance.name, id: chat }, - }), - ); - - this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); - await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); - }, - }; - - private readonly contactHandle = { - 'contacts.upsert': async (contacts: Contact[], database: Database) => { - this.logger.verbose('Event received: contacts.upsert'); - - this.logger.verbose('Finding contacts in database'); - const contactsRepository = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if contacts exists in database to insert'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - if (contactsRepository.find((cr) => cr.id === contact.id)) { - continue; - } - - contactsRaw.push({ - id: contact.id, - pushName: contact?.name || contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); - - this.logger.verbose('Inserting contacts in database'); - await this.repository.contact.insert( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - - 'contacts.update': async (contacts: Partial[], database: Database) => { - this.logger.verbose('Event received: contacts.update'); - - this.logger.verbose('Verifying if contacts exists in database to update'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - contactsRaw.push({ - id: contact.id, - pushName: contact?.name ?? contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); - - this.logger.verbose('Updating contacts in database'); - await this.repository.contact.update( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - }; - - private readonly messageHandle = { - 'messaging-history.set': async ( - { - messages, - chats, - isLatest, - }: { - chats: Chat[]; - contacts: Contact[]; - messages: proto.IWebMessageInfo[]; - isLatest: boolean; - }, - database: Database, - ) => { - this.logger.verbose('Event received: messaging-history.set'); - if (isLatest) { - this.logger.verbose('isLatest defined as true'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { - id: chat.id, - owner: this.instance.name, - lastMsgTimestamp: chat.lastMessageRecvTimestamp, - }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_SET'); - await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); - } - - const messagesRaw: MessageRaw[] = []; - const messagesRepository = await this.repository.message.find({ - where: { owner: this.instance.name }, - }); - for await (const [, m] of Object.entries(messages)) { - if (!m.message) { - continue; - } - if ( - messagesRepository.find( - (mr) => mr.owner === this.instance.name && mr.key.id === m.key.id, - ) - ) { - continue; - } - - if (Long.isLong(m?.messageTimestamp)) { - m.messageTimestamp = m.messageTimestamp?.toNumber(); - } - - messagesRaw.push({ - key: m.key, - pushName: m.pushName, - participant: m.participant, - message: { ...m.message }, - messageType: getContentType(m.message), - messageTimestamp: m.messageTimestamp as number, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); - this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); - - messages = undefined; - }, - - 'messages.upsert': async ( - { - messages, - type, - }: { - messages: proto.IWebMessageInfo[]; - type: MessageUpsertType; - }, - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.upsert'); - const received = messages[0]; - - if ( - type !== 'notify' || - // received.message?.protocolMessage || - received.message?.pollUpdateMessage - ) { - this.logger.verbose('message rejected'); - return; - } - - if (Long.isLong(received.messageTimestamp)) { - received.messageTimestamp = received.messageTimestamp?.toNumber(); - } - - if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - - const messageRaw: MessageRaw = { - key: received.key, - pushName: received.pushName, - message: { ...received.message }, - messageType: getContentType(received.message), - messageTimestamp: received.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(received.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); - await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, - messageRaw, - ); - } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - database.SAVE_DATA.NEW_MESSAGE, - ); - - this.logger.verbose('Verifying contact from message'); - const contact = await this.repository.contact.find({ - where: { owner: this.instance.name, id: received.key.remoteJid }, - }); - - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: received.pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, - owner: this.instance.name, - }; - - if (contactRaw.id === 'status@broadcast') { - this.logger.verbose('Contact is status@broadcast'); - return; - } - - if (contact?.length) { - this.logger.verbose('Contact found in database'); - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: contact[0].pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, - owner: this.instance.name, - }; - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, - contactRaw, - ); - } - - this.logger.verbose('Updating contact in database'); - await this.repository.contact.update( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - return; - } - - this.logger.verbose('Contact not found in database'); - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); - - this.logger.verbose('Inserting contact in database'); - await this.repository.contact.insert( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - - 'messages.update': async ( - args: WAMessageUpdate[], - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.update'); - const status: Record = { - 0: 'ERROR', - 1: 'PENDING', - 2: 'SERVER_ACK', - 3: 'DELIVERY_ACK', - 4: 'READ', - 5: 'PLAYED', - }; - for await (const { key, update } of args) { - if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { - this.logger.verbose('Message update is valid'); - - let pollUpdates: any; - if (update.pollUpdates) { - this.logger.verbose('Poll update found'); - - this.logger.verbose('Getting poll message'); - const pollCreation = await this.getMessage(key); - this.logger.verbose(pollCreation); - - if (pollCreation) { - this.logger.verbose('Getting aggregate votes in poll message'); - pollUpdates = getAggregateVotesInPollMessage({ - message: pollCreation as proto.IMessage, - pollUpdates: update.pollUpdates, - }); - } - } - - if (status[update.status] === 'READ' && !key.fromMe) return; - - if (update.message === null && update.status === undefined) { - this.logger.verbose('Message deleted'); - - this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); - await this.sendDataWebhook(Events.MESSAGES_DELETE, key); - - const message: MessageUpdateRaw = { - ...key, - status: 'DELETED', - datetime: Date.now(), - owner: this.instance.name, - }; - - this.logger.verbose(message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, ); - return; - } - const message: MessageUpdateRaw = { - ...key, - status: status[update.status], - datetime: Date.now(), - owner: this.instance.name, - pollUpdates, - }; - - this.logger.verbose(message); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); - await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.CONNECTION_UPDATE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'open', + }, + ); + } } - } - }, - }; - - private readonly groupHandler = { - 'groups.upsert': (groupMetadata: GroupMetadata[]) => { - this.logger.verbose('Event received: groups.upsert'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); - this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); - }, - - 'groups.update': (groupMetadataUpdate: Partial[]) => { - this.logger.verbose('Event received: groups.update'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); - this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - }, - - 'group-participants.update': (participantsUpdate: { - id: string; - participants: string[]; - action: ParticipantAction; - }) => { - this.logger.verbose('Event received: group-participants.update'); - - this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); - this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - }, - }; - - private eventHandler() { - this.logger.verbose('Initializing event handler'); - this.client.ev.process(async (events) => { - if (!this.endSession) { - const database = this.configService.get('DATABASE'); - const settings = await this.findSettings(); - - if (events.call) { - this.logger.verbose('Listening event: call'); - const call = events.call[0]; - - if (settings?.reject_call && call.status == 'offer') { - this.logger.verbose('Rejecting call'); - this.client.rejectCall(call.id, call.from); - } - - if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { - this.logger.verbose('Sending message in call'); - const msg = await this.client.sendMessage(call.from, { - text: settings.msg_call, - }); - - this.client.ev.emit('messages.upsert', { - messages: [msg], - type: 'notify', - }); - } - } - - if (events['connection.update']) { - this.logger.verbose('Listening event: connection.update'); - this.connectionUpdate(events['connection.update']); - } - - if (events['creds.update']) { - this.logger.verbose('Listening event: creds.update'); - this.instance.authState.saveCreds(); - } - - if (events['messaging-history.set']) { - this.logger.verbose('Listening event: messaging-history.set'); - const payload = events['messaging-history.set']; - this.messageHandle['messaging-history.set'](payload, database); - } - - if (events['messages.upsert']) { - this.logger.verbose('Listening event: messages.upsert'); - const payload = events['messages.upsert']; - this.messageHandle['messages.upsert'](payload, database, settings); - } - - if (events['messages.update']) { - this.logger.verbose('Listening event: messages.update'); - const payload = events['messages.update']; - this.messageHandle['messages.update'](payload, database, settings); - } - - if (events['presence.update']) { - this.logger.verbose('Listening event: presence.update'); - const payload = events['presence.update']; - - if (settings.groups_ignore && payload.id.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); - } - - if (!settings?.groups_ignore) { - if (events['groups.upsert']) { - this.logger.verbose('Listening event: groups.upsert'); - const payload = events['groups.upsert']; - this.groupHandler['groups.upsert'](payload); - } - - if (events['groups.update']) { - this.logger.verbose('Listening event: groups.update'); - const payload = events['groups.update']; - this.groupHandler['groups.update'](payload); - } - - if (events['group-participants.update']) { - this.logger.verbose('Listening event: group-participants.update'); - const payload = events['group-participants.update']; - this.groupHandler['group-participants.update'](payload); - } - } - - if (events['chats.upsert']) { - this.logger.verbose('Listening event: chats.upsert'); - const payload = events['chats.upsert']; - this.chatHandle['chats.upsert'](payload, database); - } - - if (events['chats.update']) { - this.logger.verbose('Listening event: chats.update'); - const payload = events['chats.update']; - this.chatHandle['chats.update'](payload); - } - - if (events['chats.delete']) { - this.logger.verbose('Listening event: chats.delete'); - const payload = events['chats.delete']; - this.chatHandle['chats.delete'](payload); - } - - if (events['contacts.upsert']) { - this.logger.verbose('Listening event: contacts.upsert'); - const payload = events['contacts.upsert']; - this.contactHandle['contacts.upsert'](payload, database); - } - - if (events['contacts.update']) { - this.logger.verbose('Listening event: contacts.update'); - const payload = events['contacts.update']; - this.contactHandle['contacts.update'](payload, database); - } - } - }); - } - - // Check if the number is MX or AR - private formatMXOrARNumber(jid: string): string { - const countryCode = jid.substring(0, 2); - - if (Number(countryCode) === 52 || Number(countryCode) === 54) { - if (jid.length === 13) { - const number = countryCode + jid.substring(3); - return number; - } - - return jid; - } - return jid; - } - - // Check if the number is br - private formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } - return jid; - } else { - return jid; - } - } - - private createJid(number: string): string { - this.logger.verbose('Creating jid with number: ' + number); - - if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { - this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return number; } - if (number.includes('@broadcast')) { - this.logger.verbose('Number already contains @broadcast'); - return number; - } - - number = number - ?.replace(/\s/g, '') - .replace(/\+/g, '') - .replace(/\(/g, '') - .replace(/\)/g, '') - .split(':')[0] - .split('@')[0]; - - if (number.length >= 18) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = number.replace(/\D/g, ''); - - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); - return `${number}@s.whatsapp.net`; - } - - public async profilePicture(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile picture with jid: ' + jid); - try { - this.logger.verbose('Getting profile picture url'); - return { - wuid: jid, - profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), - }; - } catch (error) { - this.logger.verbose('Profile picture not found'); - return { - wuid: jid, - profilePictureUrl: null, - }; - } - } - - public async getStatus(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile status with jid:' + jid); - try { - this.logger.verbose('Getting status'); - return { - wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, - }; - } catch (error) { - this.logger.verbose('Status not found'); - return { - wuid: jid, - status: null, - }; - } - } - - public async fetchProfile(instanceName: string, number?: string) { - const jid = number ? this.createJid(number) : this.client?.user?.id; - - this.logger.verbose('Getting profile with jid: ' + jid); - try { - this.logger.verbose('Getting profile info'); - const info = await waMonitor.instanceInfo(instanceName); - const business = await this.fetchBusinessProfile(jid); - - if (number) { - const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); - const picture = await this.profilePicture(jid); - const status = await this.getStatus(jid); - - return { - wuid: jid, - name: info?.name, - numberExists: info?.exists, - picture: picture?.profilePictureUrl, - status: status?.status, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } else { - const info = await waMonitor.instanceInfo(instanceName); - - return { - wuid: jid, - name: info?.instance?.profileName, - numberExists: true, - picture: info?.instance?.profilePictureUrl, - status: info?.instance?.profileStatus, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } - } catch (error) { - this.logger.verbose('Profile not found'); - return { - wuid: jid, - name: null, - picture: null, - status: null, - os: null, - isBusiness: false, - }; - } - } - - private async sendMessageWithTyping( - number: string, - message: T, - options?: Options, - ) { - this.logger.verbose('Sending message with typing'); - - const numberWA = await this.whatsappNumber({ numbers: [number] }); - const isWA = numberWA[0]; - - if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { - throw new BadRequestException(isWA); - } - - const sender = isWA.jid; - - try { - if (options?.delay) { - this.logger.verbose('Delaying message'); - - await this.client.presenceSubscribe(sender); - this.logger.verbose('Subscribing to presence'); - - await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); - this.logger.verbose( - 'Sending presence update: ' + options?.presence ?? 'composing', - ); - - await delay(options.delay); - this.logger.verbose('Set delay: ' + options.delay); - - await this.client.sendPresenceUpdate('paused', sender); - this.logger.verbose('Sending presence update: paused'); - } - - const linkPreview = options?.linkPreview != false ? undefined : false; - - let quoted: WAMessage; - - if (options?.quoted) { - const m = options?.quoted; - - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - quoted = msg; - this.logger.verbose('Quoted message'); - } - - let mentions: string[]; - if (isJidGroup(sender)) { + private async getMessage(key: proto.IMessageKey, full = false) { + this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); try { - const groupMetadata = await this.client.groupMetadata(sender); + const webMessageInfo = (await this.repository.message.find({ + where: { owner: this.instance.name, key: { id: key.id } }, + })) as unknown as proto.IWebMessageInfo[]; + if (full) { + this.logger.verbose('Returning full message'); + return webMessageInfo[0]; + } + if (webMessageInfo[0].message?.pollCreationMessage) { + this.logger.verbose('Returning poll message'); + const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; - if (!groupMetadata) { - throw new NotFoundException('Group not found'); - } + if (typeof messageSecretBase64 === 'string') { + const messageSecret = Buffer.from(messageSecretBase64, 'base64'); - if (options?.mentions) { - this.logger.verbose('Mentions defined'); + const msg = { + messageContextInfo: { + messageSecret, + }, + pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, + }; + + return msg; + } + } + + this.logger.verbose('Returning message'); + return webMessageInfo[0].message; + } catch (error) { + return { conversation: '' }; + } + } + + private cleanStore() { + this.logger.verbose('Cronjob to clean store initialized'); + const cleanStore = this.configService.get('CLEAN_STORE'); + const database = this.configService.get('DATABASE'); + if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { + this.logger.verbose('Cronjob to clean store enabled'); + setInterval(() => { + try { + for (const [key, value] of Object.entries(cleanStore)) { + if (value === true) { + execSync( + `rm -rf ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); + this.logger.verbose( + `Cleaned ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); + } + } + } catch (error) { + this.logger.error(error); + } + }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); + } + } + + private async defineAuthState() { + this.logger.verbose('Defining auth state'); + const db = this.configService.get('DATABASE'); + const redis = this.configService.get('REDIS'); + + if (redis?.ENABLED) { + this.logger.verbose('Redis enabled'); + this.cache.reference = this.instance.name; + return await useMultiFileAuthStateRedisDb(this.cache); + } + + if (db.SAVE_DATA.INSTANCE && db.ENABLED) { + this.logger.verbose('Database enabled'); + return await useMultiFileAuthStateDb(this.instance.name); + } + + this.logger.verbose('Store file enabled'); + return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); + } + + public async connectToWhatsapp(number?: string): Promise { + this.logger.verbose('Connecting to whatsapp'); + try { + this.loadWebhook(); + this.loadChatwoot(); + this.loadSettings(); + + this.instance.authState = await this.defineAuthState(); + + const { version } = await fetchLatestBaileysVersion(); + this.logger.verbose('Baileys version: ' + version); + const session = this.configService.get('CONFIG_SESSION_PHONE'); + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + this.logger.verbose('Browser: ' + JSON.stringify(browser)); + + const socketConfig: UserFacingSocketConfig = { + auth: { + creds: this.instance.authState.state.creds, + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + }, + logger: P({ level: this.logBaileys }), + printQRInTerminal: false, + browser, + version, + connectTimeoutMs: 60_000, + qrTimeout: 40_000, + defaultQueryTimeoutMs: undefined, + emitOwnEvents: false, + msgRetryCounterCache: this.msgRetryCounterCache, + getMessage: async (key) => (await this.getMessage(key)) as Promise, + generateHighQualityLinkPreview: true, + syncFullHistory: true, + userDevicesCache: this.userDevicesCache, + transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, + patchMessageBeforeSending: (message) => { + const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); + if (requiresPatch) { + message = { + viewOnceMessageV2: { + message: { + messageContextInfo: { + deviceListMetadataVersion: 2, + deviceListMetadata: {}, + }, + ...message, + }, + }, + }; + } + + return message; + }, + }; + + this.endSession = false; + + this.logger.verbose('Creating socket'); + + this.client = makeWASocket(socketConfig); + + this.logger.verbose('Socket created'); + + this.eventHandler(); + + this.logger.verbose('Socket event handler initialized'); + + this.phoneNumber = number; + + return this.client; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString()); + } + } + + private readonly chatHandle = { + 'chats.upsert': async (chats: Chat[], database: Database) => { + this.logger.verbose('Event received: chats.upsert'); + + this.logger.verbose('Finding chats in database'); + const chatsRepository = await this.repository.chat.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if chats exists in database to insert'); + const chatsRaw: ChatRaw[] = []; + for await (const chat of chats) { + if (chatsRepository.find((cr) => cr.id === chat.id)) { + continue; + } + + chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); + } + + this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); + await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + }, + + 'chats.update': async ( + chats: Partial< + proto.IConversation & { + lastMessageRecvTimestamp?: number; + } & { + conditional: (bufferedData: BufferedEventData) => boolean; + } + >[], + ) => { + this.logger.verbose('Event received: chats.update'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { id: chat.id, owner: this.instance.wuid }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); + await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); + }, + + 'chats.delete': async (chats: string[]) => { + this.logger.verbose('Event received: chats.delete'); + + this.logger.verbose('Deleting chats in database'); + chats.forEach( + async (chat) => + await this.repository.chat.delete({ + where: { owner: this.instance.name, id: chat }, + }), + ); + + this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); + await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); + }, + }; + + private readonly contactHandle = { + 'contacts.upsert': async (contacts: Contact[], database: Database) => { + this.logger.verbose('Event received: contacts.upsert'); + + this.logger.verbose('Finding contacts in database'); + const contactsRepository = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if contacts exists in database to insert'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + if (contactsRepository.find((cr) => cr.id === contact.id)) { + continue; + } + + contactsRaw.push({ + id: contact.id, + pushName: contact?.name || contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); + + this.logger.verbose('Inserting contacts in database'); + await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + + 'contacts.update': async (contacts: Partial[], database: Database) => { + this.logger.verbose('Event received: contacts.update'); + + this.logger.verbose('Verifying if contacts exists in database to update'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + contactsRaw.push({ + id: contact.id, + pushName: contact?.name ?? contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); + + this.logger.verbose('Updating contacts in database'); + await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + }; + + private readonly messageHandle = { + 'messaging-history.set': async ( + { + messages, + chats, + isLatest, + }: { + chats: Chat[]; + contacts: Contact[]; + messages: proto.IWebMessageInfo[]; + isLatest: boolean; + }, + database: Database, + ) => { + this.logger.verbose('Event received: messaging-history.set'); + if (isLatest) { + this.logger.verbose('isLatest defined as true'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { + id: chat.id, + owner: this.instance.name, + lastMsgTimestamp: chat.lastMessageRecvTimestamp, + }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_SET'); + await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + } + + const messagesRaw: MessageRaw[] = []; + const messagesRepository = await this.repository.message.find({ + where: { owner: this.instance.name }, + }); + for await (const [, m] of Object.entries(messages)) { + if (!m.message) { + continue; + } + if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { + continue; + } + + if (Long.isLong(m?.messageTimestamp)) { + m.messageTimestamp = m.messageTimestamp?.toNumber(); + } + + messagesRaw.push({ + key: m.key, + pushName: m.pushName, + participant: m.participant, + message: { ...m.message }, + messageType: getContentType(m.message), + messageTimestamp: m.messageTimestamp as number, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); + this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); + + messages = undefined; + }, + + 'messages.upsert': async ( + { + messages, + type, + }: { + messages: proto.IWebMessageInfo[]; + type: MessageUpsertType; + }, + database: Database, + settings: SettingsRaw, + ) => { + this.logger.verbose('Event received: messages.upsert'); + const received = messages[0]; if ( - !Array.isArray(options.mentions.mentioned) && - !options.mentions.everyOne + type !== 'notify' || + // received.message?.protocolMessage || + received.message?.pollUpdateMessage ) { - throw new BadRequestException('Mentions must be an array'); + this.logger.verbose('message rejected'); + return; } - if (options.mentions.everyOne) { - this.logger.verbose('Mentions everyone'); - - this.logger.verbose('Getting group metadata'); - mentions = groupMetadata.participants.map((participant) => participant.id); - this.logger.verbose('Getting group metadata for mentions'); - } else { - this.logger.verbose('Mentions manually defined'); - mentions = options.mentions.mentioned.map((mention) => { - const jid = this.createJid(mention); - if (isJidGroup(jid)) { - return null; - // throw new BadRequestException('Mentions must be a number'); - } - return jid; - }); + if (Long.isLong(received.messageTimestamp)) { + received.messageTimestamp = received.messageTimestamp?.toNumber(); } - } - } catch (error) { - throw new NotFoundException('Group not found'); - } - } - const messageSent = await (async () => { - const option = { - quoted, - }; - - if ( - !message['audio'] && - !message['poll'] && - !message['sticker'] && - !message['conversation'] && - sender !== 'status@broadcast' - ) { - if (!message['audio']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - forward: { - key: { remoteJid: this.instance.wuid, fromMe: true }, - message, - }, - mentions, - }, - option as unknown as MiscMessageGenerationOptions, - ); - } - } - - if (message['conversation']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - text: message['conversation'], - mentions, - linkPreview: linkPreview, - } as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - } - - if (sender === 'status@broadcast') { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message['status'].content as unknown as AnyMessageContent, - { - backgroundColor: message['status'].option.backgroundColor, - font: message['status'].option.font, - statusJidList: message['status'].option.statusJidList, - } as unknown as MiscMessageGenerationOptions, - ); - } - - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - })(); - - const messageRaw: MessageRaw = { - key: messageSent.key, - pushName: messageSent.pushName, - message: { ...messageSent.message }, - messageType: getContentType(messageSent.message), - messageTimestamp: messageSent.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(messageSent.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); - await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - - // if (this.localChatwoot.enabled) { - // this.chatwootService.eventWhatsapp( - // Events.SEND_MESSAGE, - // { instanceName: this.instance.name }, - // messageRaw, - // ); - // } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, - ); - - return messageSent; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - // Instance Controller - public get connectionStatus() { - this.logger.verbose('Getting connection status'); - return this.stateConnection; - } - - // Send Message Controller - public async textMessage(data: SendTextDto) { - this.logger.verbose('Sending text message'); - return await this.sendMessageWithTyping( - data.number, - { - conversation: data.textMessage.text, - }, - data?.options, - ); - } - - public async pollMessage(data: SendPollDto) { - this.logger.verbose('Sending poll message'); - return await this.sendMessageWithTyping( - data.number, - { - poll: { - name: data.pollMessage.name, - selectableCount: data.pollMessage.selectableCount, - values: data.pollMessage.values, - }, - }, - data?.options, - ); - } - - private async formatStatusMessage(status: StatusMessage) { - this.logger.verbose('Formatting status message'); - - if (!status.type) { - throw new BadRequestException('Type is required'); - } - - if (!status.content) { - throw new BadRequestException('Content is required'); - } - - if (status.allContacts) { - this.logger.verbose('All contacts defined as true'); - - this.logger.verbose('Getting contacts from database'); - const contacts = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - if (!contacts.length) { - throw new BadRequestException('Contacts not found'); - } - - this.logger.verbose('Getting contacts with push name'); - status.statusJidList = contacts - .filter((contact) => contact.pushName) - .map((contact) => contact.id); - - this.logger.verbose(status.statusJidList); - } - - if (!status.statusJidList?.length && !status.allContacts) { - throw new BadRequestException('StatusJidList is required'); - } - - if (status.type === 'text') { - this.logger.verbose('Type defined as text'); - - if (!status.backgroundColor) { - throw new BadRequestException('Background color is required'); - } - - if (!status.font) { - throw new BadRequestException('Font is required'); - } - - return { - content: { - text: status.content, - }, - option: { - backgroundColor: status.backgroundColor, - font: status.font, - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'image') { - this.logger.verbose('Type defined as image'); - - return { - content: { - image: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'video') { - this.logger.verbose('Type defined as video'); - - return { - content: { - video: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'audio') { - this.logger.verbose('Type defined as audio'); - - this.logger.verbose('Processing audio'); - const convert = await this.processAudio(status.content, 'status@broadcast'); - if (typeof convert === 'string') { - this.logger.verbose('Audio processed'); - const audio = fs.readFileSync(convert).toString('base64'); - - const result = { - content: { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - option: { - statusJidList: status.statusJidList, - }, - }; - - fs.unlinkSync(convert); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - throw new BadRequestException('Type not found'); - } - - public async statusMessage(data: SendStatusDto) { - this.logger.verbose('Sending status message'); - const status = await this.formatStatusMessage(data.statusMessage); - - return await this.sendMessageWithTyping('status@broadcast', { - status, - }); - } - - private async prepareMediaMessage(mediaMessage: MediaMessage) { - try { - this.logger.verbose('Preparing media message'); - const prepareMedia = await prepareWAMessageMedia( - { - [mediaMessage.mediatype]: isURL(mediaMessage.media) - ? { url: mediaMessage.media } - : Buffer.from(mediaMessage.media, 'base64'), - } as any, - { upload: this.client.waUploadToServer }, - ); - - const mediaType = mediaMessage.mediatype + 'Message'; - this.logger.verbose('Media type: ' + mediaType); - - if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { - this.logger.verbose( - 'If media type is document and file name is not defined then', - ); - const regex = new RegExp(/.*\/(.+?)\./); - const arrayMatch = regex.exec(mediaMessage.media); - mediaMessage.fileName = arrayMatch[1]; - this.logger.verbose('File name: ' + mediaMessage.fileName); - } - - let mimetype: string; - - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); - } else { - mimetype = getMIMEType(mediaMessage.fileName); - } - - this.logger.verbose('Mimetype: ' + mimetype); - - prepareMedia[mediaType].caption = mediaMessage?.caption; - prepareMedia[mediaType].mimetype = mimetype; - prepareMedia[mediaType].fileName = mediaMessage.fileName; - - if (mediaMessage.mediatype === 'video') { - this.logger.verbose('Is media type video then set gif playback as false'); - prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( - readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), - ); - prepareMedia[mediaType].gifPlayback = false; - } - - this.logger.verbose('Generating wa message from content'); - return generateWAMessageFromContent( - '', - { [mediaType]: { ...prepareMedia[mediaType] } }, - { userJid: this.instance.wuid }, - ); - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString() || error); - } - } - - private async convertToWebP(image: string, number: string) { - try { - this.logger.verbose('Converting image to WebP to sticker'); - - let imagePath: string; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to image name: ' + hash); - - const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; - this.logger.verbose('Output path: ' + outputPath); - - if (isBase64(image)) { - this.logger.verbose('Image is base64'); - - const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); - const imageBuffer = Buffer.from(base64Data, 'base64'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } else { - this.logger.verbose('Image is url'); - - const timestamp = new Date().getTime(); - const url = `${image}?timestamp=${timestamp}`; - this.logger.verbose('including timestamp in url: ' + url); - - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting image from url'); - - const imageBuffer = Buffer.from(response.data, 'binary'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } - - await sharp(imagePath).webp().toFile(outputPath); - this.logger.verbose('Image converted to WebP'); - - fs.unlinkSync(imagePath); - this.logger.verbose('Temp image deleted'); - - return outputPath; - } catch (error) { - console.error('Erro ao converter a imagem para WebP:', error); - } - } - - public async mediaSticker(data: SendStickerDto) { - this.logger.verbose('Sending media sticker'); - const convert = await this.convertToWebP(data.stickerMessage.image, data.number); - const result = await this.sendMessageWithTyping( - data.number, - { - sticker: { url: convert }, - }, - data?.options, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted image deleted'); - - return result; - } - - public async mediaMessage(data: SendMediaDto) { - this.logger.verbose('Sending media message'); - const generate = await this.prepareMediaMessage(data.mediaMessage); - - return await this.sendMessageWithTyping( - data.number, - { ...generate.message }, - data?.options, - ); - } - - private async processAudio(audio: string, number: string) { - this.logger.verbose('Processing audio'); - let tempAudioPath: string; - let outputAudio: string; - - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to audio name: ' + hash); - - if (isURL(audio)) { - this.logger.verbose('Audio is url'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const timestamp = new Date().getTime(); - const url = `${audio}?timestamp=${timestamp}`; - - this.logger.verbose('Including timestamp in url: ' + url); - - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting audio from url'); - - fs.writeFileSync(tempAudioPath, response.data); - } else { - this.logger.verbose('Audio is base64'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const audioBuffer = Buffer.from(audio, 'base64'); - fs.writeFileSync(tempAudioPath, audioBuffer); - this.logger.verbose('Temp audio created'); - } - - this.logger.verbose('Converting audio to mp4'); - return new Promise((resolve, reject) => { - exec( - `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, - (error, _stdout, _stderr) => { - fs.unlinkSync(tempAudioPath); - this.logger.verbose('Temp audio deleted'); - - if (error) reject(error); - - this.logger.verbose('Audio converted to mp4'); - resolve(outputAudio); - }, - ); - }); - } - - public async audioWhatsapp(data: SendAudioDto) { - this.logger.verbose('Sending audio whatsapp'); - - if (!data.options?.encoding && data.options?.encoding !== false) { - data.options.encoding = true; - } - - if (data.options?.encoding) { - const convert = await this.processAudio(data.audioMessage.audio, data.number); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - const result = this.sendMessageWithTyping( - data.number, - { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - return await this.sendMessageWithTyping( - data.number, - { - audio: isURL(data.audioMessage.audio) - ? { url: data.audioMessage.audio } - : Buffer.from(data.audioMessage.audio, 'base64'), - ptt: true, - mimetype: 'audio/ogg; codecs=opus', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - } - - public async buttonMessage(data: SendButtonDto) { - this.logger.verbose('Sending button message'); - const embeddedMedia: any = {}; - let mediatype = 'TEXT'; - - if (data.buttonMessage?.mediaMessage) { - mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; - embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; - const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); - embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; - embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; - } - - const btnItems = { - text: data.buttonMessage.buttons.map((btn) => btn.buttonText), - ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), - }; - - if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { - throw new BadRequestException( - 'Button texts cannot be repeated', - 'Button IDs cannot be repeated.', - ); - } - - return await this.sendMessageWithTyping( - data.number, - { - buttonsMessage: { - text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, - contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, - footerText: data.buttonMessage?.footerText, - buttons: data.buttonMessage.buttons.map((button) => { - return { - buttonText: { - displayText: button.buttonText, - }, - buttonId: button.buttonId, - type: 1, + if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + + const messageRaw: MessageRaw = { + key: received.key, + pushName: received.pushName, + message: { ...received.message }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), }; - }), - headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], - [embeddedMedia?.mediaKey]: embeddedMedia?.message, + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); + await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.MESSAGES_UPSERT, + { instanceName: this.instance.name }, + messageRaw, + ); + } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); + + this.logger.verbose('Verifying contact from message'); + const contact = await this.repository.contact.find({ + where: { owner: this.instance.name, id: received.key.remoteJid }, + }); + + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: received.pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, + }; + + if (contactRaw.id === 'status@broadcast') { + this.logger.verbose('Contact is status@broadcast'); + return; + } + + if (contact?.length) { + this.logger.verbose('Contact found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: contact[0].pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.CONTACTS_UPDATE, + { instanceName: this.instance.name }, + contactRaw, + ); + } + + this.logger.verbose('Updating contact in database'); + await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); + return; + } + + this.logger.verbose('Contact not found in database'); + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); + + this.logger.verbose('Inserting contact in database'); + await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); }, - }, - data?.options, - ); - } - public async locationMessage(data: SendLocationDto) { - this.logger.verbose('Sending location message'); - return await this.sendMessageWithTyping( - data.number, - { - locationMessage: { - degreesLatitude: data.locationMessage.latitude, - degreesLongitude: data.locationMessage.longitude, - name: data.locationMessage?.name, - address: data.locationMessage?.address, + 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { + this.logger.verbose('Event received: messages.update'); + const status: Record = { + 0: 'ERROR', + 1: 'PENDING', + 2: 'SERVER_ACK', + 3: 'DELIVERY_ACK', + 4: 'READ', + 5: 'PLAYED', + }; + for await (const { key, update } of args) { + if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { + this.logger.verbose('Message update is valid'); + + let pollUpdates: any; + if (update.pollUpdates) { + this.logger.verbose('Poll update found'); + + this.logger.verbose('Getting poll message'); + const pollCreation = await this.getMessage(key); + this.logger.verbose(pollCreation); + + if (pollCreation) { + this.logger.verbose('Getting aggregate votes in poll message'); + pollUpdates = getAggregateVotesInPollMessage({ + message: pollCreation as proto.IMessage, + pollUpdates: update.pollUpdates, + }); + } + } + + if (status[update.status] === 'READ' && !key.fromMe) return; + + if (update.message === null && update.status === undefined) { + this.logger.verbose('Message deleted'); + + this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); + await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + + const message: MessageUpdateRaw = { + ...key, + status: 'DELETED', + datetime: Date.now(), + owner: this.instance.name, + }; + + this.logger.verbose(message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + return; + } + + const message: MessageUpdateRaw = { + ...key, + status: status[update.status], + datetime: Date.now(), + owner: this.instance.name, + pollUpdates, + }; + + this.logger.verbose(message); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); + await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + } + } }, - }, - data?.options, - ); - } - - public async listMessage(data: SendListDto) { - this.logger.verbose('Sending list message'); - return await this.sendMessageWithTyping( - data.number, - { - listMessage: { - title: data.listMessage.title, - description: data.listMessage.description, - buttonText: data.listMessage?.buttonText, - footerText: data.listMessage?.footerText, - sections: data.listMessage.sections, - listType: 1, - }, - }, - data?.options, - ); - } - - public async contactMessage(data: SendContactDto) { - this.logger.verbose('Sending contact message'); - const message: proto.IMessage = {}; - - const vcard = (contact: ContactMessage) => { - this.logger.verbose('Creating vcard'); - let result = - 'BEGIN:VCARD\n' + - 'VERSION:3.0\n' + - `N:${contact.fullName}\n` + - `FN:${contact.fullName}\n`; - - if (contact.organization) { - this.logger.verbose('Organization defined'); - result += `ORG:${contact.organization};\n`; - } - - if (contact.email) { - this.logger.verbose('Email defined'); - result += `EMAIL:${contact.email}\n`; - } - - if (contact.url) { - this.logger.verbose('Url defined'); - result += `URL:${contact.url}\n`; - } - - if (!contact.wuid) { - this.logger.verbose('Wuid defined'); - contact.wuid = this.createJid(contact.phoneNumber); - } - - result += - `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + - 'item1.X-ABLabel:Celular\n' + - 'END:VCARD'; - - this.logger.verbose('Vcard created'); - return result; }; - if (data.contactMessage.length === 1) { - message.contactMessage = { - displayName: data.contactMessage[0].fullName, - vcard: vcard(data.contactMessage[0]), - }; - } else { - message.contactsArrayMessage = { - displayName: `${data.contactMessage.length} contacts`, - contacts: data.contactMessage.map((contact) => { - return { - displayName: contact.fullName, - vcard: vcard(contact), - }; - }), - }; + private readonly groupHandler = { + 'groups.upsert': (groupMetadata: GroupMetadata[]) => { + this.logger.verbose('Event received: groups.upsert'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); + this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); + }, + + 'groups.update': (groupMetadataUpdate: Partial[]) => { + this.logger.verbose('Event received: groups.update'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); + this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); + }, + + 'group-participants.update': (participantsUpdate: { + id: string; + participants: string[]; + action: ParticipantAction; + }) => { + this.logger.verbose('Event received: group-participants.update'); + + this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); + this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); + }, + }; + + private eventHandler() { + this.logger.verbose('Initializing event handler'); + this.client.ev.process(async (events) => { + if (!this.endSession) { + const database = this.configService.get('DATABASE'); + const settings = await this.findSettings(); + + if (events.call) { + this.logger.verbose('Listening event: call'); + const call = events.call[0]; + + if (settings?.reject_call && call.status == 'offer') { + this.logger.verbose('Rejecting call'); + this.client.rejectCall(call.id, call.from); + } + + if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { + this.logger.verbose('Sending message in call'); + const msg = await this.client.sendMessage(call.from, { + text: settings.msg_call, + }); + + this.client.ev.emit('messages.upsert', { + messages: [msg], + type: 'notify', + }); + } + } + + if (events['connection.update']) { + this.logger.verbose('Listening event: connection.update'); + this.connectionUpdate(events['connection.update']); + } + + if (events['creds.update']) { + this.logger.verbose('Listening event: creds.update'); + this.instance.authState.saveCreds(); + } + + if (events['messaging-history.set']) { + this.logger.verbose('Listening event: messaging-history.set'); + const payload = events['messaging-history.set']; + this.messageHandle['messaging-history.set'](payload, database); + } + + if (events['messages.upsert']) { + this.logger.verbose('Listening event: messages.upsert'); + const payload = events['messages.upsert']; + this.messageHandle['messages.upsert'](payload, database, settings); + } + + if (events['messages.update']) { + this.logger.verbose('Listening event: messages.update'); + const payload = events['messages.update']; + this.messageHandle['messages.update'](payload, database, settings); + } + + if (events['presence.update']) { + this.logger.verbose('Listening event: presence.update'); + const payload = events['presence.update']; + + if (settings.groups_ignore && payload.id.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); + } + + if (!settings?.groups_ignore) { + if (events['groups.upsert']) { + this.logger.verbose('Listening event: groups.upsert'); + const payload = events['groups.upsert']; + this.groupHandler['groups.upsert'](payload); + } + + if (events['groups.update']) { + this.logger.verbose('Listening event: groups.update'); + const payload = events['groups.update']; + this.groupHandler['groups.update'](payload); + } + + if (events['group-participants.update']) { + this.logger.verbose('Listening event: group-participants.update'); + const payload = events['group-participants.update']; + this.groupHandler['group-participants.update'](payload); + } + } + + if (events['chats.upsert']) { + this.logger.verbose('Listening event: chats.upsert'); + const payload = events['chats.upsert']; + this.chatHandle['chats.upsert'](payload, database); + } + + if (events['chats.update']) { + this.logger.verbose('Listening event: chats.update'); + const payload = events['chats.update']; + this.chatHandle['chats.update'](payload); + } + + if (events['chats.delete']) { + this.logger.verbose('Listening event: chats.delete'); + const payload = events['chats.delete']; + this.chatHandle['chats.delete'](payload); + } + + if (events['contacts.upsert']) { + this.logger.verbose('Listening event: contacts.upsert'); + const payload = events['contacts.upsert']; + this.contactHandle['contacts.upsert'](payload, database); + } + + if (events['contacts.update']) { + this.logger.verbose('Listening event: contacts.update'); + const payload = events['contacts.update']; + this.contactHandle['contacts.update'](payload, database); + } + } + }); } - return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); - } + // Check if the number is MX or AR + private formatMXOrARNumber(jid: string): string { + const countryCode = jid.substring(0, 2); - public async reactionMessage(data: SendReactionDto) { - this.logger.verbose('Sending reaction message'); - return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { - reactionMessage: { - key: data.reactionMessage.key, - text: data.reactionMessage.reaction, - }, - }); - } + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; + } - // Chat Controller - public async whatsappNumber(data: WhatsAppNumberDto) { - this.logger.verbose('Getting whatsapp number'); + return jid; + } + return jid; + } - const onWhatsapp: OnWhatsAppDto[] = []; - for await (const number of data.numbers) { - let jid = this.createJid(number); - - if (isJidGroup(jid)) { - const group = await this.findGroup({ groupJid: jid }, 'inner'); - - if (!group) throw new BadRequestException('Group not found'); - - onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); - } else { - jid = !jid.startsWith('+') ? `+${jid}` : jid; - const verify = await this.client.onWhatsApp(jid); - - const result = verify[0]; - - if (!result) { - onWhatsapp.push(new OnWhatsAppDto(jid, false)); + // Check if the number is br + private formatBRNumber(jid: string) { + const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); + if (regexp.test(jid)) { + const match = regexp.exec(jid); + if (match && match[1] === '55') { + const joker = Number.parseInt(match[3][0]); + const ddd = Number.parseInt(match[2]); + if (joker < 7 || ddd < 31) { + return match[0]; + } + return match[1] + match[2] + match[3]; + } + return jid; } else { - onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); + return jid; } - } } - return onWhatsapp; - } + private createJid(number: string): string { + this.logger.verbose('Creating jid with number: ' + number); - public async markMessageAsRead(data: ReadMessageDto) { - this.logger.verbose('Marking message as read'); - try { - const keys: proto.IMessageKey[] = []; - data.readMessages.forEach((read) => { - if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { - keys.push({ - remoteJid: read.remoteJid, - fromMe: read.fromMe, - id: read.id, - }); + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { + this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); + return number; } - }); - await this.client.readMessages(keys); - return { message: 'Read messages', read: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Read messages fail', error.toString()); - } - } - public async archiveChat(data: ArchiveChatDto) { - this.logger.verbose('Archiving chat'); - try { - data.lastMessage.messageTimestamp = - data.lastMessage?.messageTimestamp ?? Date.now(); - await this.client.chatModify( - { - archive: data.archive, - lastMessages: [data.lastMessage], - }, - data.lastMessage.key.remoteJid, - ); - - return { - chatId: data.lastMessage.key.remoteJid, - archived: true, - }; - } catch (error) { - throw new InternalServerErrorException({ - archived: false, - message: [ - 'An error occurred while archiving the chat. Open a calling.', - error.toString(), - ], - }); - } - } - - public async deleteMessage(del: DeleteMessage) { - this.logger.verbose('Deleting message'); - try { - return await this.client.sendMessage(del.remoteJid, { delete: del }); - } catch (error) { - throw new InternalServerErrorException( - 'Error while deleting message for everyone', - error?.toString(), - ); - } - } - - public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { - this.logger.verbose('Getting base64 from media message'); - try { - const m = data?.message; - const convertToMp4 = data?.convertToMp4 ?? false; - - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - for (const subtype of MessageSubtype) { - if (msg.message[subtype]) { - msg.message = msg.message[subtype].message; + if (number.includes('@broadcast')) { + this.logger.verbose('Number already contains @broadcast'); + return number; } - } - let mediaMessage: any; - let mediaType: string; + number = number + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(':')[0] + .split('@')[0]; - for (const type of TypeMediaMessage) { - mediaMessage = msg.message[type]; - if (mediaMessage) { - mediaType = type; - break; + if (number.length >= 18) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; } - } - if (!mediaMessage) { - throw 'The message is not of the media type'; - } + number = number.replace(/\D/g, ''); - if (typeof mediaMessage['mediaKey'] === 'object') { - msg.message = JSON.parse(JSON.stringify(msg.message)); - } + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); + return `${number}@s.whatsapp.net`; + } - this.logger.verbose('Downloading media message'); - const buffer = await downloadMediaMessage( - { key: msg?.key, message: msg?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }), - reuploadRequest: this.client.updateMediaMessage, - }, - ); - const typeMessage = getContentType(msg.message); + public async profilePicture(number: string) { + const jid = this.createJid(number); - if (convertToMp4 && typeMessage === 'audioMessage') { - this.logger.verbose('Converting audio to mp4'); - const number = msg.key.remoteJid.split('@')[0]; - const convert = await this.processAudio(buffer.toString('base64'), number); + this.logger.verbose('Getting profile picture with jid: ' + jid); + try { + this.logger.verbose('Getting profile picture url'); + return { + wuid: jid, + profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), + }; + } catch (error) { + this.logger.verbose('Profile picture not found'); + return { + wuid: jid, + profilePictureUrl: null, + }; + } + } - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - this.logger.verbose('Audio converted to mp4'); + public async getStatus(number: string) { + const jid = this.createJid(number); - const result = { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], + this.logger.verbose('Getting profile status with jid:' + jid); + try { + this.logger.verbose('Getting status'); + return { + wuid: jid, + status: (await this.client.fetchStatus(jid))?.status, + }; + } catch (error) { + this.logger.verbose('Status not found'); + return { + wuid: jid, + status: null, + }; + } + } + + public async fetchProfile(instanceName: string, number?: string) { + const jid = number ? this.createJid(number) : this.client?.user?.id; + + this.logger.verbose('Getting profile with jid: ' + jid); + try { + this.logger.verbose('Getting profile info'); + const info = await waMonitor.instanceInfo(instanceName); + const business = await this.fetchBusinessProfile(jid); + + if (number) { + const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); + const picture = await this.profilePicture(jid); + const status = await this.getStatus(jid); + + return { + wuid: jid, + name: info?.name, + numberExists: info?.exists, + picture: picture?.profilePictureUrl, + status: status?.status, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } else { + const info = await waMonitor.instanceInfo(instanceName); + + return { + wuid: jid, + name: info?.instance?.profileName, + numberExists: true, + picture: info?.instance?.profilePictureUrl, + status: info?.instance?.profileStatus, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } + } catch (error) { + this.logger.verbose('Profile not found'); + return { + wuid: jid, + name: null, + picture: null, + status: null, + os: null, + isBusiness: false, + }; + } + } + + private async sendMessageWithTyping(number: string, message: T, options?: Options) { + this.logger.verbose('Sending message with typing'); + + const numberWA = await this.whatsappNumber({ numbers: [number] }); + const isWA = numberWA[0]; + + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { + throw new BadRequestException(isWA); + } + + const sender = isWA.jid; + + try { + if (options?.delay) { + this.logger.verbose('Delaying message'); + + await this.client.presenceSubscribe(sender); + this.logger.verbose('Subscribing to presence'); + + await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); + this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); + + await delay(options.delay); + this.logger.verbose('Set delay: ' + options.delay); + + await this.client.sendPresenceUpdate('paused', sender); + this.logger.verbose('Sending presence update: paused'); + } + + const linkPreview = options?.linkPreview != false ? undefined : false; + + let quoted: WAMessage; + + if (options?.quoted) { + const m = options?.quoted; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + quoted = msg; + this.logger.verbose('Quoted message'); + } + + let mentions: string[]; + if (isJidGroup(sender)) { + try { + const groupMetadata = await this.client.groupMetadata(sender); + + if (!groupMetadata) { + throw new NotFoundException('Group not found'); + } + + if (options?.mentions) { + this.logger.verbose('Mentions defined'); + + if (!Array.isArray(options.mentions.mentioned) && !options.mentions.everyOne) { + throw new BadRequestException('Mentions must be an array'); + } + + if (options.mentions.everyOne) { + this.logger.verbose('Mentions everyone'); + + this.logger.verbose('Getting group metadata'); + mentions = groupMetadata.participants.map((participant) => participant.id); + this.logger.verbose('Getting group metadata for mentions'); + } else { + this.logger.verbose('Mentions manually defined'); + mentions = options.mentions.mentioned.map((mention) => { + const jid = this.createJid(mention); + if (isJidGroup(jid)) { + return null; + // throw new BadRequestException('Mentions must be a number'); + } + return jid; + }); + } + } + } catch (error) { + throw new NotFoundException('Group not found'); + } + } + + const messageSent = await (async () => { + const option = { + quoted, + }; + + if ( + !message['audio'] && + !message['poll'] && + !message['sticker'] && + !message['conversation'] && + sender !== 'status@broadcast' + ) { + if (!message['audio']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + forward: { + key: { remoteJid: this.instance.wuid, fromMe: true }, + message, + }, + mentions, + }, + option as unknown as MiscMessageGenerationOptions, + ); + } + } + + if (message['conversation']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + text: message['conversation'], + mentions, + linkPreview: linkPreview, + } as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + } + + if (sender === 'status@broadcast') { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message['status'].content as unknown as AnyMessageContent, + { + backgroundColor: message['status'].option.backgroundColor, + font: message['status'].option.font, + statusJidList: message['status'].option.statusJidList, + } as unknown as MiscMessageGenerationOptions, + ); + } + + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + })(); + + const messageRaw: MessageRaw = { + key: messageSent.key, + pushName: messageSent.pushName, + message: { ...messageSent.message }, + messageType: getContentType(messageSent.message), + messageTimestamp: messageSent.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(messageSent.key.id), + }; + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); + await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); + + // if (this.localChatwoot.enabled) { + // this.chatwootService.eventWhatsapp( + // Events.SEND_MESSAGE, + // { instanceName: this.instance.name }, + // messageRaw, + // ); + // } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert( + [messageRaw], + this.instance.name, + this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, + ); + + return messageSent; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + // Instance Controller + public get connectionStatus() { + this.logger.verbose('Getting connection status'); + return this.stateConnection; + } + + // Send Message Controller + public async textMessage(data: SendTextDto) { + this.logger.verbose('Sending text message'); + return await this.sendMessageWithTyping( + data.number, + { + conversation: data.textMessage.text, }, - mimetype: 'audio/mp4', - base64: Buffer.from(audio, 'base64').toString('base64'), - }; + data?.options, + ); + } - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); + public async pollMessage(data: SendPollDto) { + this.logger.verbose('Sending poll message'); + return await this.sendMessageWithTyping( + data.number, + { + poll: { + name: data.pollMessage.name, + selectableCount: data.pollMessage.selectableCount, + values: data.pollMessage.values, + }, + }, + data?.options, + ); + } - this.logger.verbose('Media message downloaded'); - return result; + private async formatStatusMessage(status: StatusMessage) { + this.logger.verbose('Formatting status message'); + + if (!status.type) { + throw new BadRequestException('Type is required'); } - } - this.logger.verbose('Media message downloaded'); - return { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: mediaMessage['mimetype'], - base64: buffer.toString('base64'), - }; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - public async fetchContacts(query: ContactQuery) { - this.logger.verbose('Fetching contacts'); - if (query?.where) { - query.where.owner = this.instance.name; - if (query.where?.id) { - query.where.id = this.createJid(query.where.id); - } - } else { - query = { - where: { - owner: this.instance.name, - }, - }; - } - return await this.repository.contact.find(query); - } - - public async fetchMessages(query: MessageQuery) { - this.logger.verbose('Fetching messages'); - if (query?.where) { - if (query.where?.key?.remoteJid) { - query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.message.find(query); - } - - public async fetchStatusMessage(query: MessageUpQuery) { - this.logger.verbose('Fetching status messages'); - if (query?.where) { - if (query.where?.remoteJid) { - query.where.remoteJid = this.createJid(query.where.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.messageUpdate.find(query); - } - - public async fetchChats() { - this.logger.verbose('Fetching chats'); - return await this.repository.chat.find({ where: { owner: this.instance.name } }); - } - - public async fetchPrivacySettings() { - this.logger.verbose('Fetching privacy settings'); - return await this.client.fetchPrivacySettings(); - } - - public async updatePrivacySettings(settings: PrivacySettingDto) { - this.logger.verbose('Updating privacy settings'); - try { - await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); - this.logger.verbose('Read receipts privacy updated'); - - await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); - this.logger.verbose('Profile picture privacy updated'); - - await this.client.updateStatusPrivacy(settings.privacySettings.status); - this.logger.verbose('Status privacy updated'); - - await this.client.updateOnlinePrivacy(settings.privacySettings.online); - this.logger.verbose('Online privacy updated'); - - await this.client.updateLastSeenPrivacy(settings.privacySettings.last); - this.logger.verbose('Last seen privacy updated'); - - await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); - this.logger.verbose('Groups add privacy updated'); - - // reinicia a instancia - this.client?.ws?.close(); - - return { - update: 'success', - data: { - readreceipts: settings.privacySettings.readreceipts, - profile: settings.privacySettings.profile, - status: settings.privacySettings.status, - online: settings.privacySettings.online, - last: settings.privacySettings.last, - groupadd: settings.privacySettings.groupadd, - }, - }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating privacy settings', - error.toString(), - ); - } - } - - public async fetchBusinessProfile(number: string): Promise { - this.logger.verbose('Fetching business profile'); - try { - const jid = number ? this.createJid(number) : this.instance.wuid; - - const profile = await this.client.getBusinessProfile(jid); - this.logger.verbose('Trying to get business profile'); - - if (!profile) { - const info = await this.whatsappNumber({ numbers: [jid] }); - - return { - isBusiness: false, - message: 'Not is business profile', - ...info?.shift(), - }; - } - - this.logger.verbose('Business profile fetched'); - return { - isBusiness: true, - ...profile, - }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); - } - } - - public async updateProfileName(name: string) { - this.logger.verbose('Updating profile name to ' + name); - try { - await this.client.updateProfileName(name); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); - } - } - - public async updateProfileStatus(status: string) { - this.logger.verbose('Updating profile status to: ' + status); - try { - await this.client.updateProfileStatus(status); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile status', - error.toString(), - ); - } - } - - public async updateProfilePicture(picture: string) { - this.logger.verbose('Updating profile picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(this.instance.wuid, pic); - this.logger.verbose('Profile picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile picture', - error.toString(), - ); - } - } - - public async removeProfilePicture() { - this.logger.verbose('Removing profile picture'); - try { - await this.client.removeProfilePicture(this.instance.wuid); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error removing profile picture', - error.toString(), - ); - } - } - - // Group - public async createGroup(create: CreateGroupDto) { - this.logger.verbose('Creating group: ' + create.subject); - try { - const participants = create.participants.map((p) => this.createJid(p)); - const { id } = await this.client.groupCreate(create.subject, participants); - this.logger.verbose('Group created: ' + id); - - if (create?.description) { - this.logger.verbose('Updating group description: ' + create.description); - await this.client.groupUpdateDescription(id, create.description); - } - - const group = await this.client.groupMetadata(id); - this.logger.verbose('Getting group metadata'); - - return { groupMetadata: group }; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException('Error creating group', error.toString()); - } - } - - public async updateGroupPicture(picture: GroupPictureDto) { - this.logger.verbose('Updating group picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture.image)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture.image}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture.image)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture.image, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(picture.groupJid, pic); - this.logger.verbose('Group picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error update group picture', - error.toString(), - ); - } - } - - public async updateGroupSubject(data: GroupSubjectDto) { - this.logger.verbose('Updating group subject to: ' + data.subject); - try { - await this.client.groupUpdateSubject(data.groupJid, data.subject); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating group subject', - error.toString(), - ); - } - } - - public async updateGroupDescription(data: GroupDescriptionDto) { - this.logger.verbose('Updating group description to: ' + data.description); - try { - await this.client.groupUpdateDescription(data.groupJid, data.description); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating group description', - error.toString(), - ); - } - } - - public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { - this.logger.verbose('Fetching group'); - try { - return await this.client.groupMetadata(id.groupJid); - } catch (error) { - if (reply === 'inner') { - return; - } - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async fetchAllGroups(getParticipants: GetParticipant) { - this.logger.verbose('Fetching all groups'); - try { - const fetch = Object.values(await this.client.groupFetchAllParticipating()); - - const groups = fetch.map((group) => { - const result = { - id: group.id, - subject: group.subject, - subjectOwner: group.subjectOwner, - subjectTime: group.subjectTime, - size: group.size, - creation: group.creation, - owner: group.owner, - desc: group.desc, - descId: group.descId, - restrict: group.restrict, - announce: group.announce, - }; - - if (getParticipants.getParticipants == 'true') { - result['participants'] = group.participants; + if (!status.content) { + throw new BadRequestException('Content is required'); } + if (status.allContacts) { + this.logger.verbose('All contacts defined as true'); + + this.logger.verbose('Getting contacts from database'); + const contacts = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + if (!contacts.length) { + throw new BadRequestException('Contacts not found'); + } + + this.logger.verbose('Getting contacts with push name'); + status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); + + this.logger.verbose(status.statusJidList); + } + + if (!status.statusJidList?.length && !status.allContacts) { + throw new BadRequestException('StatusJidList is required'); + } + + if (status.type === 'text') { + this.logger.verbose('Type defined as text'); + + if (!status.backgroundColor) { + throw new BadRequestException('Background color is required'); + } + + if (!status.font) { + throw new BadRequestException('Font is required'); + } + + return { + content: { + text: status.content, + }, + option: { + backgroundColor: status.backgroundColor, + font: status.font, + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'image') { + this.logger.verbose('Type defined as image'); + + return { + content: { + image: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'video') { + this.logger.verbose('Type defined as video'); + + return { + content: { + video: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'audio') { + this.logger.verbose('Type defined as audio'); + + this.logger.verbose('Processing audio'); + const convert = await this.processAudio(status.content, 'status@broadcast'); + if (typeof convert === 'string') { + this.logger.verbose('Audio processed'); + const audio = fs.readFileSync(convert).toString('base64'); + + const result = { + content: { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + option: { + statusJidList: status.statusJidList, + }, + }; + + fs.unlinkSync(convert); + + return result; + } else { + throw new InternalServerErrorException(convert); + } + } + + throw new BadRequestException('Type not found'); + } + + public async statusMessage(data: SendStatusDto) { + this.logger.verbose('Sending status message'); + const status = await this.formatStatusMessage(data.statusMessage); + + return await this.sendMessageWithTyping('status@broadcast', { + status, + }); + } + + private async prepareMediaMessage(mediaMessage: MediaMessage) { + try { + this.logger.verbose('Preparing media message'); + const prepareMedia = await prepareWAMessageMedia( + { + [mediaMessage.mediatype]: isURL(mediaMessage.media) + ? { url: mediaMessage.media } + : Buffer.from(mediaMessage.media, 'base64'), + } as any, + { upload: this.client.waUploadToServer }, + ); + + const mediaType = mediaMessage.mediatype + 'Message'; + this.logger.verbose('Media type: ' + mediaType); + + if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { + this.logger.verbose('If media type is document and file name is not defined then'); + const regex = new RegExp(/.*\/(.+?)\./); + const arrayMatch = regex.exec(mediaMessage.media); + mediaMessage.fileName = arrayMatch[1]; + this.logger.verbose('File name: ' + mediaMessage.fileName); + } + + let mimetype: string; + + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + } else { + mimetype = getMIMEType(mediaMessage.fileName); + } + + this.logger.verbose('Mimetype: ' + mimetype); + + prepareMedia[mediaType].caption = mediaMessage?.caption; + prepareMedia[mediaType].mimetype = mimetype; + prepareMedia[mediaType].fileName = mediaMessage.fileName; + + if (mediaMessage.mediatype === 'video') { + this.logger.verbose('Is media type video then set gif playback as false'); + prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( + readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), + ); + prepareMedia[mediaType].gifPlayback = false; + } + + this.logger.verbose('Generating wa message from content'); + return generateWAMessageFromContent( + '', + { [mediaType]: { ...prepareMedia[mediaType] } }, + { userJid: this.instance.wuid }, + ); + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString() || error); + } + } + + private async convertToWebP(image: string, number: string) { + try { + this.logger.verbose('Converting image to WebP to sticker'); + + let imagePath: string; + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to image name: ' + hash); + + const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; + this.logger.verbose('Output path: ' + outputPath); + + if (isBase64(image)) { + this.logger.verbose('Image is base64'); + + const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); + const imageBuffer = Buffer.from(base64Data, 'base64'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } else { + this.logger.verbose('Image is url'); + + const timestamp = new Date().getTime(); + const url = `${image}?timestamp=${timestamp}`; + this.logger.verbose('including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting image from url'); + + const imageBuffer = Buffer.from(response.data, 'binary'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } + + await sharp(imagePath).webp().toFile(outputPath); + this.logger.verbose('Image converted to WebP'); + + fs.unlinkSync(imagePath); + this.logger.verbose('Temp image deleted'); + + return outputPath; + } catch (error) { + console.error('Erro ao converter a imagem para WebP:', error); + } + } + + public async mediaSticker(data: SendStickerDto) { + this.logger.verbose('Sending media sticker'); + const convert = await this.convertToWebP(data.stickerMessage.image, data.number); + const result = await this.sendMessageWithTyping( + data.number, + { + sticker: { url: convert }, + }, + data?.options, + ); + + fs.unlinkSync(convert); + this.logger.verbose('Converted image deleted'); + return result; - }); - - return groups; - } catch (error) { - throw new NotFoundException('Error fetching group', error.toString()); } - } - public async inviteCode(id: GroupJid) { - this.logger.verbose('Fetching invite code for group: ' + id.groupJid); - try { - const code = await this.client.groupInviteCode(id.groupJid); - return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; - } catch (error) { - throw new NotFoundException('No invite code', error.toString()); + public async mediaMessage(data: SendMediaDto) { + this.logger.verbose('Sending media message'); + const generate = await this.prepareMediaMessage(data.mediaMessage); + + return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); } - } - public async inviteInfo(id: GroupInvite) { - this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); - try { - return await this.client.groupGetInviteInfo(id.inviteCode); - } catch (error) { - throw new NotFoundException('No invite info', id.inviteCode); + private async processAudio(audio: string, number: string) { + this.logger.verbose('Processing audio'); + let tempAudioPath: string; + let outputAudio: string; + + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to audio name: ' + hash); + + if (isURL(audio)) { + this.logger.verbose('Audio is url'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const timestamp = new Date().getTime(); + const url = `${audio}?timestamp=${timestamp}`; + + this.logger.verbose('Including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting audio from url'); + + fs.writeFileSync(tempAudioPath, response.data); + } else { + this.logger.verbose('Audio is base64'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const audioBuffer = Buffer.from(audio, 'base64'); + fs.writeFileSync(tempAudioPath, audioBuffer); + this.logger.verbose('Temp audio created'); + } + + this.logger.verbose('Converting audio to mp4'); + return new Promise((resolve, reject) => { + exec( + `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, + (error, _stdout, _stderr) => { + fs.unlinkSync(tempAudioPath); + this.logger.verbose('Temp audio deleted'); + + if (error) reject(error); + + this.logger.verbose('Audio converted to mp4'); + resolve(outputAudio); + }, + ); + }); } - } - public async sendInvite(id: GroupSendInvite) { - this.logger.verbose('Sending invite for group: ' + id.groupJid); - try { - const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); - this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); + public async audioWhatsapp(data: SendAudioDto) { + this.logger.verbose('Sending audio whatsapp'); - const inviteUrl = inviteCode.inviteUrl; - this.logger.verbose('Invite url: ' + inviteUrl); + if (!data.options?.encoding && data.options?.encoding !== false) { + data.options.encoding = true; + } - const numbers = id.numbers.map((number) => this.createJid(number)); - const description = id.description ?? ''; + if (data.options?.encoding) { + const convert = await this.processAudio(data.audioMessage.audio, data.number); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + const result = this.sendMessageWithTyping( + data.number, + { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); - const msg = `${description}\n\n${inviteUrl}`; + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); - const message = { - conversation: msg, - }; + return result; + } else { + throw new InternalServerErrorException(convert); + } + } - for await (const number of numbers) { - await this.sendMessageWithTyping(number, message); - } - - this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - - return { send: true, inviteUrl }; - } catch (error) { - throw new NotFoundException('No send invite'); + return await this.sendMessageWithTyping( + data.number, + { + audio: isURL(data.audioMessage.audio) + ? { url: data.audioMessage.audio } + : Buffer.from(data.audioMessage.audio, 'base64'), + ptt: true, + mimetype: 'audio/ogg; codecs=opus', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); } - } - public async revokeInviteCode(id: GroupJid) { - this.logger.verbose('Revoking invite code for group: ' + id.groupJid); - try { - const inviteCode = await this.client.groupRevokeInvite(id.groupJid); - return { revoked: true, inviteCode }; - } catch (error) { - throw new NotFoundException('Revoke error', error.toString()); - } - } + public async buttonMessage(data: SendButtonDto) { + this.logger.verbose('Sending button message'); + const embeddedMedia: any = {}; + let mediatype = 'TEXT'; - public async findParticipants(id: GroupJid) { - this.logger.verbose('Fetching participants for group: ' + id.groupJid); - try { - const participants = (await this.client.groupMetadata(id.groupJid)).participants; - return { participants }; - } catch (error) { - throw new NotFoundException('No participants', error.toString()); - } - } + if (data.buttonMessage?.mediaMessage) { + mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; + embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; + const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); + embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; + embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; + } - public async updateGParticipant(update: GroupUpdateParticipantDto) { - this.logger.verbose('Updating participants'); - try { - const participants = update.participants.map((p) => this.createJid(p)); - const updateParticipants = await this.client.groupParticipantsUpdate( - update.groupJid, - participants, - update.action, - ); - return { updateParticipants: updateParticipants }; - } catch (error) { - throw new BadRequestException('Error updating participants', error.toString()); - } - } + const btnItems = { + text: data.buttonMessage.buttons.map((btn) => btn.buttonText), + ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + }; - public async updateGSetting(update: GroupUpdateSettingDto) { - this.logger.verbose('Updating setting for group: ' + update.groupJid); - try { - const updateSetting = await this.client.groupSettingUpdate( - update.groupJid, - update.action, - ); - return { updateSetting: updateSetting }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } + if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { + throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); + } - public async toggleEphemeral(update: GroupToggleEphemeralDto) { - this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); - try { - const toggleEphemeral = await this.client.groupToggleEphemeral( - update.groupJid, - update.expiration, - ); - return { success: true }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); + return await this.sendMessageWithTyping( + data.number, + { + buttonsMessage: { + text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, + contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, + footerText: data.buttonMessage?.footerText, + buttons: data.buttonMessage.buttons.map((button) => { + return { + buttonText: { + displayText: button.buttonText, + }, + buttonId: button.buttonId, + type: 1, + }; + }), + headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], + [embeddedMedia?.mediaKey]: embeddedMedia?.message, + }, + }, + data?.options, + ); } - } - public async leaveGroup(id: GroupJid) { - this.logger.verbose('Leaving group: ' + id.groupJid); - try { - await this.client.groupLeave(id.groupJid); - return { groupJid: id.groupJid, leave: true }; - } catch (error) { - throw new BadRequestException('Unable to leave the group', error.toString()); + public async locationMessage(data: SendLocationDto) { + this.logger.verbose('Sending location message'); + return await this.sendMessageWithTyping( + data.number, + { + locationMessage: { + degreesLatitude: data.locationMessage.latitude, + degreesLongitude: data.locationMessage.longitude, + name: data.locationMessage?.name, + address: data.locationMessage?.address, + }, + }, + data?.options, + ); + } + + public async listMessage(data: SendListDto) { + this.logger.verbose('Sending list message'); + return await this.sendMessageWithTyping( + data.number, + { + listMessage: { + title: data.listMessage.title, + description: data.listMessage.description, + buttonText: data.listMessage?.buttonText, + footerText: data.listMessage?.footerText, + sections: data.listMessage.sections, + listType: 1, + }, + }, + data?.options, + ); + } + + public async contactMessage(data: SendContactDto) { + this.logger.verbose('Sending contact message'); + const message: proto.IMessage = {}; + + const vcard = (contact: ContactMessage) => { + this.logger.verbose('Creating vcard'); + let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; + + if (contact.organization) { + this.logger.verbose('Organization defined'); + result += `ORG:${contact.organization};\n`; + } + + if (contact.email) { + this.logger.verbose('Email defined'); + result += `EMAIL:${contact.email}\n`; + } + + if (contact.url) { + this.logger.verbose('Url defined'); + result += `URL:${contact.url}\n`; + } + + if (!contact.wuid) { + this.logger.verbose('Wuid defined'); + contact.wuid = this.createJid(contact.phoneNumber); + } + + result += + `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; + + this.logger.verbose('Vcard created'); + return result; + }; + + if (data.contactMessage.length === 1) { + message.contactMessage = { + displayName: data.contactMessage[0].fullName, + vcard: vcard(data.contactMessage[0]), + }; + } else { + message.contactsArrayMessage = { + displayName: `${data.contactMessage.length} contacts`, + contacts: data.contactMessage.map((contact) => { + return { + displayName: contact.fullName, + vcard: vcard(contact), + }; + }), + }; + } + + return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + } + + public async reactionMessage(data: SendReactionDto) { + this.logger.verbose('Sending reaction message'); + return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { + reactionMessage: { + key: data.reactionMessage.key, + text: data.reactionMessage.reaction, + }, + }); + } + + // Chat Controller + public async whatsappNumber(data: WhatsAppNumberDto) { + this.logger.verbose('Getting whatsapp number'); + + const onWhatsapp: OnWhatsAppDto[] = []; + for await (const number of data.numbers) { + let jid = this.createJid(number); + + if (isJidGroup(jid)) { + const group = await this.findGroup({ groupJid: jid }, 'inner'); + + if (!group) throw new BadRequestException('Group not found'); + + onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); + } else { + jid = !jid.startsWith('+') ? `+${jid}` : jid; + const verify = await this.client.onWhatsApp(jid); + + const result = verify[0]; + + if (!result) { + onWhatsapp.push(new OnWhatsAppDto(jid, false)); + } else { + onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); + } + } + } + + return onWhatsapp; + } + + public async markMessageAsRead(data: ReadMessageDto) { + this.logger.verbose('Marking message as read'); + try { + const keys: proto.IMessageKey[] = []; + data.readMessages.forEach((read) => { + if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { + keys.push({ + remoteJid: read.remoteJid, + fromMe: read.fromMe, + id: read.id, + }); + } + }); + await this.client.readMessages(keys); + return { message: 'Read messages', read: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Read messages fail', error.toString()); + } + } + + public async archiveChat(data: ArchiveChatDto) { + this.logger.verbose('Archiving chat'); + try { + data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); + await this.client.chatModify( + { + archive: data.archive, + lastMessages: [data.lastMessage], + }, + data.lastMessage.key.remoteJid, + ); + + return { + chatId: data.lastMessage.key.remoteJid, + archived: true, + }; + } catch (error) { + throw new InternalServerErrorException({ + archived: false, + message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], + }); + } + } + + public async deleteMessage(del: DeleteMessage) { + this.logger.verbose('Deleting message'); + try { + return await this.client.sendMessage(del.remoteJid, { delete: del }); + } catch (error) { + throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); + } + } + + public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { + this.logger.verbose('Getting base64 from media message'); + try { + const m = data?.message; + const convertToMp4 = data?.convertToMp4 ?? false; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + for (const subtype of MessageSubtype) { + if (msg.message[subtype]) { + msg.message = msg.message[subtype].message; + } + } + + let mediaMessage: any; + let mediaType: string; + + for (const type of TypeMediaMessage) { + mediaMessage = msg.message[type]; + if (mediaMessage) { + mediaType = type; + break; + } + } + + if (!mediaMessage) { + throw 'The message is not of the media type'; + } + + if (typeof mediaMessage['mediaKey'] === 'object') { + msg.message = JSON.parse(JSON.stringify(msg.message)); + } + + this.logger.verbose('Downloading media message'); + const buffer = await downloadMediaMessage( + { key: msg?.key, message: msg?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }), + reuploadRequest: this.client.updateMediaMessage, + }, + ); + const typeMessage = getContentType(msg.message); + + if (convertToMp4 && typeMessage === 'audioMessage') { + this.logger.verbose('Converting audio to mp4'); + const number = msg.key.remoteJid.split('@')[0]; + const convert = await this.processAudio(buffer.toString('base64'), number); + + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + this.logger.verbose('Audio converted to mp4'); + + const result = { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: 'audio/mp4', + base64: Buffer.from(audio, 'base64').toString('base64'), + }; + + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); + + this.logger.verbose('Media message downloaded'); + return result; + } + } + + this.logger.verbose('Media message downloaded'); + return { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: mediaMessage['mimetype'], + base64: buffer.toString('base64'), + }; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + public async fetchContacts(query: ContactQuery) { + this.logger.verbose('Fetching contacts'); + if (query?.where) { + query.where.owner = this.instance.name; + if (query.where?.id) { + query.where.id = this.createJid(query.where.id); + } + } else { + query = { + where: { + owner: this.instance.name, + }, + }; + } + return await this.repository.contact.find(query); + } + + public async fetchMessages(query: MessageQuery) { + this.logger.verbose('Fetching messages'); + if (query?.where) { + if (query.where?.key?.remoteJid) { + query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.message.find(query); + } + + public async fetchStatusMessage(query: MessageUpQuery) { + this.logger.verbose('Fetching status messages'); + if (query?.where) { + if (query.where?.remoteJid) { + query.where.remoteJid = this.createJid(query.where.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.messageUpdate.find(query); + } + + public async fetchChats() { + this.logger.verbose('Fetching chats'); + return await this.repository.chat.find({ where: { owner: this.instance.name } }); + } + + public async fetchPrivacySettings() { + this.logger.verbose('Fetching privacy settings'); + return await this.client.fetchPrivacySettings(); + } + + public async updatePrivacySettings(settings: PrivacySettingDto) { + this.logger.verbose('Updating privacy settings'); + try { + await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); + this.logger.verbose('Read receipts privacy updated'); + + await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); + this.logger.verbose('Profile picture privacy updated'); + + await this.client.updateStatusPrivacy(settings.privacySettings.status); + this.logger.verbose('Status privacy updated'); + + await this.client.updateOnlinePrivacy(settings.privacySettings.online); + this.logger.verbose('Online privacy updated'); + + await this.client.updateLastSeenPrivacy(settings.privacySettings.last); + this.logger.verbose('Last seen privacy updated'); + + await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); + this.logger.verbose('Groups add privacy updated'); + + // reinicia a instancia + this.client?.ws?.close(); + + return { + update: 'success', + data: { + readreceipts: settings.privacySettings.readreceipts, + profile: settings.privacySettings.profile, + status: settings.privacySettings.status, + online: settings.privacySettings.online, + last: settings.privacySettings.last, + groupadd: settings.privacySettings.groupadd, + }, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating privacy settings', error.toString()); + } + } + + public async fetchBusinessProfile(number: string): Promise { + this.logger.verbose('Fetching business profile'); + try { + const jid = number ? this.createJid(number) : this.instance.wuid; + + const profile = await this.client.getBusinessProfile(jid); + this.logger.verbose('Trying to get business profile'); + + if (!profile) { + const info = await this.whatsappNumber({ numbers: [jid] }); + + return { + isBusiness: false, + message: 'Not is business profile', + ...info?.shift(), + }; + } + + this.logger.verbose('Business profile fetched'); + return { + isBusiness: true, + ...profile, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileName(name: string) { + this.logger.verbose('Updating profile name to ' + name); + try { + await this.client.updateProfileName(name); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileStatus(status: string) { + this.logger.verbose('Updating profile status to: ' + status); + try { + await this.client.updateProfileStatus(status); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile status', error.toString()); + } + } + + public async updateProfilePicture(picture: string) { + this.logger.verbose('Updating profile picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(this.instance.wuid, pic); + this.logger.verbose('Profile picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile picture', error.toString()); + } + } + + public async removeProfilePicture() { + this.logger.verbose('Removing profile picture'); + try { + await this.client.removeProfilePicture(this.instance.wuid); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error removing profile picture', error.toString()); + } + } + + // Group + public async createGroup(create: CreateGroupDto) { + this.logger.verbose('Creating group: ' + create.subject); + try { + const participants = create.participants.map((p) => this.createJid(p)); + const { id } = await this.client.groupCreate(create.subject, participants); + this.logger.verbose('Group created: ' + id); + + if (create?.description) { + this.logger.verbose('Updating group description: ' + create.description); + await this.client.groupUpdateDescription(id, create.description); + } + + const group = await this.client.groupMetadata(id); + this.logger.verbose('Getting group metadata'); + + return { groupMetadata: group }; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException('Error creating group', error.toString()); + } + } + + public async updateGroupPicture(picture: GroupPictureDto) { + this.logger.verbose('Updating group picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture.image)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture.image}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture.image)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture.image, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(picture.groupJid, pic); + this.logger.verbose('Group picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error update group picture', error.toString()); + } + } + + public async updateGroupSubject(data: GroupSubjectDto) { + this.logger.verbose('Updating group subject to: ' + data.subject); + try { + await this.client.groupUpdateSubject(data.groupJid, data.subject); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group subject', error.toString()); + } + } + + public async updateGroupDescription(data: GroupDescriptionDto) { + this.logger.verbose('Updating group description to: ' + data.description); + try { + await this.client.groupUpdateDescription(data.groupJid, data.description); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group description', error.toString()); + } + } + + public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { + this.logger.verbose('Fetching group'); + try { + return await this.client.groupMetadata(id.groupJid); + } catch (error) { + if (reply === 'inner') { + return; + } + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async fetchAllGroups(getParticipants: GetParticipant) { + this.logger.verbose('Fetching all groups'); + try { + const fetch = Object.values(await this.client.groupFetchAllParticipating()); + + const groups = fetch.map((group) => { + const result = { + id: group.id, + subject: group.subject, + subjectOwner: group.subjectOwner, + subjectTime: group.subjectTime, + size: group.size, + creation: group.creation, + owner: group.owner, + desc: group.desc, + descId: group.descId, + restrict: group.restrict, + announce: group.announce, + }; + + if (getParticipants.getParticipants == 'true') { + result['participants'] = group.participants; + } + + return result; + }); + + return groups; + } catch (error) { + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async inviteCode(id: GroupJid) { + this.logger.verbose('Fetching invite code for group: ' + id.groupJid); + try { + const code = await this.client.groupInviteCode(id.groupJid); + return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; + } catch (error) { + throw new NotFoundException('No invite code', error.toString()); + } + } + + public async inviteInfo(id: GroupInvite) { + this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); + try { + return await this.client.groupGetInviteInfo(id.inviteCode); + } catch (error) { + throw new NotFoundException('No invite info', id.inviteCode); + } + } + + public async sendInvite(id: GroupSendInvite) { + this.logger.verbose('Sending invite for group: ' + id.groupJid); + try { + const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); + this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); + + const inviteUrl = inviteCode.inviteUrl; + this.logger.verbose('Invite url: ' + inviteUrl); + + const numbers = id.numbers.map((number) => this.createJid(number)); + const description = id.description ?? ''; + + const msg = `${description}\n\n${inviteUrl}`; + + const message = { + conversation: msg, + }; + + for await (const number of numbers) { + await this.sendMessageWithTyping(number, message); + } + + this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); + + return { send: true, inviteUrl }; + } catch (error) { + throw new NotFoundException('No send invite'); + } + } + + public async revokeInviteCode(id: GroupJid) { + this.logger.verbose('Revoking invite code for group: ' + id.groupJid); + try { + const inviteCode = await this.client.groupRevokeInvite(id.groupJid); + return { revoked: true, inviteCode }; + } catch (error) { + throw new NotFoundException('Revoke error', error.toString()); + } + } + + public async findParticipants(id: GroupJid) { + this.logger.verbose('Fetching participants for group: ' + id.groupJid); + try { + const participants = (await this.client.groupMetadata(id.groupJid)).participants; + return { participants }; + } catch (error) { + throw new NotFoundException('No participants', error.toString()); + } + } + + public async updateGParticipant(update: GroupUpdateParticipantDto) { + this.logger.verbose('Updating participants'); + try { + const participants = update.participants.map((p) => this.createJid(p)); + const updateParticipants = await this.client.groupParticipantsUpdate( + update.groupJid, + participants, + update.action, + ); + return { updateParticipants: updateParticipants }; + } catch (error) { + throw new BadRequestException('Error updating participants', error.toString()); + } + } + + public async updateGSetting(update: GroupUpdateSettingDto) { + this.logger.verbose('Updating setting for group: ' + update.groupJid); + try { + const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); + return { updateSetting: updateSetting }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); + } + } + + public async toggleEphemeral(update: GroupToggleEphemeralDto) { + this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); + try { + const toggleEphemeral = await this.client.groupToggleEphemeral(update.groupJid, update.expiration); + return { success: true }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); + } + } + + public async leaveGroup(id: GroupJid) { + this.logger.verbose('Leaving group: ' + id.groupJid); + try { + await this.client.groupLeave(id.groupJid); + return { groupJid: id.groupJid, leave: true }; + } catch (error) { + throw new BadRequestException('Unable to leave the group', error.toString()); + } } - } } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d0c5f80c..7e4b8352 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -2,94 +2,81 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys'; export enum Events { - APPLICATION_STARTUP = 'application.startup', - QRCODE_UPDATED = 'qrcode.updated', - CONNECTION_UPDATE = 'connection.update', - STATUS_INSTANCE = 'status.instance', - MESSAGES_SET = 'messages.set', - MESSAGES_UPSERT = 'messages.upsert', - MESSAGES_UPDATE = 'messages.update', - MESSAGES_DELETE = 'messages.delete', - SEND_MESSAGE = 'send.message', - CONTACTS_SET = 'contacts.set', - CONTACTS_UPSERT = 'contacts.upsert', - CONTACTS_UPDATE = 'contacts.update', - PRESENCE_UPDATE = 'presence.update', - CHATS_SET = 'chats.set', - CHATS_UPDATE = 'chats.update', - CHATS_UPSERT = 'chats.upsert', - CHATS_DELETE = 'chats.delete', - GROUPS_UPSERT = 'groups.upsert', - GROUPS_UPDATE = 'groups.update', - GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + APPLICATION_STARTUP = 'application.startup', + QRCODE_UPDATED = 'qrcode.updated', + CONNECTION_UPDATE = 'connection.update', + STATUS_INSTANCE = 'status.instance', + MESSAGES_SET = 'messages.set', + MESSAGES_UPSERT = 'messages.upsert', + MESSAGES_UPDATE = 'messages.update', + MESSAGES_DELETE = 'messages.delete', + SEND_MESSAGE = 'send.message', + CONTACTS_SET = 'contacts.set', + CONTACTS_UPSERT = 'contacts.upsert', + CONTACTS_UPDATE = 'contacts.update', + PRESENCE_UPDATE = 'presence.update', + CHATS_SET = 'chats.set', + CHATS_UPDATE = 'chats.update', + CHATS_UPSERT = 'chats.upsert', + CHATS_DELETE = 'chats.delete', + GROUPS_UPSERT = 'groups.upsert', + GROUPS_UPDATE = 'groups.update', + GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', } export declare namespace wa { - export type QrCode = { - count?: number; - pairingCode?: string; - base64?: string; - code?: string; - }; - export type Instance = { - qrcode?: QrCode; - pairingCode?: string; - authState?: { state: AuthenticationState; saveCreds: () => void }; - name?: string; - wuid?: string; - profileName?: string; - profilePictureUrl?: string; - }; + export type QrCode = { + count?: number; + pairingCode?: string; + base64?: string; + code?: string; + }; + export type Instance = { + qrcode?: QrCode; + pairingCode?: string; + authState?: { state: AuthenticationState; saveCreds: () => void }; + name?: string; + wuid?: string; + profileName?: string; + profilePictureUrl?: string; + }; - export type LocalWebHook = { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; - }; + export type LocalWebHook = { + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; + }; - export type LocalChatwoot = { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - }; + export type LocalChatwoot = { + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + }; - export type LocalSettings = { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - }; + export type LocalSettings = { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + }; - export type StateConnection = { - instance?: string; - state?: WAConnectionState | 'refused'; - statusReason?: number; - }; + export type StateConnection = { + instance?: string; + state?: WAConnectionState | 'refused'; + statusReason?: number; + }; - export type StatusMessage = - | 'ERROR' - | 'PENDING' - | 'SERVER_ACK' - | 'DELIVERY_ACK' - | 'READ' - | 'DELETED' - | 'PLAYED'; + export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; } -export const TypeMediaMessage = [ - 'imageMessage', - 'documentMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', -]; +export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage']; export const MessageSubtype = [ - 'ephemeralMessage', - 'documentWithCaptionMessage', - 'viewOnceMessage', - 'viewOnceMessageV2', + 'ephemeralMessage', + 'documentWithCaptionMessage', + 'viewOnceMessage', + 'viewOnceMessageV2', ]; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 30f43015..e783d490 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -14,14 +14,14 @@ import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; import { WebhookController } from './controllers/webhook.controller'; import { - AuthModel, - ChatModel, - ChatwootModel, - ContactModel, - MessageModel, - MessageUpModel, - SettingsModel, - WebhookModel, + AuthModel, + ChatModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + SettingsModel, + WebhookModel, } from './models'; import { AuthRepository } from './repository/auth.repository'; import { ChatRepository } from './repository/chat.repository'; @@ -52,26 +52,21 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); export const repository = new RepositoryBroker( - messageRepository, - chatRepository, - contactRepository, - messageUpdateRepository, - webhookRepository, - chatwootRepository, - settingsRepository, - authRepository, - configService, - dbserver?.getClient(), + messageRepository, + chatRepository, + contactRepository, + messageUpdateRepository, + webhookRepository, + chatwootRepository, + settingsRepository, + authRepository, + configService, + dbserver?.getClient(), ); export const cache = new RedisCache(); -export const waMonitor = new WAMonitoringService( - eventEmitter, - configService, - repository, - cache, -); +export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache); const authService = new AuthService(configService, waMonitor, repository); @@ -88,14 +83,14 @@ const settingsService = new SettingsService(waMonitor); export const settingsController = new SettingsController(settingsService); export const instanceController = new InstanceController( - waMonitor, - configService, - repository, - eventEmitter, - authService, - webhookService, - chatwootService, - cache, + waMonitor, + configService, + repository, + eventEmitter, + authService, + webhookService, + chatwootService, + cache, ); export const viewsController = new ViewsController(waMonitor, configService); export const sendMessageController = new SendMessageController(waMonitor); From 5482601b41c650df84f0a7abde461832241372d8 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 10:59:15 -0300 Subject: [PATCH 068/177] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fb6e58b3c4257a23b0b46a29231099ceb172f60b Merge: 1d3d557 67e9845 Author: Davidson Gomes Date: Wed Jul 26 09:39:37 2023 -0300 Merge branch 'release/1.4.5' commit 67e98456bb39bfc7e545c5b90bf76160f458dce6 Author: Davidson Gomes Date: Wed Jul 26 09:39:27 2023 -0300 fix: Fix mids going duplicated in chatwoot commit 3e47420534e4fdfa3a6898b3c6c1e5ea4f4df5c3 Merge: 3f41974 1d3d557 Author: Davidson Gomes Date: Wed Jul 26 09:38:44 2023 -0300 Merge tag '1.4.5' into develop * Fixed problems in localization template in chatwoot * Fix mids going duplicated in chatwoot commit 1d3d557c439631bbee14808e83516cbb67f95992 Merge: 6b926dc 3f41974 Author: Davidson Gomes Date: Wed Jul 26 09:38:36 2023 -0300 Merge branch 'release/1.4.5' commit 3f41974a753285fd36fce7f0cdef3c4eb6cf044f Author: Davidson Gomes Date: Wed Jul 26 09:38:22 2023 -0300 fix: Fix mids going duplicated in chatwoot commit 3e3c7397a5a7efbb1f68f6b91f6202ae227a0755 Merge: de0c9a1 dcb5170 Author: Davidson Gomes Date: Wed Jul 26 09:36:10 2023 -0300 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop commit dcb51702e75e76ea901b198f14d28e021de9d62e Merge: 4769d75 dd0c1e2 Author: Davidson Gomes Date: Wed Jul 26 09:36:01 2023 -0300 Merge pull request #30 from codephix/patch-1 Update whatsapp.service.ts commit de0c9a1eff88aa1d22fad9ba9f8b8676caa4aa96 Author: Davidson Gomes Date: Wed Jul 26 09:34:10 2023 -0300 fix: fixed problems in localization template commit dd0c1e20a723b835407efbb3b96005de5a5a7680 Author: CodePhix Date: Tue Jul 25 19:59:42 2023 -0300 Update whatsapp.service.ts commit 4769d75dc3ea8f6508b80bbb7e0df86f5e1d4786 Merge: ecae077 6b926dc Author: Davidson Gomes Date: Tue Jul 25 16:20:04 2023 -0300 Merge tag '1.4.4' into develop * Fixed chatwoot line wrap issue * Solved receive location in chatwoot * When requesting the pairing code, it also brings the qr code * Option reopen_conversation in chatwoot endpoint * Option conversation_pending in chatwoot endpoint commit 6b926dc697c4efa8a387f94b4a449149068378c3 Merge: 2b6dbfd ecae077 Author: Davidson Gomes Date: Tue Jul 25 16:19:54 2023 -0300 Merge branch 'release/1.4.4' commit ecae077c6d50dc480934409efb00ee5f83a87389 Author: Davidson Gomes Date: Tue Jul 25 16:16:49 2023 -0300 fix: Option conversation_pending in chatwoot endpoint commit 78ab1bed359807d46d5728df54001612150c0832 Merge: 6bb1abd 2b6dbfd Author: Davidson Gomes Date: Tue Jul 25 15:31:16 2023 -0300 Merge tag '1.4.4' into develop * Fixed chatwoot line wrap issue * Solved receive location in chatwoot * When requesting the pairing code, it also brings the qr code * Option reopen_conversation in chatwoot endpoint * Option conversation_pending in chatwoot endpoint commit 2b6dbfde6bd7d52ef625a9ea95ff946de8568b03 Merge: 82b1567 6bb1abd Author: Davidson Gomes Date: Tue Jul 25 15:31:06 2023 -0300 Merge branch 'release/1.4.4' commit 6bb1abd7f0a186dd535cb11610fc860e078cb219 Author: Davidson Gomes Date: Tue Jul 25 15:29:42 2023 -0300 fix: Option conversation_pending in chatwoot endpoint commit aef92240cc09ab7c74574c24d5ab916de89c0bb6 Author: Davidson Gomes Date: Tue Jul 25 15:20:21 2023 -0300 fix: Option conversation_pending in chatwoot endpoint commit f0d8c2d0954bb5a5f9bf7e3db943b7b53bc6dbf9 Author: Davidson Gomes Date: Tue Jul 25 13:19:15 2023 -0300 fix: Solved receive location in chatwoot commit 14529f2c3580445a892a46dcdfdc25215e211d1a Author: Davidson Gomes Date: Tue Jul 25 12:47:35 2023 -0300 fix: When requesting the pairing code, it also brings the qr code commit 89f40d54d979b38d0583275b8fc20665d35bff20 Author: Davidson Gomes Date: Tue Jul 25 12:41:54 2023 -0300 fix: Solved receive location in chatwoot commit 4c006970a24c798a701c3a2adc1e573e0b8956be Author: Davidson Gomes Date: Tue Jul 25 11:52:26 2023 -0300 fix: Fixed chatwoot line wrap issue commit de676041dfe58340fd526a5d288efc75bbb9a83d Merge: 1cd7291 82b1567 Author: Davidson Gomes Date: Tue Jul 25 10:51:53 2023 -0300 Merge tag '1.4.3' into develop * Adjusts in settings with options always_online, read_messages and read_status * Fixed send webhook for event CALL * Create instance with settings commit 82b1567ae51acfd5af4940b5827a2f99dcb7ca7e Merge: f95f312 1cd7291 Author: Davidson Gomes Date: Tue Jul 25 10:51:42 2023 -0300 Merge branch 'release/1.4.3' commit 1cd7291068d8818aa6f3e8cfabe6ecfc6fc9fa19 Author: Davidson Gomes Date: Tue Jul 25 10:51:28 2023 -0300 version: 1.4.3 commit fdee1df5b32ef9d867819b83ab2acd9051a360e3 Author: Davidson Gomes Date: Tue Jul 25 10:42:45 2023 -0300 fix: Create instance with settings commit c314d00ccd98ae8bcc55b0873e2ccf1497fff88c Author: Davidson Gomes Date: Tue Jul 25 10:42:34 2023 -0300 fix: Create instance with settings commit 62e2a8a6e3a882e8350131aa53becc28ee862df7 Author: Davidson Gomes Date: Tue Jul 25 10:23:18 2023 -0300 fix: Fixed send webhook for event CALL commit a12231a0aa003a01510cec3dc7db5d8e430fb523 Author: Davidson Gomes Date: Tue Jul 25 09:57:28 2023 -0300 fix: Adjusts in settings with options always_online, read_messages and read_status commit 183efd427a86b4ef237504a3ecebd134b285bfe4 Merge: 4d9ca4b f95f312 Author: Davidson Gomes Date: Mon Jul 24 20:52:58 2023 -0300 Merge tag '1.4.2' into develop * Fixed validation is set settings * Adjusts in group validations * Ajusts in sticker message to chatwoot commit f95f3126c3adad5b1bd8b35e119987eca95b06e4 Merge: cc91f2e 4d9ca4b Author: Davidson Gomes Date: Mon Jul 24 20:52:46 2023 -0300 Merge branch 'release/1.4.2' commit 4d9ca4b4511ba997f28b4efa764b9079a180bcb4 Author: Davidson Gomes Date: Mon Jul 24 20:52:34 2023 -0300 version: 1.4.2 commit c76334a68aab4622d75abd905bbd59eaee8e2fa9 Author: Davidson Gomes Date: Mon Jul 24 20:32:29 2023 -0300 fix: Ajusts in sticker message to chatwoot commit f475391ba6b3c8af8d0fbdf02819b0a7bfacee80 Author: Davidson Gomes Date: Mon Jul 24 20:32:15 2023 -0300 fix: Ajusts in sticker message to chatwoot commit b77f22790bb5ea17133993f005d3613193698f3a Author: Davidson Gomes Date: Mon Jul 24 20:13:18 2023 -0300 fix: Fixed validation is set settings commit 757a578c6ec362c77564daf6ff0262fc73c7f8f6 Merge: c582476 f8e1892 Author: Davidson Gomes Date: Mon Jul 24 20:12:51 2023 -0300 Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop commit c5824767c845013c83dceb735b2e13a0606985e1 Author: Davidson Gomes Date: Mon Jul 24 20:11:49 2023 -0300 fix: Fixed validation is set settings commit 84f3f072794d054d0e7097f3495f28569b6a1147 Author: Davidson Gomes Date: Mon Jul 24 20:11:15 2023 -0300 fix: Fixed validation is set settings commit f8e1892eee3cd186e45cb5fd4fd79bf9b81cc20d Merge: 036a8ed 58ed6f3 Author: Davidson Gomes Date: Mon Jul 24 20:08:24 2023 -0300 fix: group validation Group validation commit 036a8edca0c3ebf00cbf1fcbccaca41c85b7b7ff Merge: 3d8e6f4 ef4be6a Author: Davidson Gomes Date: Mon Jul 24 20:07:05 2023 -0300 fix: Promote All Participants in Create Group Promote All Participants in Create Group commit 58ed6f395fce5ba7a8d8c7cc15592e981204cc15 Author: Alan Mosko Date: Mon Jul 24 19:59:09 2023 -0300 Validação de Grupo commit ef4be6a612ff50465d1e48925eef14d578592b68 Author: Alan Mosko Date: Mon Jul 24 19:53:03 2023 -0300 Start commit 3d8e6f439445334b060a0ce7ab4120601bb6f277 Merge: 8b6e577 0cc1f18 Author: Davidson Gomes Date: Mon Jul 24 19:08:39 2023 -0300 fix: Fixed mentions Fixed mentions commit 0cc1f18a7eaafaa851194a0955f5bbf9637350bf Author: Alan Mosko Date: Mon Jul 24 19:05:32 2023 -0300 [BUG] Correção de mencionar Caso seja enviado everyOne como false sem passar nada no mentioned commit 8b6e577b8ff94b28aea06e2b8f81fa38f6665fac Merge: f9abd90 cc91f2e Author: Davidson Gomes Date: Mon Jul 24 18:28:57 2023 -0300 Merge tag '1.4.1' into develop * Fixed reconnect with pairing code or qrcode * Fixed problem in createJid --- CHANGELOG.md | 33 + Docker/.env.example | 1 + Dockerfile | 1 + package.json | 2 +- src/config/env.config.ts | 408 +- src/dev-env.yml | 1 + src/validate/validate.schema.ts | 1441 +++-- .../controllers/chatwoot.controller.ts | 156 +- .../controllers/instance.controller.ts | 597 +- .../controllers/settings.controller.ts | 27 +- src/whatsapp/dto/chat.dto.ts | 89 +- src/whatsapp/dto/chatwoot.dto.ts | 16 +- src/whatsapp/dto/group.dto.ts | 39 +- src/whatsapp/dto/instance.dto.ts | 30 +- src/whatsapp/dto/settings.dto.ts | 9 +- src/whatsapp/models/chatwoot.model.ts | 41 +- src/whatsapp/models/settings.model.ts | 29 +- src/whatsapp/repository/repository.manager.ts | 209 +- src/whatsapp/services/chatwoot.service.ts | 2904 +++++---- src/whatsapp/services/whatsapp.service.ts | 5640 +++++++++-------- src/whatsapp/types/wa.types.ts | 150 +- src/whatsapp/whatsapp.module.ts | 107 +- 22 files changed, 6231 insertions(+), 5699 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd59c0d..cf5498ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# 1.4.5 (2023-07-26 09:32) + +### Fixed + +* Fixed problems in localization template in chatwoot +* Fix mids going duplicated in chatwoot + +# 1.4.4 (2023-07-25 15:24) + +### Fixed + +* Fixed chatwoot line wrap issue +* Solved receive location in chatwoot +* When requesting the pairing code, it also brings the qr code +* Option reopen_conversation in chatwoot endpoint +* Option conversation_pending in chatwoot endpoint + +# 1.4.3 (2023-07-25 10:51) + +### Fixed + +* Adjusts in settings with options always_online, read_messages and read_status +* Fixed send webhook for event CALL +* Create instance with settings + +# 1.4.2 (2023-07-24 20:52) + +### Fixed + +* Fixed validation is set settings +* Adjusts in group validations +* Ajusts in sticker message to chatwoot + # 1.4.1 (2023-07-24 18:28) ### Fixed diff --git a/Docker/.env.example b/Docker/.env.example index c3dbe505..f4e8291d 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -73,6 +73,7 @@ WEBHOOK_EVENTS_GROUPS_UPSERT=true WEBHOOK_EVENTS_GROUPS_UPDATE=true WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true WEBHOOK_EVENTS_CONNECTION_UPDATE=true +WEBHOOK_EVENTS_CALL=true # This event fires every time a new token is requested via the refresh route WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/Dockerfile b/Dockerfile index 93fa60c4..0b3ac950 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,6 +74,7 @@ ENV WEBHOOK_EVENTS_GROUPS_UPSERT=true ENV WEBHOOK_EVENTS_GROUPS_UPDATE=true ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true +ENV WEBHOOK_EVENTS_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/package.json b/package.json index 4d82309c..0e0407a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.1", + "version": "1.4.5", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 737fff51..78c90ec9 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -1,105 +1,114 @@ -import { isBooleanString } from 'class-validator'; import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; +import { isBooleanString } from 'class-validator'; export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { - ORIGIN: string[]; - METHODS: HttpMethods[]; - CREDENTIALS: boolean; + ORIGIN: string[]; + METHODS: HttpMethods[]; + CREDENTIALS: boolean; }; export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; -export type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS'; +export type LogLevel = + | 'ERROR' + | 'WARN' + | 'DEBUG' + | 'INFO' + | 'LOG' + | 'VERBOSE' + | 'DARK' + | 'WEBHOOKS'; export type Log = { - LEVEL: LogLevel[]; - COLOR: boolean; - BAILEYS: LogBaileys; + LEVEL: LogLevel[]; + COLOR: boolean; + BAILEYS: LogBaileys; }; export type SaveData = { - INSTANCE: boolean; - NEW_MESSAGE: boolean; - MESSAGE_UPDATE: boolean; - CONTACTS: boolean; - CHATS: boolean; + INSTANCE: boolean; + NEW_MESSAGE: boolean; + MESSAGE_UPDATE: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type StoreConf = { - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type CleanStoreConf = { - CLEANING_INTERVAL: number; - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + CLEANING_INTERVAL: number; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type DBConnection = { - URI: string; - DB_PREFIX_NAME: string; + URI: string; + DB_PREFIX_NAME: string; }; export type Database = { - CONNECTION: DBConnection; - ENABLED: boolean; - SAVE_DATA: SaveData; + CONNECTION: DBConnection; + ENABLED: boolean; + SAVE_DATA: SaveData; }; export type Redis = { - ENABLED: boolean; - URI: string; - PREFIX_KEY: string; + ENABLED: boolean; + URI: string; + PREFIX_KEY: string; }; export type EventsWebhook = { - APPLICATION_STARTUP: boolean; - QRCODE_UPDATED: boolean; - MESSAGES_SET: boolean; - MESSAGES_UPSERT: boolean; - MESSAGES_UPDATE: boolean; - MESSAGES_DELETE: boolean; - SEND_MESSAGE: boolean; - CONTACTS_SET: boolean; - CONTACTS_UPDATE: boolean; - CONTACTS_UPSERT: boolean; - PRESENCE_UPDATE: boolean; - CHATS_SET: boolean; - CHATS_UPDATE: boolean; - CHATS_DELETE: boolean; - CHATS_UPSERT: boolean; - CONNECTION_UPDATE: boolean; - GROUPS_UPSERT: boolean; - GROUP_UPDATE: boolean; - GROUP_PARTICIPANTS_UPDATE: boolean; - NEW_JWT_TOKEN: boolean; + APPLICATION_STARTUP: boolean; + QRCODE_UPDATED: boolean; + MESSAGES_SET: boolean; + MESSAGES_UPSERT: boolean; + MESSAGES_UPDATE: boolean; + MESSAGES_DELETE: boolean; + SEND_MESSAGE: boolean; + CONTACTS_SET: boolean; + CONTACTS_UPDATE: boolean; + CONTACTS_UPSERT: boolean; + PRESENCE_UPDATE: boolean; + CHATS_SET: boolean; + CHATS_UPDATE: boolean; + CHATS_DELETE: boolean; + CHATS_UPSERT: boolean; + CONNECTION_UPDATE: boolean; + GROUPS_UPSERT: boolean; + GROUP_UPDATE: boolean; + GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; + NEW_JWT_TOKEN: boolean; }; export type ApiKey = { KEY: string }; export type Jwt = { EXPIRIN_IN: number; SECRET: string }; export type Auth = { - API_KEY: ApiKey; - EXPOSE_IN_FETCH_INSTANCES: boolean; - JWT: Jwt; - TYPE: 'jwt' | 'apikey'; + API_KEY: ApiKey; + EXPOSE_IN_FETCH_INSTANCES: boolean; + JWT: Jwt; + TYPE: 'jwt' | 'apikey'; }; export type DelInstance = number | boolean; export type GlobalWebhook = { - URL: string; - ENABLED: boolean; - WEBHOOK_BY_EVENTS: boolean; + URL: string; + ENABLED: boolean; + WEBHOOK_BY_EVENTS: boolean; }; export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; @@ -108,157 +117,162 @@ export type QrCode = { LIMIT: number }; export type Production = boolean; export interface Env { - SERVER: HttpServer; - CORS: Cors; - SSL_CONF: SslConf; - STORE: StoreConf; - CLEAN_STORE: CleanStoreConf; - DATABASE: Database; - REDIS: Redis; - LOG: Log; - DEL_INSTANCE: DelInstance; - WEBHOOK: Webhook; - CONFIG_SESSION_PHONE: ConfigSessionPhone; - QRCODE: QrCode; - AUTHENTICATION: Auth; - PRODUCTION?: Production; + SERVER: HttpServer; + CORS: Cors; + SSL_CONF: SslConf; + STORE: StoreConf; + CLEAN_STORE: CleanStoreConf; + DATABASE: Database; + REDIS: Redis; + LOG: Log; + DEL_INSTANCE: DelInstance; + WEBHOOK: Webhook; + CONFIG_SESSION_PHONE: ConfigSessionPhone; + QRCODE: QrCode; + AUTHENTICATION: Auth; + PRODUCTION?: Production; } export type Key = keyof Env; export class ConfigService { - constructor() { - this.loadEnv(); - } + constructor() { + this.loadEnv(); + } - private env: Env; + private env: Env; - public get(key: Key) { - return this.env[key] as T; - } + public get(key: Key) { + return this.env[key] as T; + } - private loadEnv() { - this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); - this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; - if (process.env?.DOCKER_ENV === 'true') { - this.env.SERVER.TYPE = 'http'; - this.env.SERVER.PORT = 8080; - } + private loadEnv() { + this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); + this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; + if (process.env?.DOCKER_ENV === 'true') { + this.env.SERVER.TYPE = 'http'; + this.env.SERVER.PORT = 8080; } + } - private envYaml(): Env { - return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; - } + private envYaml(): Env { + return load( + readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' }), + ) as Env; + } - private envProcess(): Env { - return { - SERVER: { - TYPE: process.env.SERVER_TYPE as 'http' | 'https', - PORT: Number.parseInt(process.env.SERVER_PORT), - URL: process.env.SERVER_URL, - }, - CORS: { - ORIGIN: process.env.CORS_ORIGIN.split(','), - METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], - CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', - }, - SSL_CONF: { - PRIVKEY: process.env?.SSL_CONF_PRIVKEY, - FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, - }, - STORE: { - MESSAGES: process.env?.STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.STORE_CONTACTS === 'true', - CHATS: process.env?.STORE_CHATS === 'true', - }, - CLEAN_STORE: { - CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) - ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) - : 7200, - MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', - CHATS: process.env?.CLEAN_STORE_CHATS === 'true', - }, - DATABASE: { - CONNECTION: { - URI: process.env.DATABASE_CONNECTION_URI, - DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, - }, - ENABLED: process.env?.DATABASE_ENABLED === 'true', - SAVE_DATA: { - INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', - NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', - MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', - CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', - CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', - }, - }, - REDIS: { - ENABLED: process.env?.REDIS_ENABLED === 'true', - URI: process.env.REDIS_URI, - PREFIX_KEY: process.env.REDIS_PREFIX_KEY, - }, - LOG: { - LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], - COLOR: process.env?.LOG_COLOR === 'true', - BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', - }, - DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 'true' - : Number.parseInt(process.env.DEL_INSTANCE) || false, - WEBHOOK: { - GLOBAL: { - URL: process.env?.WEBHOOK_GLOBAL_URL, - ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', - WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', - }, - EVENTS: { - APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', - QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', - MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', - MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', - MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', - MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', - SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', - CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', - CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', - CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', - PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', - CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', - CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', - CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', - CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', - CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', - GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', - GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', - GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', - NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', - }, - }, - CONFIG_SESSION_PHONE: { - CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', - NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', - }, - QRCODE: { - LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, - }, - AUTHENTICATION: { - TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', - API_KEY: { - KEY: process.env.AUTHENTICATION_API_KEY, - }, - EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', - JWT: { - EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) - ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) - : 3600, - SECRET: process.env.AUTHENTICATION_JWT_SECRET, - }, - }, - }; - } + private envProcess(): Env { + return { + SERVER: { + TYPE: process.env.SERVER_TYPE as 'http' | 'https', + PORT: Number.parseInt(process.env.SERVER_PORT), + URL: process.env.SERVER_URL, + }, + CORS: { + ORIGIN: process.env.CORS_ORIGIN.split(','), + METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], + CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', + }, + SSL_CONF: { + PRIVKEY: process.env?.SSL_CONF_PRIVKEY, + FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, + }, + STORE: { + MESSAGES: process.env?.STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.STORE_CONTACTS === 'true', + CHATS: process.env?.STORE_CHATS === 'true', + }, + CLEAN_STORE: { + CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) + ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) + : 7200, + MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', + CHATS: process.env?.CLEAN_STORE_CHATS === 'true', + }, + DATABASE: { + CONNECTION: { + URI: process.env.DATABASE_CONNECTION_URI, + DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, + }, + ENABLED: process.env?.DATABASE_ENABLED === 'true', + SAVE_DATA: { + INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', + NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', + MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', + CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', + CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', + }, + }, + REDIS: { + ENABLED: process.env?.REDIS_ENABLED === 'true', + URI: process.env.REDIS_URI, + PREFIX_KEY: process.env.REDIS_PREFIX_KEY, + }, + LOG: { + LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], + COLOR: process.env?.LOG_COLOR === 'true', + BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', + }, + DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) + ? process.env.DEL_INSTANCE === 'true' + : Number.parseInt(process.env.DEL_INSTANCE) || false, + WEBHOOK: { + GLOBAL: { + URL: process.env?.WEBHOOK_GLOBAL_URL, + ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', + WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', + }, + EVENTS: { + APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', + QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', + MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', + MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', + MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', + MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', + SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', + CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', + CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', + CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', + PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', + CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', + CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', + CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', + CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', + CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', + GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', + GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', + GROUP_PARTICIPANTS_UPDATE: + process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', + NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', + }, + }, + CONFIG_SESSION_PHONE: { + CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', + }, + QRCODE: { + LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, + }, + AUTHENTICATION: { + TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', + API_KEY: { + KEY: process.env.AUTHENTICATION_API_KEY, + }, + EXPOSE_IN_FETCH_INSTANCES: + process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', + JWT: { + EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) + ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) + : 3600, + SECRET: process.env.AUTHENTICATION_JWT_SECRET, + }, + }, + }; + } } export const configService = new ConfigService(); diff --git a/src/dev-env.yml b/src/dev-env.yml index 41368ea4..b45d3201 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -110,6 +110,7 @@ WEBHOOK: GROUP_UPDATE: true GROUP_PARTICIPANTS_UPDATE: true CONNECTION_UPDATE: true + CALL: true # This event fires every time a new token is requested via the refresh route NEW_JWT_TOKEN: false diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index c83d6a61..d7e2ac1e 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -2,888 +2,923 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; import { v4 } from 'uuid'; const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => { - const properties = {}; - propertyNames.forEach( - (property) => - (properties[property] = { - minLength: 1, - description: `The "${property}" cannot be empty`, - }), - ); - return { - if: { - propertyNames: { - enum: [...propertyNames], - }, - }, - then: { properties }, - }; + const properties = {}; + propertyNames.forEach( + (property) => + (properties[property] = { + minLength: 1, + description: `The "${property}" cannot be empty`, + }), + ); + return { + if: { + propertyNames: { + enum: [...propertyNames], + }, + }, + then: { properties }, + }; }; // Instance Schema export const instanceNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - instanceName: { type: 'string' }, - webhook: { type: 'string' }, - webhook_by_events: { type: 'boolean' }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'NEW_JWT_TOKEN', - ], - }, - }, - qrcode: { type: 'boolean', enum: [true, false] }, - number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, - token: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + instanceName: { type: 'string' }, + webhook: { type: 'string' }, + webhook_by_events: { type: 'boolean' }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, }, - ...isNotEmpty('instanceName'), + qrcode: { type: 'boolean', enum: [true, false] }, + number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, + token: { type: 'string' }, + }, + ...isNotEmpty('instanceName'), }; export const oldTokenSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - oldToken: { type: 'string' }, - }, - required: ['oldToken'], - ...isNotEmpty('oldToken'), + $id: v4(), + type: 'object', + properties: { + oldToken: { type: 'string' }, + }, + required: ['oldToken'], + ...isNotEmpty('oldToken'), }; const quotedOptionsSchema: JSONSchema7 = { - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id'], - ...isNotEmpty('id'), - }, - message: { type: 'object' }, + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id'], + ...isNotEmpty('id'), }, + message: { type: 'object' }, + }, }; const mentionsOptionsSchema: JSONSchema7 = { - properties: { - everyOne: { type: 'boolean', enum: [true, false] }, - mentioned: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"mentioned" must be an array of numeric strings', - }, - }, + properties: { + everyOne: { type: 'boolean', enum: [true, false] }, + mentioned: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"mentioned" must be an array of numeric strings', + }, }, + }, }; // Send Message Schema const optionsSchema: JSONSchema7 = { - properties: { - delay: { - type: 'integer', - description: 'Enter a value in milliseconds', - }, - presence: { - type: 'string', - enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], - }, - quoted: { ...quotedOptionsSchema }, - mentions: { ...mentionsOptionsSchema }, + properties: { + delay: { + type: 'integer', + description: 'Enter a value in milliseconds', }, + presence: { + type: 'string', + enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], + }, + quoted: { ...quotedOptionsSchema }, + mentions: { ...mentionsOptionsSchema }, + }, }; const numberDefinition: JSONSchema7Definition = { - type: 'string', - description: 'Invalid format', + type: 'string', + description: 'Invalid format', }; export const textMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - textMessage: { - type: 'object', - properties: { - text: { type: 'string' }, - }, - required: ['text'], - ...isNotEmpty('text'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + textMessage: { + type: 'object', + properties: { + text: { type: 'string' }, + }, + required: ['text'], + ...isNotEmpty('text'), }, - required: ['textMessage', 'number'], + }, + required: ['textMessage', 'number'], }; export const pollMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - pollMessage: { - type: 'object', - properties: { - name: { type: 'string' }, - selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, - values: { - type: 'array', - minItems: 2, - maxItems: 10, - uniqueItems: true, - items: { - type: 'string', - }, - }, - }, - required: ['name', 'selectableCount', 'values'], - ...isNotEmpty('name', 'selectableCount', 'values'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + pollMessage: { + type: 'object', + properties: { + name: { type: 'string' }, + selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, + values: { + type: 'array', + minItems: 2, + maxItems: 10, + uniqueItems: true, + items: { + type: 'string', + }, }, + }, + required: ['name', 'selectableCount', 'values'], + ...isNotEmpty('name', 'selectableCount', 'values'), }, - required: ['pollMessage', 'number'], + }, + required: ['pollMessage', 'number'], }; export const statusMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - statusMessage: { - type: 'object', - properties: { - type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, - content: { type: 'string' }, - caption: { type: 'string' }, - backgroundColor: { type: 'string' }, - font: { type: 'integer', minimum: 0, maximum: 5 }, - statusJidList: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"statusJidList" must be an array of numeric strings', - }, - }, - allContacts: { type: 'boolean', enum: [true, false] }, - }, - required: ['type', 'content'], - ...isNotEmpty('type', 'content'), + $id: v4(), + type: 'object', + properties: { + statusMessage: { + type: 'object', + properties: { + type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, + content: { type: 'string' }, + caption: { type: 'string' }, + backgroundColor: { type: 'string' }, + font: { type: 'integer', minimum: 0, maximum: 5 }, + statusJidList: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"statusJidList" must be an array of numeric strings', + }, }, + allContacts: { type: 'boolean', enum: [true, false] }, + }, + required: ['type', 'content'], + ...isNotEmpty('type', 'content'), }, - required: ['statusMessage'], + }, + required: ['statusMessage'], }; export const mediaMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - mediaMessage: { - type: 'object', - properties: { - mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, - media: { type: 'string' }, - fileName: { type: 'string' }, - caption: { type: 'string' }, - }, - required: ['mediatype', 'media'], - ...isNotEmpty('fileName', 'caption', 'media'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + mediaMessage: { + type: 'object', + properties: { + mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, + media: { type: 'string' }, + fileName: { type: 'string' }, + caption: { type: 'string' }, + }, + required: ['mediatype', 'media'], + ...isNotEmpty('fileName', 'caption', 'media'), }, - required: ['mediaMessage', 'number'], + }, + required: ['mediaMessage', 'number'], }; export const stickerMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - stickerMessage: { - type: 'object', - properties: { - image: { type: 'string' }, - }, - required: ['image'], - ...isNotEmpty('image'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + stickerMessage: { + type: 'object', + properties: { + image: { type: 'string' }, + }, + required: ['image'], + ...isNotEmpty('image'), }, - required: ['stickerMessage', 'number'], + }, + required: ['stickerMessage', 'number'], }; export const audioMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - audioMessage: { - type: 'object', - properties: { - audio: { type: 'string' }, - }, - required: ['audio'], - ...isNotEmpty('audio'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + audioMessage: { + type: 'object', + properties: { + audio: { type: 'string' }, + }, + required: ['audio'], + ...isNotEmpty('audio'), }, - required: ['audioMessage', 'number'], + }, + required: ['audioMessage', 'number'], }; export const buttonMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - buttonMessage: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + buttonMessage: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttons: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { type: 'object', properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttons: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - buttonText: { type: 'string' }, - buttonId: { type: 'string' }, - }, - required: ['buttonText', 'buttonId'], - ...isNotEmpty('buttonText', 'buttonId'), - }, - }, - mediaMessage: { - type: 'object', - properties: { - media: { type: 'string' }, - fileName: { type: 'string' }, - mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, - }, - required: ['media', 'mediatype'], - ...isNotEmpty('media', 'fileName'), - }, + buttonText: { type: 'string' }, + buttonId: { type: 'string' }, }, - required: ['title', 'buttons'], - ...isNotEmpty('title', 'description'), + required: ['buttonText', 'buttonId'], + ...isNotEmpty('buttonText', 'buttonId'), + }, }, + mediaMessage: { + type: 'object', + properties: { + media: { type: 'string' }, + fileName: { type: 'string' }, + mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, + }, + required: ['media', 'mediatype'], + ...isNotEmpty('media', 'fileName'), + }, + }, + required: ['title', 'buttons'], + ...isNotEmpty('title', 'description'), }, - required: ['number', 'buttonMessage'], + }, + required: ['number', 'buttonMessage'], }; export const locationMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - locationMessage: { - type: 'object', - properties: { - latitude: { type: 'number' }, - longitude: { type: 'number' }, - name: { type: 'string' }, - address: { type: 'string' }, - }, - required: ['latitude', 'longitude'], - ...isNotEmpty('name', 'addresss'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + locationMessage: { + type: 'object', + properties: { + latitude: { type: 'number' }, + longitude: { type: 'number' }, + name: { type: 'string' }, + address: { type: 'string' }, + }, + required: ['latitude', 'longitude'], + ...isNotEmpty('name', 'addresss'), }, - required: ['number', 'locationMessage'], + }, + required: ['number', 'locationMessage'], }; export const listMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - listMessage: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + listMessage: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttonText: { type: 'string' }, + sections: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { type: 'object', properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttonText: { type: 'string' }, - sections: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - rows: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - rowId: { type: 'string' }, - }, - required: ['title', 'description', 'rowId'], - ...isNotEmpty('title', 'description', 'rowId'), - }, - }, - }, - required: ['title', 'rows'], - ...isNotEmpty('title'), - }, + title: { type: 'string' }, + rows: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + rowId: { type: 'string' }, + }, + required: ['title', 'description', 'rowId'], + ...isNotEmpty('title', 'description', 'rowId'), }, + }, }, - required: ['title', 'description', 'buttonText', 'sections'], - ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), + required: ['title', 'rows'], + ...isNotEmpty('title'), + }, }, + }, + required: ['title', 'description', 'buttonText', 'sections'], + ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - required: ['number', 'listMessage'], + }, + required: ['number', 'listMessage'], }; export const contactMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - contactMessage: { - type: 'array', - items: { - type: 'object', - properties: { - fullName: { type: 'string' }, - wuid: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"wuid" must be a numeric string', - }, - phoneNumber: { type: 'string', minLength: 10 }, - organization: { type: 'string' }, - email: { type: 'string' }, - url: { type: 'string' }, - }, - required: ['fullName', 'phoneNumber'], - ...isNotEmpty('fullName'), - }, - minItems: 1, - uniqueItems: true, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + contactMessage: { + type: 'array', + items: { + type: 'object', + properties: { + fullName: { type: 'string' }, + wuid: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"wuid" must be a numeric string', + }, + phoneNumber: { type: 'string', minLength: 10 }, + organization: { type: 'string' }, + email: { type: 'string' }, + url: { type: 'string' }, }, + required: ['fullName', 'phoneNumber'], + ...isNotEmpty('fullName'), + }, + minItems: 1, + uniqueItems: true, }, - required: ['number', 'contactMessage'], + }, + required: ['number', 'contactMessage'], }; export const reactionMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reactionMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'remoteJid', 'fromMe'], - ...isNotEmpty('id', 'remoteJid'), - }, - reaction: { type: 'string' }, - }, - required: ['key', 'reaction'], - ...isNotEmpty('reaction'), + $id: v4(), + type: 'object', + properties: { + reactionMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'remoteJid', 'fromMe'], + ...isNotEmpty('id', 'remoteJid'), }, + reaction: { type: 'string' }, + }, + required: ['key', 'reaction'], + ...isNotEmpty('reaction'), }, - required: ['reactionMessage'], + }, + required: ['reactionMessage'], }; // Chat Schema export const whatsappNumberSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - description: '"numbers" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + description: '"numbers" must be an array of numeric strings', + }, }, + }, }; export const readMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - readMessages: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, + $id: v4(), + type: 'object', + properties: { + read_messages: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, }, - required: ['readMessages'], + }, + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - privacySettings: { - type: 'object', - properties: { - readreceipts: { type: 'string', enum: ['all', 'none'] }, - profile: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - status: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - online: { type: 'string', enum: ['all', 'match_last_seen'] }, - last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, - groupadd: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - }, - required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], - ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), + $id: v4(), + type: 'object', + properties: { + privacySettings: { + type: 'object', + properties: { + readreceipts: { type: 'string', enum: ['all', 'none'] }, + profile: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], }, + status: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + online: { type: 'string', enum: ['all', 'match_last_seen'] }, + last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, + groupadd: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + }, + required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], + ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - required: ['privacySettings'], + }, + required: ['privacySettings'], }; export const archiveChatSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - lastMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, - messageTimestamp: { type: 'integer', minLength: 1 }, - }, - required: ['key'], - ...isNotEmpty('messageTimestamp'), + $id: v4(), + type: 'object', + properties: { + lastMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), }, - archive: { type: 'boolean', enum: [true, false] }, + messageTimestamp: { type: 'integer', minLength: 1 }, + }, + required: ['key'], + ...isNotEmpty('messageTimestamp'), }, - required: ['lastMessage', 'archive'], + archive: { type: 'boolean', enum: [true, false] }, + }, + required: ['lastMessage', 'archive'], }; export const deleteMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - participant: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid', 'participant'), + $id: v4(), + type: 'object', + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + participant: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid', 'participant'), }; export const contactValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - pushName: { type: 'string', minLength: 1 }, - id: { type: 'string', minLength: 1 }, - }, - ...isNotEmpty('_id', 'id', 'pushName'), - }, + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + pushName: { type: 'string', minLength: 1 }, + id: { type: 'string', minLength: 1 }, + }, + ...isNotEmpty('_id', 'id', 'pushName'), }, + }, }; export const profileNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - name: { type: 'string' }, - }, - ...isNotEmpty('name'), + $id: v4(), + type: 'object', + properties: { + name: { type: 'string' }, + }, + ...isNotEmpty('name'), }; export const profileStatusSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - status: { type: 'string' }, - }, - ...isNotEmpty('status'), + $id: v4(), + type: 'object', + properties: { + status: { type: 'string' }, + }, + ...isNotEmpty('status'), }; export const profilePictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { type: 'string' }, - picture: { type: 'string' }, - }, + $id: v4(), + type: 'object', + properties: { + number: { type: 'string' }, + picture: { type: 'string' }, + }, }; export const profileSchema: JSONSchema7 = { - type: 'object', - properties: { - wuid: { type: 'string' }, - name: { type: 'string' }, - picture: { type: 'string' }, - status: { type: 'string' }, - isBusiness: { type: 'boolean' }, - }, + type: 'object', + properties: { + wuid: { type: 'string' }, + name: { type: 'string' }, + picture: { type: 'string' }, + status: { type: 'string' }, + isBusiness: { type: 'boolean' }, + }, }; export const messageValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - key: { - type: 'object', - if: { - propertyNames: { - enum: ['fromMe', 'remoteJid', 'id'], - }, - }, - then: { - properties: { - remoteJid: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - id: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - }, - }, - message: { type: 'object' }, + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + key: { + type: 'object', + if: { + propertyNames: { + enum: ['fromMe', 'remoteJid', 'id'], }, - ...isNotEmpty('_id'), + }, + then: { + properties: { + remoteJid: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + id: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + }, }, - limit: { type: 'integer' }, + message: { type: 'object' }, + }, + ...isNotEmpty('_id'), }, + limit: { type: 'integer' }, + }, }; export const messageUpSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string' }, - remoteJid: { type: 'string' }, - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - participant: { type: 'string' }, - status: { - type: 'string', - enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], - }, - }, - ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string' }, + remoteJid: { type: 'string' }, + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + participant: { type: 'string' }, + status: { + type: 'string', + enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], }, - limit: { type: 'integer' }, + }, + ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), }, + limit: { type: 'integer' }, + }, }; // Group Schema export const createGroupSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - subject: { type: 'string' }, - description: { type: 'string' }, - profilePicture: { type: 'string' }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + subject: { type: 'string' }, + description: { type: 'string' }, + profilePicture: { type: 'string' }, + promoteParticipants: { type: 'boolean', enum: [true, false] }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, }, - required: ['subject', 'participants'], - ...isNotEmpty('subject', 'description', 'profilePicture'), + }, + required: ['subject', 'participants'], + ...isNotEmpty('subject', 'description', 'profilePicture'), }; export const groupJidSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, - }, - required: ['groupJid'], - ...isNotEmpty('groupJid'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, + }, + required: ['groupJid'], + ...isNotEmpty('groupJid'), }; export const getParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - getParticipants: { type: 'string', enum: ['true', 'false'] }, - }, - required: ['getParticipants'], - ...isNotEmpty('getParticipants'), + $id: v4(), + type: 'object', + properties: { + getParticipants: { type: 'string', enum: ['true', 'false'] }, + }, + required: ['getParticipants'], + ...isNotEmpty('getParticipants'), }; export const groupSendInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"numbers" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"numbers" must be an array of numeric strings', + }, }, - required: ['groupJid', 'description', 'numbers'], - ...isNotEmpty('groupJid', 'description', 'numbers'), + }, + required: ['groupJid', 'description', 'numbers'], + ...isNotEmpty('groupJid', 'description', 'numbers'), }; export const groupInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, - }, - required: ['inviteCode'], - ...isNotEmpty('inviteCode'), + $id: v4(), + type: 'object', + properties: { + inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, + }, + required: ['inviteCode'], + ...isNotEmpty('inviteCode'), }; export const updateParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['add', 'remove', 'promote', 'demote'], - }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['add', 'remove', 'promote', 'demote'], }, - required: ['groupJid', 'action', 'participants'], - ...isNotEmpty('groupJid', 'action'), + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, + }, + required: ['groupJid', 'action', 'participants'], + ...isNotEmpty('groupJid', 'action'), }; export const updateSettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], }, - required: ['groupJid', 'action'], - ...isNotEmpty('groupJid', 'action'), + }, + required: ['groupJid', 'action'], + ...isNotEmpty('groupJid', 'action'), }; export const toggleEphemeralSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - expiration: { - type: 'number', - enum: [0, 86400, 604800, 7776000], - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + expiration: { + type: 'number', + enum: [0, 86400, 604800, 7776000], }, - required: ['groupJid', 'expiration'], - ...isNotEmpty('groupJid', 'expiration'), + }, + required: ['groupJid', 'expiration'], + ...isNotEmpty('groupJid', 'expiration'), }; export const updateGroupPictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - image: { type: 'string' }, - }, - required: ['groupJid', 'image'], - ...isNotEmpty('groupJid', 'image'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + image: { type: 'string' }, + }, + required: ['groupJid', 'image'], + ...isNotEmpty('groupJid', 'image'), }; export const updateGroupSubjectSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - subject: { type: 'string' }, - }, - required: ['groupJid', 'subject'], - ...isNotEmpty('groupJid', 'subject'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + subject: { type: 'string' }, + }, + required: ['groupJid', 'subject'], + ...isNotEmpty('groupJid', 'subject'), }; export const updateGroupDescriptionSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - }, - required: ['groupJid', 'description'], - ...isNotEmpty('groupJid', 'description'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + }, + required: ['groupJid', 'description'], + ...isNotEmpty('groupJid', 'description'), }; // Webhook Schema export const webhookSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - url: { type: 'string' }, - enabled: { type: 'boolean', enum: [true, false] }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'NEW_JWT_TOKEN', - ], - }, - }, + $id: v4(), + type: 'object', + properties: { + url: { type: 'string' }, + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, }, - required: ['url', 'enabled'], - ...isNotEmpty('url'), + }, + required: ['url', 'enabled'], + ...isNotEmpty('url'), }; export const chatwootSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - enabled: { type: 'boolean', enum: [true, false] }, - account_id: { type: 'string' }, - token: { type: 'string' }, - url: { type: 'string' }, - sign_msg: { type: 'boolean', enum: [true, false] }, - }, - required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], - ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + account_id: { type: 'string' }, + token: { type: 'string' }, + url: { type: 'string' }, + sign_msg: { type: 'boolean', enum: [true, false] }, + reopen_conversation: { type: 'boolean', enum: [true, false] }, + conversation_pending: { type: 'boolean', enum: [true, false] }, + }, + required: [ + 'enabled', + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ], + ...isNotEmpty( + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ), }; export const settingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reject_call: { type: 'boolean', enum: [true, false] }, - msg_call: { type: 'string' }, - groups_ignore: { type: 'boolean', enum: [true, false] }, - }, - required: ['reject_call'], - ...isNotEmpty('reject_call'), + $id: v4(), + type: 'object', + properties: { + reject_call: { type: 'boolean', enum: [true, false] }, + msg_call: { type: 'string' }, + groups_ignore: { type: 'boolean', enum: [true, false] }, + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, + }, + required: [ + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ], + ...isNotEmpty( + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ), }; diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index d4563485..ad92e607 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -1,97 +1,105 @@ import { isURL } from 'class-validator'; - -import { ConfigService, HttpServer } from '../../config/env.config'; -import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; -import { ChatwootDto } from '../dto/chatwoot.dto'; import { InstanceDto } from '../dto/instance.dto'; +import { ChatwootDto } from '../dto/chatwoot.dto'; import { ChatwootService } from '../services/chatwoot.service'; +import { Logger } from '../../config/logger.config'; import { waMonitor } from '../whatsapp.module'; +import { ConfigService, HttpServer } from '../../config/env.config'; const logger = new Logger('ChatwootController'); export class ChatwootController { - constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} + constructor( + private readonly chatwootService: ChatwootService, + private readonly configService: ConfigService, + ) {} - public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { - logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); + public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { + logger.verbose( + 'requested createChatwoot from ' + instance.instanceName + ' instance', + ); - if (data.enabled) { - if (!isURL(data.url, { require_tld: false })) { - throw new BadRequestException('url is not valid'); - } + if (data.enabled) { + if (!isURL(data.url, { require_tld: false })) { + throw new BadRequestException('url is not valid'); + } - if (!data.account_id) { - throw new BadRequestException('account_id is required'); - } + if (!data.account_id) { + throw new BadRequestException('account_id is required'); + } - if (!data.token) { - throw new BadRequestException('token is required'); - } + if (!data.token) { + throw new BadRequestException('token is required'); + } - if (data.sign_msg !== true && data.sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } - } - - if (!data.enabled) { - logger.verbose('chatwoot disabled'); - data.account_id = ''; - data.token = ''; - data.url = ''; - data.sign_msg = false; - } - - data.name_inbox = instance.instanceName; - - const result = this.chatwootService.create(instance, data); - - const urlServer = this.configService.get('SERVER').URL; - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; + if (data.sign_msg !== true && data.sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } } - public async findChatwoot(instance: InstanceDto) { - logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); - const result = await this.chatwootService.find(instance); - - const urlServer = this.configService.get('SERVER').URL; - - if (Object.keys(result).length === 0) { - return { - enabled: false, - url: '', - account_id: '', - token: '', - sign_msg: false, - name_inbox: '', - webhook_url: '', - }; - } - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; + if (!data.enabled) { + logger.verbose('chatwoot disabled'); + data.account_id = ''; + data.token = ''; + data.url = ''; + data.sign_msg = false; + data.reopen_conversation = false; + data.conversation_pending = false; } - public async receiveWebhook(instance: InstanceDto, data: any) { - logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); - const chatwootService = new ChatwootService(waMonitor, this.configService); + data.name_inbox = instance.instanceName; - return chatwootService.receiveWebhook(instance, data); + const result = this.chatwootService.create(instance, data); + + const urlServer = this.configService.get('SERVER').URL; + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; + } + + public async findChatwoot(instance: InstanceDto) { + logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); + const result = await this.chatwootService.find(instance); + + const urlServer = this.configService.get('SERVER').URL; + + if (Object.keys(result).length === 0) { + return { + enabled: false, + url: '', + account_id: '', + token: '', + sign_msg: false, + name_inbox: '', + webhook_url: '', + }; } - public async newInstance(data: any) { - const chatwootService = new ChatwootService(waMonitor, this.configService); + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; - return chatwootService.newInstance(data); - } + return response; + } + + public async receiveWebhook(instance: InstanceDto, data: any) { + logger.verbose( + 'requested receiveWebhook from ' + instance.instanceName + ' instance', + ); + const chatwootService = new ChatwootService(waMonitor, this.configService); + + return chatwootService.receiveWebhook(instance, data); + } + + public async newInstance(data: any) { + const chatwootService = new ChatwootService(waMonitor, this.configService); + + return chatwootService.newInstance(data); + } } diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 79449e29..d9c351f7 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -1,309 +1,376 @@ import { delay } from '@whiskeysockets/baileys'; -import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; - -import { ConfigService, HttpServer } from '../../config/env.config'; -import { Logger } from '../../config/logger.config'; -import { RedisCache } from '../../db/redis.client'; +import { Auth, ConfigService, HttpServer } from '../../config/env.config'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; -import { ChatwootService } from '../services/chatwoot.service'; import { WAMonitoringService } from '../services/monitor.service'; -import { WebhookService } from '../services/webhook.service'; import { WAStartupService } from '../services/whatsapp.service'; +import { WebhookService } from '../services/webhook.service'; +import { ChatwootService } from '../services/chatwoot.service'; +import { Logger } from '../../config/logger.config'; import { wa } from '../types/wa.types'; +import { RedisCache } from '../../db/redis.client'; +import { isURL } from 'class-validator'; +import { SettingsService } from '../services/settings.service'; export class InstanceController { - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly eventEmitter: EventEmitter2, - private readonly authService: AuthService, - private readonly webhookService: WebhookService, - private readonly chatwootService: ChatwootService, - private readonly cache: RedisCache, - ) {} + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly eventEmitter: EventEmitter2, + private readonly authService: AuthService, + private readonly webhookService: WebhookService, + private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, + private readonly cache: RedisCache, + ) {} - private readonly logger = new Logger(InstanceController.name); + private readonly logger = new Logger(InstanceController.name); - public async createInstance({ - instanceName, + public async createInstance({ + instanceName, + webhook, + webhook_by_events, + events, + qrcode, + number, + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + chatwoot_reopen_conversation, + chatwoot_conversation_pending, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, + }: InstanceDto) { + try { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException( + 'The instance name must be lowercase and without special characters', + ); + } + + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); + + this.logger.verbose('creating instance'); + const instance = new WAStartupService( + this.configService, + this.eventEmitter, + this.repository, + this.cache, + ); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); + + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + let getEvents: string[]; + + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } + + this.logger.verbose('creating webhook'); + try { + this.webhookService.create(instance, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); + + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; + + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + settings, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + + if ( + chatwoot_reopen_conversation !== true && + chatwoot_reopen_conversation !== false + ) { + throw new BadRequestException('reopen_conversation is required'); + } + + if ( + chatwoot_conversation_pending !== true && + chatwoot_conversation_pending !== false + ) { + throw new BadRequestException('conversation_pending is required'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + }); + + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); + } catch (error) { + this.logger.log(error); + } + + return { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, webhook, webhook_by_events, - events, - qrcode, - number, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - }: InstanceDto) { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + events: getEvents, + settings, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, + }; + } catch (error) { + console.log(error); + return { error: true, message: error.toString() }; + } + } - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException('The instance name must be lowercase and without special characters'); - } + public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { + try { + this.logger.verbose( + 'requested connectToWhatsapp from ' + instanceName + ' instance', + ); - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); + const instance = this.waMonitor.waInstances[instanceName]; + const state = instance?.connectionStatus?.state; - this.logger.verbose('creating instance'); - const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); + this.logger.verbose('state: ' + state); - this.logger.verbose('instance: ' + instance.instanceName + ' created'); + if (state == 'open') { + return await this.connectionState({ instanceName }); + } - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); + if (state == 'connecting') { + return instance.qrCode; + } - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); + if (state == 'close') { + this.logger.verbose('connecting'); + await instance.connectToWhatsapp(number); - this.logger.verbose('hash: ' + hash + ' generated'); + await delay(5000); + return instance.qrCode; + } - let getEvents: string[]; + return { + instance: { + instanceName: instanceName, + status: state, + }, + qrcode: instance?.qrCode, + }; + } catch (error) { + this.logger.error(error); + } + } - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } + public async restartInstance({ instanceName }: InstanceDto) { + try { + this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); + this.logger.verbose('logging out instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } + return { error: false, message: 'Instance restarted' }; + } catch (error) { + this.logger.error(error); + } + } - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; + public async connectionState({ instanceName }: InstanceDto) { + this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); + return { + instance: { + instanceName: instanceName, + state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, + }, + }; + } - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - qrcode: getQrcode, - }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - number, - ); - } catch (error) { - this.logger.log(error); - } - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; + public async fetchInstances({ instanceName }: InstanceDto) { + this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); + if (instanceName) { + this.logger.verbose('instanceName: ' + instanceName); + return this.waMonitor.instanceInfo(instanceName); } - public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { - try { - this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); + return this.waMonitor.instanceInfo(); + } - const instance = this.waMonitor.waInstances[instanceName]; - const state = instance?.connectionStatus?.state; + public async logout({ instanceName }: InstanceDto) { + this.logger.verbose('requested logout from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); - this.logger.verbose('state: ' + state); - - if (state == 'open') { - return await this.connectionState({ instanceName }); - } - - if (state == 'connecting') { - return instance.qrCode; - } - - if (state == 'close') { - this.logger.verbose('connecting'); - await instance.connectToWhatsapp(number); - - await delay(5000); - return instance.qrCode; - } - - return { - instance: { - instanceName: instanceName, - status: state, - }, - qrcode: instance?.qrCode, - }; - } catch (error) { - this.logger.error(error); - } + if (instance.state === 'close') { + throw new BadRequestException( + 'The "' + instanceName + '" instance is not connected', + ); } - public async restartInstance({ instanceName }: InstanceDto) { - try { - this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); + try { + this.logger.verbose('logging out instance: ' + instanceName); + await this.waMonitor.waInstances[instanceName]?.client?.logout( + 'Log out instance: ' + instanceName, + ); - this.logger.verbose('logging out instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + this.logger.verbose('close connection instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - return { error: false, message: 'Instance restarted' }; - } catch (error) { - this.logger.error(error); - } + return { error: false, message: 'Instance logged out' }; + } catch (error) { + throw new InternalServerErrorException(error.toString()); } + } - public async connectionState({ instanceName }: InstanceDto) { - this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); - return { - instance: { - instanceName: instanceName, - state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, - }, - }; + public async deleteInstance({ instanceName }: InstanceDto) { + this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); + + if (instance.state === 'open') { + throw new BadRequestException( + 'The "' + instanceName + '" instance needs to be disconnected', + ); } + try { + if (instance.state === 'connecting') { + this.logger.verbose('logging out instance: ' + instanceName); - public async fetchInstances({ instanceName }: InstanceDto) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); - if (instanceName) { - this.logger.verbose('instanceName: ' + instanceName); - return this.waMonitor.instanceInfo(instanceName); - } + await this.logout({ instanceName }); + delete this.waMonitor.waInstances[instanceName]; + return { error: false, message: 'Instance deleted' }; + } else { + this.logger.verbose('deleting instance: ' + instanceName); - return this.waMonitor.instanceInfo(); + delete this.waMonitor.waInstances[instanceName]; + this.eventEmitter.emit('remove.instance', instanceName, 'inner'); + return { error: false, message: 'Instance deleted' }; + } + } catch (error) { + throw new BadRequestException(error.toString()); } + } - public async logout({ instanceName }: InstanceDto) { - this.logger.verbose('requested logout from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); - - if (instance.state === 'close') { - throw new BadRequestException('The "' + instanceName + '" instance is not connected'); - } - - try { - this.logger.verbose('logging out instance: ' + instanceName); - await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); - - this.logger.verbose('close connection instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - - return { error: false, message: 'Instance logged out' }; - } catch (error) { - throw new InternalServerErrorException(error.toString()); - } - } - - public async deleteInstance({ instanceName }: InstanceDto) { - this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); - - if (instance.state === 'open') { - throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); - } - try { - if (instance.state === 'connecting') { - this.logger.verbose('logging out instance: ' + instanceName); - - await this.logout({ instanceName }); - delete this.waMonitor.waInstances[instanceName]; - return { error: false, message: 'Instance deleted' }; - } else { - this.logger.verbose('deleting instance: ' + instanceName); - - delete this.waMonitor.waInstances[instanceName]; - this.eventEmitter.emit('remove.instance', instanceName, 'inner'); - return { error: false, message: 'Instance deleted' }; - } - } catch (error) { - throw new BadRequestException(error.toString()); - } - } - - public async refreshToken(_: InstanceDto, oldToken: OldToken) { - this.logger.verbose('requested refreshToken'); - return await this.authService.refreshToken(oldToken); - } + public async refreshToken(_: InstanceDto, oldToken: OldToken) { + this.logger.verbose('requested refreshToken'); + return await this.authService.refreshToken(oldToken); + } } diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 1d033783..f538abe6 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -1,26 +1,25 @@ -import { Logger } from '../../config/logger.config'; +import { isURL } from 'class-validator'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { SettingsService } from '../services/settings.service'; +import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsController'); export class SettingsController { - constructor(private readonly settingsService: SettingsService) {} + constructor(private readonly settingsService: SettingsService) {} - public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); + public async createSettings(instance: InstanceDto, data: SettingsDto) { + logger.verbose( + 'requested createSettings from ' + instance.instanceName + ' instance', + ); - if (data.reject_call && data.msg_call.trim() == '') { - throw new BadRequestException('msg_call is required'); - } + return this.settingsService.create(instance, data); + } - return this.settingsService.create(instance, data); - } - - public async findSettings(instance: InstanceDto) { - logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.find(instance); - } + public async findSettings(instance: InstanceDto) { + logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); + return this.settingsService.find(instance); + } } diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 38f17bf0..4681ef76 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,84 +1,93 @@ -import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; +import { + WAPrivacyOnlineValue, + WAPrivacyValue, + WAReadReceiptsValue, + proto, +} from '@whiskeysockets/baileys'; export class OnWhatsAppDto { - constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} + constructor( + public readonly jid: string, + public readonly exists: boolean, + public readonly name?: string, + ) {} } export class getBase64FromMediaMessageDto { - message: proto.WebMessageInfo; - convertToMp4?: boolean; + message: proto.WebMessageInfo; + convertToMp4?: boolean; } export class WhatsAppNumberDto { - numbers: string[]; + numbers: string[]; } export class NumberDto { - number: string; + number: string; } export class NumberBusiness { - wid?: string; - jid?: string; - exists?: boolean; - isBusiness: boolean; - name?: string; - message?: string; - description?: string; - email?: string; - website?: string[]; - address?: string; + wid?: string; + jid?: string; + exists?: boolean; + isBusiness: boolean; + name?: string; + message?: string; + description?: string; + email?: string; + website?: string[]; + address?: string; } export class ProfileNameDto { - name: string; + name: string; } export class ProfileStatusDto { - status: string; + status: string; } export class ProfilePictureDto { - number?: string; - // url or base64 - picture?: string; + number?: string; + // url or base64 + picture?: string; } class Key { - id: string; - fromMe: boolean; - remoteJid: string; + id: string; + fromMe: boolean; + remoteJid: string; } export class ReadMessageDto { - readMessages: Key[]; + read_messages: Key[]; } class LastMessage { - key: Key; - messageTimestamp?: number; + key: Key; + messageTimestamp?: number; } export class ArchiveChatDto { - lastMessage: LastMessage; - archive: boolean; + lastMessage: LastMessage; + archive: boolean; } class PrivacySetting { - readreceipts: WAReadReceiptsValue; - profile: WAPrivacyValue; - status: WAPrivacyValue; - online: WAPrivacyOnlineValue; - last: WAPrivacyValue; - groupadd: WAPrivacyValue; + readreceipts: WAReadReceiptsValue; + profile: WAPrivacyValue; + status: WAPrivacyValue; + online: WAPrivacyOnlineValue; + last: WAPrivacyValue; + groupadd: WAPrivacyValue; } export class PrivacySettingDto { - privacySettings: PrivacySetting; + privacySettings: PrivacySetting; } export class DeleteMessage { - id: string; - fromMe: boolean; - remoteJid: string; - participant?: string; + id: string; + fromMe: boolean; + remoteJid: string; + participant?: string; } diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index 64a2f1b6..b270c869 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -1,9 +1,11 @@ export class ChatwootDto { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index ef47f9b8..6dfdc45c 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,51 +1,52 @@ export class CreateGroupDto { - subject: string; - description?: string; - participants: string[]; + subject: string; + participants: string[]; + description?: string; + promoteParticipants?: boolean; } export class GroupPictureDto { - groupJid: string; - image: string; + groupJid: string; + image: string; } export class GroupSubjectDto { - groupJid: string; - subject: string; + groupJid: string; + subject: string; } export class GroupDescriptionDto { - groupJid: string; - description: string; + groupJid: string; + description: string; } export class GroupJid { - groupJid: string; + groupJid: string; } export class GetParticipant { - getParticipants: string; + getParticipants: string; } export class GroupInvite { - inviteCode: string; + inviteCode: string; } export class GroupSendInvite { - groupJid: string; - description: string; - numbers: string[]; + groupJid: string; + description: string; + numbers: string[]; } export class GroupUpdateParticipantDto extends GroupJid { - action: 'add' | 'remove' | 'promote' | 'demote'; - participants: string[]; + action: 'add' | 'remove' | 'promote' | 'demote'; + participants: string[]; } export class GroupUpdateSettingDto extends GroupJid { - action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; + action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; } export class GroupToggleEphemeralDto extends GroupJid { - expiration: 0 | 86400 | 604800 | 7776000; + expiration: 0 | 86400 | 604800 | 7776000; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 3fc780d1..c317060f 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,13 +1,21 @@ export class InstanceDto { - instanceName: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; - qrcode?: boolean; - number?: string; - token?: string; - chatwoot_account_id?: string; - chatwoot_token?: string; - chatwoot_url?: string; - chatwoot_sign_msg?: boolean; + instanceName: string; + qrcode?: boolean; + number?: string; + token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + chatwoot_account_id?: string; + chatwoot_token?: string; + chatwoot_url?: string; + chatwoot_sign_msg?: boolean; + chatwoot_reopen_conversation?: boolean; + chatwoot_conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 870a24d9..594ab3a4 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -1,5 +1,8 @@ export class SettingsDto { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 31e28894..bac226e9 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -1,28 +1,33 @@ import { Schema } from 'mongoose'; - import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { - _id?: string; - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; + _id?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } const chatwootSchema = new Schema({ - _id: { type: String, _id: true }, - enabled: { type: Boolean, required: true }, - account_id: { type: String, required: true }, - token: { type: String, required: true }, - url: { type: String, required: true }, - name_inbox: { type: String, required: true }, - sign_msg: { type: Boolean, required: true }, - number: { type: String, required: true }, + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + account_id: { type: String, required: true }, + token: { type: String, required: true }, + url: { type: String, required: true }, + name_inbox: { type: String, required: true }, + sign_msg: { type: Boolean, required: true }, + number: { type: String, required: true }, }); -export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot'); +export const ChatwootModel = dbserver?.model( + ChatwootRaw.name, + chatwootSchema, + 'chatwoot', +); export type IChatwootModel = typeof ChatwootModel; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index 283f44fd..b6d2488d 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -1,20 +1,29 @@ import { Schema } from 'mongoose'; - import { dbserver } from '../../db/db.connect'; export class SettingsRaw { - _id?: string; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; + _id?: string; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ - _id: { type: String, _id: true }, - reject_call: { type: Boolean, required: true }, - msg_call: { type: String, required: true }, - groups_ignore: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + reject_call: { type: Boolean, required: true }, + msg_call: { type: String, required: true }, + groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); -export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings'); +export const SettingsModel = dbserver?.model( + SettingsRaw.name, + settingsSchema, + 'settings', +); export type ISettingsModel = typeof SettingsModel; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 57a206b8..d506cc46 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -1,112 +1,121 @@ -import fs from 'fs'; -import { MongoClient } from 'mongodb'; -import { join } from 'path'; - -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { Logger } from '../../config/logger.config'; -import { AuthRepository } from './auth.repository'; -import { ChatRepository } from './chat.repository'; -import { ChatwootRepository } from './chatwoot.repository'; -import { ContactRepository } from './contact.repository'; import { MessageRepository } from './message.repository'; +import { ChatRepository } from './chat.repository'; +import { ContactRepository } from './contact.repository'; import { MessageUpRepository } from './messageUp.repository'; -import { SettingsRepository } from './settings.repository'; +import { MongoClient } from 'mongodb'; import { WebhookRepository } from './webhook.repository'; +import { ChatwootRepository } from './chatwoot.repository'; +import { SettingsRepository } from './settings.repository'; + +import { AuthRepository } from './auth.repository'; +import { Auth, ConfigService, Database } from '../../config/env.config'; +import { join } from 'path'; +import fs from 'fs'; +import { Logger } from '../../config/logger.config'; export class RepositoryBroker { - constructor( - public readonly message: MessageRepository, - public readonly chat: ChatRepository, - public readonly contact: ContactRepository, - public readonly messageUpdate: MessageUpRepository, - public readonly webhook: WebhookRepository, - public readonly chatwoot: ChatwootRepository, - public readonly settings: SettingsRepository, - public readonly auth: AuthRepository, - private configService: ConfigService, - dbServer?: MongoClient, - ) { - this.dbClient = dbServer; - this.__init_repo_without_db__(); - } + constructor( + public readonly message: MessageRepository, + public readonly chat: ChatRepository, + public readonly contact: ContactRepository, + public readonly messageUpdate: MessageUpRepository, + public readonly webhook: WebhookRepository, + public readonly chatwoot: ChatwootRepository, + public readonly settings: SettingsRepository, + public readonly auth: AuthRepository, + private configService: ConfigService, + dbServer?: MongoClient, + ) { + this.dbClient = dbServer; + this.__init_repo_without_db__(); + } - private dbClient?: MongoClient; - private readonly logger = new Logger('RepositoryBroker'); + private dbClient?: MongoClient; + private readonly logger = new Logger('RepositoryBroker'); - public get dbServer() { - return this.dbClient; - } + public get dbServer() { + return this.dbClient; + } - private __init_repo_without_db__() { - this.logger.verbose('initializing repository without db'); - if (!this.configService.get('DATABASE').ENABLED) { - const storePath = join(process.cwd(), 'store'); + private __init_repo_without_db__() { + this.logger.verbose('initializing repository without db'); + if (!this.configService.get('DATABASE').ENABLED) { + const storePath = join(process.cwd(), 'store'); - this.logger.verbose('creating store path: ' + storePath); - try { - const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); - const chatsDir = join(storePath, 'chats'); - const contactsDir = join(storePath, 'contacts'); - const messagesDir = join(storePath, 'messages'); - const messageUpDir = join(storePath, 'message-up'); - const webhookDir = join(storePath, 'webhook'); - const chatwootDir = join(storePath, 'chatwoot'); - const settingsDir = join(storePath, 'settings'); - const tempDir = join(storePath, 'temp'); + this.logger.verbose('creating store path: ' + storePath); + try { + const authDir = join( + storePath, + 'auth', + this.configService.get('AUTHENTICATION').TYPE, + ); + const chatsDir = join(storePath, 'chats'); + const contactsDir = join(storePath, 'contacts'); + const messagesDir = join(storePath, 'messages'); + const messageUpDir = join(storePath, 'message-up'); + const webhookDir = join(storePath, 'webhook'); + const chatwootDir = join(storePath, 'chatwoot'); + const settingsDir = join(storePath, 'settings'); + const tempDir = join(storePath, 'temp'); - if (!fs.existsSync(authDir)) { - this.logger.verbose('creating auth dir: ' + authDir); - fs.mkdirSync(authDir, { recursive: true }); - } - if (!fs.existsSync(chatsDir)) { - this.logger.verbose('creating chats dir: ' + chatsDir); - fs.mkdirSync(chatsDir, { recursive: true }); - } - if (!fs.existsSync(contactsDir)) { - this.logger.verbose('creating contacts dir: ' + contactsDir); - fs.mkdirSync(contactsDir, { recursive: true }); - } - if (!fs.existsSync(messagesDir)) { - this.logger.verbose('creating messages dir: ' + messagesDir); - fs.mkdirSync(messagesDir, { recursive: true }); - } - if (!fs.existsSync(messageUpDir)) { - this.logger.verbose('creating message-up dir: ' + messageUpDir); - fs.mkdirSync(messageUpDir, { recursive: true }); - } - if (!fs.existsSync(webhookDir)) { - this.logger.verbose('creating webhook dir: ' + webhookDir); - fs.mkdirSync(webhookDir, { recursive: true }); - } - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(settingsDir)) { - this.logger.verbose('creating settings dir: ' + settingsDir); - fs.mkdirSync(settingsDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } - } else { - try { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - - const tempDir = join(storePath, 'temp'); - - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } + if (!fs.existsSync(authDir)) { + this.logger.verbose('creating auth dir: ' + authDir); + fs.mkdirSync(authDir, { recursive: true }); } + if (!fs.existsSync(chatsDir)) { + this.logger.verbose('creating chats dir: ' + chatsDir); + fs.mkdirSync(chatsDir, { recursive: true }); + } + if (!fs.existsSync(contactsDir)) { + this.logger.verbose('creating contacts dir: ' + contactsDir); + fs.mkdirSync(contactsDir, { recursive: true }); + } + if (!fs.existsSync(messagesDir)) { + this.logger.verbose('creating messages dir: ' + messagesDir); + fs.mkdirSync(messagesDir, { recursive: true }); + } + if (!fs.existsSync(messageUpDir)) { + this.logger.verbose('creating message-up dir: ' + messageUpDir); + fs.mkdirSync(messageUpDir, { recursive: true }); + } + if (!fs.existsSync(webhookDir)) { + this.logger.verbose('creating webhook dir: ' + webhookDir); + fs.mkdirSync(webhookDir, { recursive: true }); + } + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(settingsDir)) { + this.logger.verbose('creating settings dir: ' + settingsDir); + fs.mkdirSync(settingsDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } else { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + const chatwootDir = join(storePath, 'chatwoot'); + + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + try { + } catch (error) { + this.logger.error(error); + } } + } } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 48368cb9..2d470c37 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1,1549 +1,1671 @@ +import { InstanceDto } from '../dto/instance.dto'; +import path from 'path'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { WAMonitoringService } from './monitor.service'; +import { Logger } from '../../config/logger.config'; import ChatwootClient from '@figuro/chatwoot-sdk'; +import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import axios from 'axios'; import FormData from 'form-data'; -import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; +import { SendTextDto } from '../dto/sendMessage.dto'; import mimeTypes from 'mime-types'; -import path from 'path'; - -import { ConfigService, HttpServer } from '../../config/env.config'; -import { Logger } from '../../config/logger.config'; +import { SendAudioDto } from '../dto/sendMessage.dto'; +import { SendMediaDto } from '../dto/sendMessage.dto'; import { ROOT_DIR } from '../../config/path.config'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { InstanceDto } from '../dto/instance.dto'; -import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; -import { WAMonitoringService } from './monitor.service'; +import { ConfigService, HttpServer } from '../../config/env.config'; +import { type } from 'os'; export class ChatwootService { - private messageCacheFile: string; - private messageCache: Set; + private messageCacheFile: string; + private messageCache: Set; - private readonly logger = new Logger(ChatwootService.name); + private readonly logger = new Logger(ChatwootService.name); - private provider: any; + private provider: any; - constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { - this.messageCache = new Set(); + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + ) { + this.messageCache = new Set(); + } + + private loadMessageCache(): Set { + this.logger.verbose('load message cache'); + try { + const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); + const cacheArray = cacheData.split('\n'); + return new Set(cacheArray); + } catch (error) { + return new Set(); + } + } + + private saveMessageCache() { + this.logger.verbose('save message cache'); + const cacheData = Array.from(this.messageCache).join('\n'); + writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); + this.logger.verbose('message cache saved'); + } + + private clearMessageCache() { + this.logger.verbose('clear message cache'); + this.messageCache.clear(); + this.saveMessageCache(); + } + + private async getProvider(instance: InstanceDto) { + this.logger.verbose('get provider to instance: ' + instance.instanceName); + try { + const provider = await this.waMonitor.waInstances[ + instance.instanceName + ].findChatwoot(); + + if (!provider) { + this.logger.warn('provider not found'); + return null; + } + + this.logger.verbose('provider found'); + + return provider; + } catch (error) { + this.logger.error('provider not found'); + return null; + } + } + + private async clientCw(instance: InstanceDto) { + this.logger.verbose('get client to instance: ' + instance.instanceName); + const provider = await this.getProvider(instance); + + if (!provider) { + this.logger.error('provider not found'); + return null; } - private loadMessageCache(): Set { - this.logger.verbose('load message cache'); - try { - const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); - const cacheArray = cacheData.split('\n'); - return new Set(cacheArray); - } catch (error) { - return new Set(); - } + this.logger.verbose('provider found'); + + this.provider = provider; + + this.logger.verbose('create client to instance: ' + instance.instanceName); + const client = new ChatwootClient({ + config: { + basePath: provider.url, + with_credentials: true, + credentials: 'include', + token: provider.token, + }, + }); + + this.logger.verbose('client created'); + + return client; + } + + public create(instance: InstanceDto, data: ChatwootDto) { + this.logger.verbose('create chatwoot: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + + this.logger.verbose('chatwoot created'); + return data; + } + + public async find(instance: InstanceDto): Promise { + this.logger.verbose('find chatwoot: ' + instance.instanceName); + try { + return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + } catch (error) { + this.logger.error('chatwoot not found'); + return { enabled: null, url: '' }; + } + } + + public async getContact(instance: InstanceDto, id: number) { + this.logger.verbose('get contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; } - private saveMessageCache() { - this.logger.verbose('save message cache'); - const cacheData = Array.from(this.messageCache).join('\n'); - writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); - this.logger.verbose('message cache saved'); + if (!id) { + this.logger.warn('id is required'); + return null; } - private clearMessageCache() { - this.logger.verbose('clear message cache'); - this.messageCache.clear(); - this.saveMessageCache(); + this.logger.verbose('find contact in chatwoot'); + const contact = await client.contact.getContactable({ + accountId: this.provider.account_id, + id, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; } - private async getProvider(instance: InstanceDto) { - this.logger.verbose('get provider to instance: ' + instance.instanceName); - try { - const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + this.logger.verbose('contact found'); + return contact; + } - if (!provider) { - this.logger.warn('provider not found'); - return null; - } + public async initInstanceChatwoot( + instance: InstanceDto, + inboxName: string, + webhookUrl: string, + qrcode: boolean, + number: string, + ) { + this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - this.logger.verbose('provider found'); + const client = await this.clientCw(instance); - return provider; - } catch (error) { - this.logger.error('provider not found'); - return null; - } + if (!client) { + this.logger.warn('client not found'); + return null; } - private async clientCw(instance: InstanceDto) { - this.logger.verbose('get client to instance: ' + instance.instanceName); - const provider = await this.getProvider(instance); + this.logger.verbose('find inbox in chatwoot'); + const findInbox: any = await client.inboxes.list({ + accountId: this.provider.account_id, + }); - if (!provider) { - this.logger.error('provider not found'); - return null; - } + this.logger.verbose('check duplicate inbox'); + const checkDuplicate = findInbox.payload + .map((inbox) => inbox.name) + .includes(inboxName); - this.logger.verbose('provider found'); + let inboxId: number; - this.provider = provider; + if (!checkDuplicate) { + this.logger.verbose('create inbox in chatwoot'); + const data = { + type: 'api', + webhook_url: webhookUrl, + }; - this.logger.verbose('create client to instance: ' + instance.instanceName); - const client = new ChatwootClient({ - config: { - basePath: provider.url, - with_credentials: true, - credentials: 'include', - token: provider.token, - }, - }); + const inbox = await client.inboxes.create({ + accountId: this.provider.account_id, + data: { + name: inboxName, + channel: data as any, + }, + }); - this.logger.verbose('client created'); + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } - return client; + inboxId = inbox.id; + } else { + this.logger.verbose('find inbox in chatwoot'); + const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); + + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } + + inboxId = inbox.id; } - public create(instance: InstanceDto, data: ChatwootDto) { - this.logger.verbose('create chatwoot: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + this.logger.verbose('find contact in chatwoot and create if not exists'); + const contact = + (await this.findContact(instance, '123456')) || + ((await this.createContact( + instance, + '123456', + inboxId, + false, + 'EvolutionAPI', + )) as any); - this.logger.verbose('chatwoot created'); - return data; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async find(instance: InstanceDto): Promise { - this.logger.verbose('find chatwoot: ' + instance.instanceName); - try { - return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); - } catch (error) { - this.logger.error('chatwoot not found'); - return { enabled: null, url: '' }; - } + const contactId = contact.id || contact.payload.contact.id; + + if (qrcode) { + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('create message for init instance in chatwoot'); + + let contentMsg = '/init'; + + if (number) { + contentMsg = `/init:${number}`; + } + + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: contentMsg, + message_type: 'outgoing', + }, + }); + + if (!message) { + this.logger.warn('conversation not found'); + return null; + } } - public async getContact(instance: InstanceDto, id: number) { - this.logger.verbose('get contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + this.logger.verbose('instance chatwoot initialized'); + return true; + } - if (!client) { - this.logger.warn('client not found'); - return null; - } + public async createContact( + instance: InstanceDto, + phoneNumber: string, + inboxId: number, + isGroup: boolean, + name?: string, + avatar_url?: string, + ) { + this.logger.verbose('create contact to instance: ' + instance.instanceName); - if (!id) { - this.logger.warn('id is required'); - return null; - } + const client = await this.clientCw(instance); - this.logger.verbose('find contact in chatwoot'); - const contact = await client.contact.getContactable({ - accountId: this.provider.account_id, - id, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact found'); - return contact; + if (!client) { + this.logger.warn('client not found'); + return null; } - public async initInstanceChatwoot( - instance: InstanceDto, - inboxName: string, - webhookUrl: string, - qrcode: boolean, - number: string, - ) { - this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inbox in chatwoot'); - const findInbox: any = await client.inboxes.list({ - accountId: this.provider.account_id, - }); - - this.logger.verbose('check duplicate inbox'); - const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); - - let inboxId: number; - - if (!checkDuplicate) { - this.logger.verbose('create inbox in chatwoot'); - const data = { - type: 'api', - webhook_url: webhookUrl, - }; - - const inbox = await client.inboxes.create({ - accountId: this.provider.account_id, - data: { - name: inboxName, - channel: data as any, - }, - }); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } else { - this.logger.verbose('find inbox in chatwoot'); - const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } - - this.logger.verbose('find contact in chatwoot and create if not exists'); - const contact = - (await this.findContact(instance, '123456')) || - ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact.id || contact.payload.contact.id; - - if (qrcode) { - this.logger.verbose('create conversation in chatwoot'); - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data: { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('create message for init instance in chatwoot'); - - let contentMsg = '/init'; - - if (number) { - contentMsg = `/init:${number}`; - } - - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: contentMsg, - message_type: 'outgoing', - }, - }); - - if (!message) { - this.logger.warn('conversation not found'); - return null; - } - } - - this.logger.verbose('instance chatwoot initialized'); - return true; + let data: any = {}; + if (!isGroup) { + this.logger.verbose('create contact in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + phone_number: `+${phoneNumber}`, + avatar_url: avatar_url, + }; + } else { + this.logger.verbose('create contact group in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + identifier: phoneNumber, + avatar_url: avatar_url, + }; } - public async createContact( - instance: InstanceDto, - phoneNumber: string, - inboxId: number, - isGroup: boolean, - name?: string, - avatar_url?: string, - ) { - this.logger.verbose('create contact to instance: ' + instance.instanceName); + this.logger.verbose('create contact in chatwoot'); + const contact = await client.contacts.create({ + accountId: this.provider.account_id, + data, + }); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let data: any = {}; - if (!isGroup) { - this.logger.verbose('create contact in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - phone_number: `+${phoneNumber}`, - avatar_url: avatar_url, - }; - } else { - this.logger.verbose('create contact group in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - identifier: phoneNumber, - avatar_url: avatar_url, - }; - } - - this.logger.verbose('create contact in chatwoot'); - const contact = await client.contacts.create({ - accountId: this.provider.account_id, - data, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact created'); - return contact; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async updateContact(instance: InstanceDto, id: number, data: any) { - this.logger.verbose('update contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + this.logger.verbose('contact created'); + return contact; + } - if (!client) { - this.logger.warn('client not found'); - return null; - } + public async updateContact(instance: InstanceDto, id: number, data: any) { + this.logger.verbose('update contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('update contact in chatwoot'); - const contact = await client.contacts.update({ - accountId: this.provider.account_id, - id, - data, - }); - - this.logger.verbose('contact updated'); - return contact; + if (!client) { + this.logger.warn('client not found'); + return null; } - public async findContact(instance: InstanceDto, phoneNumber: string) { - this.logger.verbose('find contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let query: any; - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('format phone number'); - query = `+${phoneNumber}`; - } else { - this.logger.verbose('format group id'); - query = phoneNumber; - } - - this.logger.verbose('find contact in chatwoot'); - const contact: any = await client.contacts.search({ - accountId: this.provider.account_id, - q: query, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('return contact'); - return contact.payload.find((contact) => contact.phone_number === query); - } else { - this.logger.verbose('return group'); - return contact.payload.find((contact) => contact.identifier === query); - } + if (!id) { + this.logger.warn('id is required'); + return null; } - public async createConversation(instance: InstanceDto, body: any) { - this.logger.verbose('create conversation to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); + this.logger.verbose('update contact in chatwoot'); + const contact = await client.contacts.update({ + accountId: this.provider.account_id, + id, + data, + }); - if (!client) { - this.logger.warn('client not found'); - return null; - } + this.logger.verbose('contact updated'); + return contact; + } - const isGroup = body.key.remoteJid.includes('@g.us'); + public async findContact(instance: InstanceDto, phoneNumber: string) { + this.logger.verbose('find contact to instance: ' + instance.instanceName); - this.logger.verbose('is group: ' + isGroup); + const client = await this.clientCw(instance); - const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - - this.logger.verbose('chat id: ' + chatId); - - let nameContact: string; - - nameContact = !body.key.fromMe ? body.pushName : chatId; - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - if (isGroup) { - this.logger.verbose('get group name'); - const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); - - nameContact = `${group.subject} (GROUP)`; - - this.logger.verbose('find or create participant in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( - body.key.participant.split('@')[0], - ); - - const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); - - if (findParticipant) { - if (!findParticipant.name || findParticipant.name === chatId) { - await this.updateContact(instance, findParticipant.id, { - name: body.pushName, - avatar_url: picture_url.profilePictureUrl || null, - }); - } - } else { - await this.createContact( - instance, - body.key.participant.split('@')[0], - filterInbox.id, - false, - body.pushName, - picture_url.profilePictureUrl || null, - ); - } - } - - this.logger.verbose('find or create contact in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); - - const findContact = await this.findContact(instance, chatId); - - let contact: any; - if (body.key.fromMe) { - if (findContact) { - contact = findContact; - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } else { - if (findContact) { - if (!findContact.name || findContact.name === chatId) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); - } else { - contact = findContact; - } - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; - - if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { - this.logger.verbose('update contact name in chatwoot'); - await this.updateContact(instance, contactId, { - name: nameContact, - }); - } - - this.logger.verbose('get contact conversations in chatwoot'); - const contactConversations = (await client.contacts.listConversations({ - accountId: this.provider.account_id, - id: contactId, - })) as any; - - if (contactConversations) { - this.logger.verbose('return conversation if exists'); - const conversation = contactConversations.payload.find( - (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, - ); - if (conversation) { - this.logger.verbose('conversation found'); - return conversation.id; - } - } - - this.logger.verbose('create conversation in chatwoot'); - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data: { - contact_id: `${contactId}`, - inbox_id: `${filterInbox.id}`, - }, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('conversation created'); - return conversation.id; - } catch (error) { - this.logger.error(error); - } + if (!client) { + this.logger.warn('client not found'); + return null; } - public async getInbox(instance: InstanceDto) { - this.logger.verbose('get inbox to instance: ' + instance.instanceName); + let query: any; - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inboxes in chatwoot'); - const inbox = (await client.inboxes.list({ - accountId: this.provider.account_id, - })) as any; - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); - - if (!findByName) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('return inbox'); - return findByName; + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('format phone number'); + query = `+${phoneNumber}`; + } else { + this.logger.verbose('format group id'); + query = phoneNumber; } - public async createMessage( - instance: InstanceDto, - conversationId: number, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - privateMessage?: boolean, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create message to instance: ' + instance.instanceName); + this.logger.verbose('find contact in chatwoot'); + const contact: any = await client.contacts.search({ + accountId: this.provider.account_id, + q: query, + }); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversationId, - data: { - content: content, - message_type: messageType, - attachments: attachments, - private: privateMessage || false, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('message created'); - - return message; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async createBotMessage( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create bot message to instance: ' + instance.instanceName); + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('return contact'); + return contact.payload.find((contact) => contact.phone_number === query); + } else { + this.logger.verbose('return group'); + return contact.payload.find((contact) => contact.identifier === query); + } + } - const client = await this.clientCw(instance); + public async createConversation(instance: InstanceDto, body: any) { + this.logger.verbose('create conversation to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); - if (!client) { - this.logger.warn('client not found'); - return null; - } + if (!client) { + this.logger.warn('client not found'); + return null; + } - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); + const isGroup = body.key.remoteJid.includes('@g.us'); - if (!contact) { - this.logger.warn('contact not found'); - return null; - } + this.logger.verbose('is group: ' + isGroup); - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); + const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } + this.logger.verbose('chat id: ' + chatId); - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); + let nameContact: string; - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } + nameContact = !body.key.fromMe ? body.pushName : chatId; - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + if (isGroup) { + this.logger.verbose('get group name'); + const group = await this.waMonitor.waInstances[ + instance.instanceName + ].client.groupMetadata(chatId); + + nameContact = `${group.subject} (GROUP)`; + + this.logger.verbose('find or create participant in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[ + instance.instanceName + ].profilePicture(body.key.participant.split('@')[0]); + + const findParticipant = await this.findContact( + instance, + body.key.participant.split('@')[0], ); - if (!conversation) { - this.logger.warn('conversation not found'); - return; + if (findParticipant) { + if (!findParticipant.name || findParticipant.name === chatId) { + await this.updateContact(instance, findParticipant.id, { + name: body.pushName, + avatar_url: picture_url.profilePictureUrl || null, + }); + } + } else { + await this.createContact( + instance, + body.key.participant.split('@')[0], + filterInbox.id, + false, + body.pushName, + picture_url.profilePictureUrl || null, + ); } + } - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: content, - message_type: messageType, - attachments: attachments, - }, + this.logger.verbose('find or create contact in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[ + instance.instanceName + ].profilePicture(chatId); + + const findContact = await this.findContact(instance, chatId); + + let contact: any; + if (body.key.fromMe) { + if (findContact) { + contact = findContact; + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } else { + if (findContact) { + if (!findContact.name || findContact.name === chatId) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = findContact; + } + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = + contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; + + if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { + this.logger.verbose('update contact name in chatwoot'); + await this.updateContact(instance, contactId, { + name: nameContact, }); + } - if (!message) { - this.logger.warn('message not found'); - return null; + this.logger.verbose('get contact conversations in chatwoot'); + const contactConversations = (await client.contacts.listConversations({ + accountId: this.provider.account_id, + id: contactId, + })) as any; + + if (contactConversations) { + let conversation: any; + if (this.provider.reopen_conversation) { + conversation = contactConversations.payload.find( + (conversation) => conversation.inbox_id == filterInbox.id, + ); + } else { + conversation = contactConversations.payload.find( + (conversation) => + conversation.status !== 'resolved' && + conversation.inbox_id == filterInbox.id, + ); } + this.logger.verbose('return conversation if exists'); - this.logger.verbose('bot message created'); + if (conversation) { + this.logger.verbose('conversation found'); + return conversation.id; + } + } - return message; + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: filterInbox.id.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('conversation created'); + return conversation.id; + } catch (error) { + this.logger.error(error); + } + } + + public async getInbox(instance: InstanceDto) { + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; } - private async sendData( - conversationId: number, - file: string, - messageType: 'incoming' | 'outgoing' | undefined, - content?: string, - ) { - this.logger.verbose('send data to chatwoot'); + this.logger.verbose('find inboxes in chatwoot'); + const inbox = (await client.inboxes.list({ + accountId: this.provider.account_id, + })) as any; - const data = new FormData(); + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } + this.logger.verbose('find inbox by name'); + const findByName = inbox.payload.find( + (inbox) => inbox.name === instance.instanceName, + ); - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); + if (!findByName) { + this.logger.warn('inbox not found'); + return null; + } - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); + this.logger.verbose('return inbox'); + return findByName; + } - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, + public async createMessage( + instance: InstanceDto, + conversationId: number, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + privateMessage?: boolean, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversationId, + data: { + content: content, + message_type: messageType, + attachments: attachments, + private: privateMessage || false, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('message created'); + + return message; + } + + public async createBotMessage( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create bot message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => + conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: content, + message_type: messageType, + attachments: attachments, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('bot message created'); + + return message; + } + + private async sendData( + conversationId: number, + file: string, + messageType: 'incoming' | 'outgoing' | undefined, + content?: string, + ) { + this.logger.verbose('send data to chatwoot'); + + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + unlinkSync(file); + } + } + + public async createBotQr( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + file?: string, + ) { + this.logger.verbose('create bot qr to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => + conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('send data to chatwoot'); + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + if (file) { + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + } + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + } + } + + public async sendAttachment( + waInstance: any, + number: string, + media: any, + caption?: string, + ) { + this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); + + try { + this.logger.verbose('get media type'); + const parts = media.split('/'); + + const fileName = decodeURIComponent(parts[parts.length - 1]); + this.logger.verbose('file name: ' + fileName); + + const mimeType = mimeTypes.lookup(fileName).toString(); + this.logger.verbose('mime type: ' + mimeType); + + let type = 'document'; + + switch (mimeType.split('/')[0]) { + case 'image': + type = 'image'; + break; + case 'video': + type = 'video'; + break; + case 'audio': + type = 'audio'; + break; + default: + type = 'document'; + break; + } + + this.logger.verbose('type: ' + type); + + if (type === 'audio') { + this.logger.verbose('send audio to instance: ' + waInstance.instanceName); + const data: SendAudioDto = { + number: number, + audioMessage: { + audio: media, + }, + options: { + delay: 1200, + presence: 'recording', + }, }; - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); + await waInstance?.audioWhatsapp(data); - this.logger.verbose('remove temp file'); - unlinkSync(file); + this.logger.verbose('audio sent'); + return; + } - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - unlinkSync(file); - } + this.logger.verbose('send media to instance: ' + waInstance.instanceName); + const data: SendMediaDto = { + number: number, + mediaMessage: { + mediatype: type as any, + fileName: fileName, + media: media, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + if (caption) { + this.logger.verbose('caption found'); + data.mediaMessage.caption = caption; + } + + await waInstance?.mediaMessage(data); + + this.logger.verbose('media sent'); + return; + } catch (error) { + this.logger.error(error); } + } - public async createBotQr( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - file?: string, - ) { - this.logger.verbose('create bot qr to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + public async receiveWebhook(instance: InstanceDto, body: any) { + try { + this.logger.verbose( + 'receive webhook to chatwoot instance: ' + instance.instanceName, + ); + const client = await this.clientCw(instance); - if (!client) { - this.logger.warn('client not found'); - return null; + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('check if is bot'); + if (!body?.conversation || body.private) return { message: 'bot' }; + + this.logger.verbose('check if is group'); + const chatId = + body.conversation.meta.sender?.phone_number?.replace('+', '') || + body.conversation.meta.sender?.identifier; + const messageReceived = body.content; + const senderName = body?.sender?.name; + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (chatId === '123456' && body.message_type === 'outgoing') { + this.logger.verbose('check if is command'); + + const command = messageReceived.replace('/', ''); + + if (command.includes('init') || command.includes('iniciar')) { + this.logger.verbose('command init found'); + const state = waInstance?.connectionStatus?.state; + + if (state !== 'open') { + this.logger.verbose('connect to whatsapp'); + const number = command.split(':')[1]; + await waInstance.connectToWhatsapp(number); + } else { + this.logger.verbose('whatsapp already connected'); + await this.createBotMessage( + instance, + `🚨 ${body.inbox.name} instance is connected.`, + 'incoming', + ); + } } - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); + if (command === 'status') { + this.logger.verbose('command status found'); - if (!contact) { - this.logger.warn('contact not found'); - return null; + const state = waInstance?.connectionStatus?.state; + + if (!state) { + this.logger.verbose('state not found'); + await this.createBotMessage( + instance, + `⚠️ ${body.inbox.name} instance not found.`, + 'incoming', + ); + } + + if (state) { + this.logger.verbose('state: ' + state + ' found'); + await this.createBotMessage( + instance, + `⚠️ ${body.inbox.name} instance status: *${state}*`, + 'incoming', + ); + } } - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); + if (command === 'disconnect' || command === 'desconectar') { + this.logger.verbose('command disconnect found'); - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; + const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgLogout, 'incoming'); + + this.logger.verbose('disconnect to whatsapp'); + await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); + await waInstance?.client?.ws?.close(); } - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); + if (command.includes('new_instance')) { + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; + const data = { + instanceName: command.split(':')[1], + qrcode: true, + chatwoot_account_id: this.provider.account_id, + chatwoot_token: this.provider.token, + chatwoot_url: this.provider.url, + chatwoot_sign_msg: this.provider.sign_msg, + }; + + if (command.split(':')[2]) { + data['number'] = command.split(':')[2]; + } + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: data, + }; + + await axios.request(config); } + } - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + if ( + body.message_type === 'outgoing' && + body?.conversation?.messages?.length && + chatId !== '123456' + ) { + this.logger.verbose('check if is group'); + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, ); + this.logger.verbose('cache file path: ' + this.messageCacheFile); - if (!conversation) { - this.logger.warn('conversation not found'); - return; + this.messageCache = this.loadMessageCache(); + this.logger.verbose('cache file loaded'); + this.logger.verbose(this.messageCache); + + this.logger.verbose('check if message is cached'); + if (this.messageCache.has(body.id.toString())) { + this.logger.verbose('message is cached'); + return { message: 'bot' }; } - this.logger.verbose('send data to chatwoot'); - const data = new FormData(); + this.logger.verbose('clear cache'); + this.clearMessageCache(); - if (content) { - this.logger.verbose('content found'); - data.append('content', content); + this.logger.verbose('Format message to send'); + let formatText: string; + if (senderName === null || senderName === undefined) { + formatText = messageReceived; + } else { + formatText = this.provider.sign_msg + ? `*${senderName}:*\n\n${messageReceived}` + : messageReceived; } - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); + for (const message of body.conversation.messages) { + this.logger.verbose('check if message is media'); + if (message.attachments && message.attachments.length > 0) { + this.logger.verbose('message is media'); + for (const attachment of message.attachments) { + this.logger.verbose('send media to whatsapp'); + if (!messageReceived) { + this.logger.verbose('message do not have text'); + formatText = null; + } - if (file) { - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - } - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, - }; - - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - } - } - - public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { - this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); - - try { - this.logger.verbose('get media type'); - const parts = media.split('/'); - - const fileName = decodeURIComponent(parts[parts.length - 1]); - this.logger.verbose('file name: ' + fileName); - - const mimeType = mimeTypes.lookup(fileName).toString(); - this.logger.verbose('mime type: ' + mimeType); - - let type = 'document'; - - switch (mimeType.split('/')[0]) { - case 'image': - type = 'image'; - break; - case 'video': - type = 'video'; - break; - case 'audio': - type = 'audio'; - break; - default: - type = 'document'; - break; + await this.sendAttachment( + waInstance, + chatId, + attachment.data_url, + formatText, + ); } + } else { + this.logger.verbose('message is text'); - this.logger.verbose('type: ' + type); - - if (type === 'audio') { - this.logger.verbose('send audio to instance: ' + waInstance.instanceName); - const data: SendAudioDto = { - number: number, - audioMessage: { - audio: media, - }, - options: { - delay: 1200, - presence: 'recording', - }, - }; - - await waInstance?.audioWhatsapp(data); - - this.logger.verbose('audio sent'); - return; - } - - this.logger.verbose('send media to instance: ' + waInstance.instanceName); - const data: SendMediaDto = { - number: number, - mediaMessage: { - mediatype: type as any, - fileName: fileName, - media: media, - }, - options: { - delay: 1200, - presence: 'composing', - }, + this.logger.verbose('send text to whatsapp'); + const data: SendTextDto = { + number: chatId, + textMessage: { + text: formatText, + }, + options: { + delay: 1200, + presence: 'composing', + }, }; - if (caption) { - this.logger.verbose('caption found'); - data.mediaMessage.caption = caption; - } - - await waInstance?.mediaMessage(data); - - this.logger.verbose('media sent'); - return; - } catch (error) { - this.logger.error(error); + await waInstance?.textMessage(data); + } } - } + } - public async receiveWebhook(instance: InstanceDto, body: any) { - try { - this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + if (body.message_type === 'template' && body.event === 'message_created') { + this.logger.verbose('check if is template'); - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('check if is bot'); - if (!body?.conversation || body.private) return { message: 'bot' }; - - this.logger.verbose('check if is group'); - const chatId = - body.conversation.meta.sender?.phone_number?.replace('+', '') || - body.conversation.meta.sender?.identifier; - const messageReceived = body.content; - const senderName = body?.sender?.name; - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (chatId === '123456' && body.message_type === 'outgoing') { - this.logger.verbose('check if is command'); - - const command = messageReceived.replace('/', ''); - - if (command.includes('init') || command.includes('iniciar')) { - this.logger.verbose('command init found'); - const state = waInstance?.connectionStatus?.state; - - if (state !== 'open') { - this.logger.verbose('connect to whatsapp'); - const number = command.split(':')[1]; - await waInstance.connectToWhatsapp(number); - } else { - this.logger.verbose('whatsapp already connected'); - await this.createBotMessage( - instance, - `🚨 ${body.inbox.name} instance is connected.`, - 'incoming', - ); - } - } - - if (command === 'status') { - this.logger.verbose('command status found'); - - const state = waInstance?.connectionStatus?.state; - - if (!state) { - this.logger.verbose('state not found'); - await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); - } - - if (state) { - this.logger.verbose('state: ' + state + ' found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance status: *${state}*`, - 'incoming', - ); - } - } - - if (command === 'disconnect' || command === 'desconectar') { - this.logger.verbose('command disconnect found'); - - const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgLogout, 'incoming'); - - this.logger.verbose('disconnect to whatsapp'); - await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); - await waInstance?.client?.ws?.close(); - } - - if (command.includes('new_instance')) { - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const data = { - instanceName: command.split(':')[1], - qrcode: true, - chatwoot_account_id: this.provider.account_id, - chatwoot_token: this.provider.token, - chatwoot_url: this.provider.url, - chatwoot_sign_msg: this.provider.sign_msg, - }; - - if (command.split(':')[2]) { - data['number'] = command.split(':')[2]; - } - - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: data, - }; - - await axios.request(config); - } - } - - if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { - this.logger.verbose('check if is group'); - - this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); - this.logger.verbose('cache file path: ' + this.messageCacheFile); - - this.messageCache = this.loadMessageCache(); - this.logger.verbose('cache file loaded'); - this.logger.verbose(this.messageCache); - - this.logger.verbose('check if message is cached'); - if (this.messageCache.has(body.id.toString())) { - this.logger.verbose('message is cached'); - return { message: 'bot' }; - } - - this.logger.verbose('clear cache'); - this.clearMessageCache(); - - this.logger.verbose('Format message to send'); - let formatText: string; - if (senderName === null || senderName === undefined) { - formatText = messageReceived; - } else { - formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; - } - - for (const message of body.conversation.messages) { - this.logger.verbose('check if message is media'); - if (message.attachments && message.attachments.length > 0) { - this.logger.verbose('message is media'); - for (const attachment of message.attachments) { - this.logger.verbose('send media to whatsapp'); - if (!messageReceived) { - this.logger.verbose('message do not have text'); - formatText = null; - } - - await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); - } - } else { - this.logger.verbose('message is text'); - - this.logger.verbose('send text to whatsapp'); - const data: SendTextDto = { - number: chatId, - textMessage: { - text: formatText, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - await waInstance?.textMessage(data); - } - } - } - - if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is csat'); - - const data: SendTextDto = { - number: chatId, - textMessage: { - text: body.content, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - this.logger.verbose('send text to whatsapp'); - - await waInstance?.textMessage(data); - } - - return { message: 'bot' }; - } catch (error) { - this.logger.error(error); - - return { message: 'bot' }; - } - } - - private isMediaMessage(message: any) { - this.logger.verbose('check if is media message'); - const media = [ - 'imageMessage', - 'documentMessage', - 'documentWithCaptionMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', - ]; - - const messageKeys = Object.keys(message); - - const result = messageKeys.some((key) => media.includes(key)); - - this.logger.verbose('is media message: ' + result); - return result; - } - - private getTypeMessage(msg: any) { - this.logger.verbose('get type message'); - - const types = { - conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, - extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: msg.stickerMessage?.fileSha256.toString('base64'), - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, + const data: SendTextDto = { + number: chatId, + textMessage: { + text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), + }, + options: { + delay: 1200, + presence: 'composing', + }, }; - this.logger.verbose('type message: ' + types); + this.logger.verbose('send text to whatsapp'); - return types; + await waInstance?.textMessage(data); + } + + return { message: 'bot' }; + } catch (error) { + this.logger.error(error); + + return { message: 'bot' }; + } + } + + private isMediaMessage(message: any) { + this.logger.verbose('check if is media message'); + const media = [ + 'imageMessage', + 'documentMessage', + 'documentWithCaptionMessage', + 'audioMessage', + 'videoMessage', + 'stickerMessage', + ]; + + const messageKeys = Object.keys(message); + + const result = messageKeys.some((key) => media.includes(key)); + + this.logger.verbose('is media message: ' + result); + return result; + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + imageMessage: msg.imageMessage?.caption, + videoMessage: msg.videoMessage?.caption, + extendedTextMessage: msg.extendedTextMessage?.text, + messageContextInfo: msg.messageContextInfo?.stanzaId, + stickerMessage: undefined, + documentMessage: msg.documentMessage?.caption, + documentWithCaptionMessage: + msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { + const latitude = result.degreesLatitude; + const longitude = result.degreesLongitude; + + const formattedLocation = `**Location:** + **latitude:** ${latitude} + **longitude:** ${longitude} + https://www.google.com/maps/search/?api=1&query=${latitude},${longitude} + `; + + this.logger.verbose('message content: ' + formattedLocation); + + return formattedLocation; } - private getMessageContent(types: any) { - this.logger.verbose('get message content'); - const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + if (typeKey === 'contactMessage') { + const vCardData = result.split('\n'); + const contactInfo = {}; - const result = typeKey ? types[typeKey] : undefined; - - if (typeKey === 'stickerMessage') { - return null; + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; } + }); - if (typeKey === 'contactMessage') { - const vCardData = result.split('\n'); - const contactInfo = {}; - - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); - - let formattedContact = `**Contact:** + let formattedContact = `**Contact:** **name:** ${contactInfo['FN']}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); - - this.logger.verbose('message content: ' + formattedContact); - return formattedContact; + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; } + }); - if (typeKey === 'contactsArrayMessage') { - const formattedContacts = result.contacts.map((contact) => { - const vCardData = contact.vcard.split('\n'); - const contactInfo = {}; + this.logger.verbose('message content: ' + formattedContact); + return formattedContact; + } - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); + if (typeKey === 'contactsArrayMessage') { + const formattedContacts = result.contacts.map((contact) => { + const vCardData = contact.vcard.split('\n'); + const contactInfo = {}; - let formattedContact = `**Contact:** + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + let formattedContact = `**Contact:** **name:** ${contact.displayName}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); - return formattedContact; - }); + return formattedContact; + }); - const formattedContactsArray = formattedContacts.join('\n\n'); + const formattedContactsArray = formattedContacts.join('\n\n'); - this.logger.verbose('formatted contacts: ' + formattedContactsArray); + this.logger.verbose('formatted contacts: ' + formattedContactsArray); - return formattedContactsArray; - } - - this.logger.verbose('message content: ' + result); - - return result; + return formattedContactsArray; } - private getConversationMessage(msg: any) { + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { + this.logger.verbose('get conversation message'); + + const types = this.getTypeMessage(msg); + + const messageContent = this.getMessageContent(types); + + this.logger.verbose('conversation message: ' + messageContent); + + return messageContent; + } + + public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { + this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (!waInstance) { + this.logger.warn('wa instance not found'); + return null; + } + + if (event === 'messages.upsert') { + this.logger.verbose('event messages.upsert'); + + if (body.key.remoteJid === 'status@broadcast') { + this.logger.verbose('status broadcast found'); + return; + } + this.logger.verbose('get conversation message'); + const bodyMessage = await this.getConversationMessage(body.message); - const types = this.getTypeMessage(msg); + const isMedia = this.isMediaMessage(body.message); - const messageContent = this.getMessageContent(types); - - this.logger.verbose('conversation message: ' + messageContent); - - return messageContent; - } - - public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { - this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (!waInstance) { - this.logger.warn('wa instance not found'); - return null; - } - - if (event === 'messages.upsert') { - this.logger.verbose('event messages.upsert'); - - if (body.key.remoteJid === 'status@broadcast') { - this.logger.verbose('status broadcast found'); - return; - } - - this.logger.verbose('get conversation message'); - const bodyMessage = await this.getConversationMessage(body.message); - - const isMedia = this.isMediaMessage(body.message); - - if (!bodyMessage && !isMedia) { - this.logger.warn('no body message found'); - return; - } - - this.logger.verbose('get conversation in chatwoot'); - const getConversion = await this.createConversation(instance, body); - - if (!getConversion) { - this.logger.warn('conversation not found'); - return; - } - - const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; - - this.logger.verbose('message type: ' + messageType); - - this.logger.verbose('is media: ' + isMedia); - - this.logger.verbose('check if is media'); - if (isMedia) { - this.logger.verbose('message is media'); - - this.logger.verbose('get base64 from media message'); - const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ - message: { - ...body, - }, - }); - - const random = Math.random().toString(36).substring(7); - const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; - - const fileData = Buffer.from(downloadBase64.base64, 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; - - this.logger.verbose('temp file name: ' + nameFile); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData(getConversion, fileName, messageType, content); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage(instance, getConversion, content, messageType); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - if (event === 'status.instance') { - this.logger.verbose('event status.instance'); - const data = body; - const inbox = await this.getInbox(instance); - - if (!inbox) { - this.logger.warn('inbox not found'); - return; - } - - const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgStatus, 'incoming'); - } - - if (event === 'connection.update') { - this.logger.verbose('event connection.update'); - - if (body.status === 'open') { - const msgConnection = `🚀 Connection successfully established!`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgConnection, 'incoming'); - } - } - - if (event === 'qrcode.updated') { - this.logger.verbose('event qrcode.updated'); - if (body.statusCode === 500) { - this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; - - this.logger.verbose('send message to chatwoot'); - return await this.createBotMessage(instance, erroQRcode, 'incoming'); - } else { - this.logger.verbose('qrcode success'); - const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; - - this.logger.verbose('temp file name: ' + fileName); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); - - let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; - - if (body?.qrcode?.pairingCode) { - msgQrCode = - msgQrCode + - `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( - 0, - 4, - )}-${body.qrcode.pairingCode.substring(4, 8)}`; - } - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgQrCode, 'incoming'); - } - } - } catch (error) { - this.logger.error(error); + if (!bodyMessage && !isMedia) { + this.logger.warn('no body message found'); + return; } - } - public async newInstance(data: any) { - try { - const instanceName = data.instanceName; - const qrcode = true; - const number = data.number; - const accountId = data.accountId; - const chatwootToken = data.token; - const chatwootUrl = data.url; - const signMsg = true; - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + this.logger.verbose('get conversation in chatwoot'); + const getConversion = await this.createConversation(instance, body); - const requestData = { - instanceName, - qrcode, - chatwoot_account_id: accountId, - chatwoot_token: chatwootToken, - chatwoot_url: chatwootUrl, - chatwoot_sign_msg: signMsg, - }; + if (!getConversion) { + this.logger.warn('conversation not found'); + return; + } - if (number) { - requestData['number'] = number; + const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; + + this.logger.verbose('message type: ' + messageType); + + this.logger.verbose('is media: ' + isMedia); + + this.logger.verbose('check if is media'); + if (isMedia) { + this.logger.verbose('message is media'); + + this.logger.verbose('get base64 from media message'); + const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ + message: { + ...body, + }, + }); + + const random = Math.random().toString(36).substring(7); + const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; + + const fileData = Buffer.from(downloadBase64.base64, 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; + + this.logger.verbose('temp file name: ' + nameFile); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; } - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: requestData, - }; + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData( + getConversion, + fileName, + messageType, + content, + ); - // await axios.request(config); + if (!send) { + this.logger.warn('message not sent'); + return; + } - return true; - } catch (error) { - this.logger.error(error); - return null; + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData( + getConversion, + fileName, + messageType, + bodyMessage, + ); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } } + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage( + instance, + getConversion, + content, + messageType, + ); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage( + instance, + getConversion, + bodyMessage, + messageType, + ); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + if (event === 'status.instance') { + this.logger.verbose('event status.instance'); + const data = body; + const inbox = await this.getInbox(instance); + + if (!inbox) { + this.logger.warn('inbox not found'); + return; + } + + const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgStatus, 'incoming'); + } + + if (event === 'connection.update') { + this.logger.verbose('event connection.update'); + + if (body.status === 'open') { + const msgConnection = `🚀 Connection successfully established!`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgConnection, 'incoming'); + } + } + + if (event === 'qrcode.updated') { + this.logger.verbose('event qrcode.updated'); + if (body.statusCode === 500) { + this.logger.verbose('qrcode error'); + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; + + this.logger.verbose('send message to chatwoot'); + return await this.createBotMessage(instance, erroQRcode, 'incoming'); + } else { + this.logger.verbose('qrcode success'); + const fileData = Buffer.from( + body?.qrcode.base64.replace('data:image/png;base64,', ''), + 'base64', + ); + + const fileName = `${path.join( + waInstance?.storePath, + 'temp', + `${`${instance}.png`}`, + )}`; + + this.logger.verbose('temp file name: ' + fileName); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('send qrcode to chatwoot'); + await this.createBotQr( + instance, + 'QRCode successfully generated!', + 'incoming', + fileName, + ); + + let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + + if (body?.qrcode?.pairingCode) { + msgQrCode = + msgQrCode + + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( + 0, + 4, + )}-${body.qrcode.pairingCode.substring(4, 8)}`; + } + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgQrCode, 'incoming'); + } + } + } catch (error) { + this.logger.error(error); } + } + + public async newInstance(data: any) { + try { + const instanceName = data.instanceName; + const qrcode = true; + const number = data.number; + const accountId = data.accountId; + const chatwootToken = data.token; + const chatwootUrl = data.url; + const signMsg = true; + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const requestData = { + instanceName, + qrcode, + chatwoot_account_id: accountId, + chatwoot_token: chatwootToken, + chatwoot_url: chatwootUrl, + chatwoot_sign_msg: signMsg, + }; + + if (number) { + requestData['number'] = number; + } + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: requestData, + }; + + // await axios.request(config); + + return true; + } catch (error) { + this.logger.error(error); + return null; + } + } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d1bae31e..4c9bf62d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,2887 +1,3067 @@ -import ffmpegPath from '@ffmpeg-installer/ffmpeg'; -import { Boom } from '@hapi/boom'; import makeWASocket, { - AnyMessageContent, - BufferedEventData, - BufferJSON, - CacheStore, - Chat, - ConnectionState, - Contact, - delay, - DisconnectReason, - downloadMediaMessage, - fetchLatestBaileysVersion, - generateWAMessageFromContent, - getAggregateVotesInPollMessage, - getContentType, - getDevice, - GroupMetadata, - isJidGroup, - isJidUser, - makeCacheableSignalKeyStore, - MessageUpsertType, - MiscMessageGenerationOptions, - ParticipantAction, - prepareWAMessageMedia, - proto, - useMultiFileAuthState, - UserFacingSocketConfig, - WABrowserDescription, - WAMediaUpload, - WAMessage, - WAMessageUpdate, - WASocket, + AnyMessageContent, + BufferedEventData, + BufferJSON, + CacheStore, + makeCacheableSignalKeyStore, + Chat, + ConnectionState, + Contact, + delay, + DisconnectReason, + downloadMediaMessage, + fetchLatestBaileysVersion, + generateWAMessageFromContent, + getContentType, + getDevice, + GroupMetadata, + isJidGroup, + isJidUser, + MessageUpsertType, + MiscMessageGenerationOptions, + ParticipantAction, + prepareWAMessageMedia, + proto, + useMultiFileAuthState, + UserFacingSocketConfig, + WABrowserDescription, + WAMediaUpload, + WAMessage, + WAMessageUpdate, + WASocket, + getAggregateVotesInPollMessage, } from '@whiskeysockets/baileys'; -import axios from 'axios'; -import { exec, execSync } from 'child_process'; -import { arrayUnique, isBase64, isURL } from 'class-validator'; -import EventEmitter2 from 'eventemitter2'; -import fs, { existsSync, readFileSync } from 'fs'; -import Long from 'long'; -import NodeCache from 'node-cache'; -import { getMIMEType } from 'node-mime-types'; -import { release } from 'os'; -import { join } from 'path'; -import P from 'pino'; -import ProxyAgent from 'proxy-agent'; -import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; -import qrcodeTerminal from 'qrcode-terminal'; -import sharp from 'sharp'; -import { v4 } from 'uuid'; - import { - Auth, - CleanStoreConf, - ConfigService, - ConfigSessionPhone, - Database, - HttpServer, - Log, - QrCode, - Redis, - Webhook, + Auth, + CleanStoreConf, + ConfigService, + ConfigSessionPhone, + Database, + HttpServer, + QrCode, + Redis, + Webhook, } from '../../config/env.config'; +import fs from 'fs'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; -import { dbserver } from '../../db/db.connect'; -import { RedisCache } from '../../db/redis.client'; -import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; -import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; -import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; -import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, -} from '../dto/chat.dto'; -import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, -} from '../dto/group.dto'; -import { - ContactMessage, - MediaMessage, - Options, - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, - StatusMessage, -} from '../dto/sendMessage.dto'; -import { SettingsRaw } from '../models'; -import { ChatRaw } from '../models/chat.model'; -import { ChatwootRaw } from '../models/chatwoot.model'; -import { ContactRaw } from '../models/contact.model'; -import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; -import { WebhookRaw } from '../models/webhook.model'; -import { ContactQuery } from '../repository/contact.repository'; -import { MessageQuery } from '../repository/message.repository'; -import { MessageUpQuery } from '../repository/messageUp.repository'; +import { existsSync, readFileSync } from 'fs'; +import { join } from 'path'; +import axios from 'axios'; +import { v4 } from 'uuid'; +import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; +import qrcodeTerminal from 'qrcode-terminal'; +import { Events, TypeMediaMessage, wa, MessageSubtype } from '../types/wa.types'; +import { Boom } from '@hapi/boom'; +import EventEmitter2 from 'eventemitter2'; +import { release } from 'os'; +import P from 'pino'; +import { execSync, exec } from 'child_process'; +import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { RepositoryBroker } from '../repository/repository.manager'; -import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; -import { waMonitor } from '../whatsapp.module'; +import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; +import { ContactRaw } from '../models/contact.model'; +import { ChatRaw } from '../models/chat.model'; +import { getMIMEType } from 'node-mime-types'; +import { + ContactMessage, + MediaMessage, + Options, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendReactionDto, + SendTextDto, + SendPollDto, + SendStickerDto, + SendStatusDto, + StatusMessage, +} from '../dto/sendMessage.dto'; +import { arrayUnique, isBase64, isURL } from 'class-validator'; +import { + ArchiveChatDto, + DeleteMessage, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, + getBase64FromMediaMessageDto, +} from '../dto/chat.dto'; +import { MessageQuery } from '../repository/message.repository'; +import { ContactQuery } from '../repository/contact.repository'; +import { + BadRequestException, + InternalServerErrorException, + NotFoundException, +} from '../../exceptions'; +import { + CreateGroupDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, + GroupToggleEphemeralDto, + GroupSubjectDto, + GroupDescriptionDto, + GroupSendInvite, + GetParticipant, +} from '../dto/group.dto'; +import { MessageUpQuery } from '../repository/messageUp.repository'; +import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; +import Long from 'long'; +import { WebhookRaw } from '../models/webhook.model'; +import { ChatwootRaw } from '../models/chatwoot.model'; +import { SettingsRaw } from '../models'; +import { dbserver } from '../../db/db.connect'; +import NodeCache from 'node-cache'; +import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; +import sharp from 'sharp'; +import { RedisCache } from '../../db/redis.client'; +import { Log } from '../../config/env.config'; import { ChatwootService } from './chatwoot.service'; +import { waMonitor } from '../whatsapp.module'; export class WAStartupService { - constructor( - private readonly configService: ConfigService, - private readonly eventEmitter: EventEmitter2, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('WAStartupService initialized'); - this.cleanStore(); - this.instance.qrcode = { count: 0 }; + constructor( + private readonly configService: ConfigService, + private readonly eventEmitter: EventEmitter2, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('WAStartupService initialized'); + this.cleanStore(); + this.instance.qrcode = { count: 0 }; + } + + private readonly logger = new Logger(WAStartupService.name); + private readonly instance: wa.Instance = {}; + public client: WASocket; + private readonly localWebhook: wa.LocalWebHook = {}; + private readonly localChatwoot: wa.LocalChatwoot = {}; + private readonly localSettings: wa.LocalSettings = {}; + private stateConnection: wa.StateConnection = { state: 'close' }; + public readonly storePath = join(ROOT_DIR, 'store'); + private readonly msgRetryCounterCache: CacheStore = new NodeCache(); + private readonly userDevicesCache: CacheStore = new NodeCache(); + private endSession = false; + private logBaileys = this.configService.get('LOG').BAILEYS; + + private phoneNumber: string; + + private chatwootService = new ChatwootService(waMonitor, this.configService); + + public set instanceName(name: string) { + this.logger.verbose(`Initializing instance '${name}'`); + if (!name) { + this.logger.verbose('Instance name not found, generating random name with uuid'); + this.instance.name = v4(); + return; + } + this.instance.name = name; + this.logger.verbose(`Instance '${this.instance.name}' initialized`); + this.logger.verbose('Sending instance status to webhook'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'created', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'created', + }, + ); + } + } + + public get instanceName() { + this.logger.verbose('Getting instance name'); + return this.instance.name; + } + + public get wuid() { + this.logger.verbose('Getting remoteJid of instance'); + return this.instance.wuid; + } + + public async getProfileName() { + this.logger.verbose('Getting profile name'); + let profileName = this.client.user?.name ?? this.client.user?.verifiedName; + if (!profileName) { + this.logger.verbose('Profile name not found, trying to get from database'); + if (this.configService.get('DATABASE').ENABLED) { + this.logger.verbose('Database enabled, trying to get from database'); + const collection = dbserver + .getClient() + .db( + this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + + '-instances', + ) + .collection(this.instanceName); + const data = await collection.findOne({ _id: 'creds' }); + if (data) { + this.logger.verbose('Profile name found in database'); + const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); + profileName = creds.me?.name || creds.me?.verifiedName; + } + } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { + this.logger.verbose('Profile name found in file'); + const creds = JSON.parse( + readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { + encoding: 'utf-8', + }), + ); + profileName = creds.me?.name || creds.me?.verifiedName; + } } - private readonly logger = new Logger(WAStartupService.name); - private readonly instance: wa.Instance = {}; - public client: WASocket; - private readonly localWebhook: wa.LocalWebHook = {}; - private readonly localChatwoot: wa.LocalChatwoot = {}; - private readonly localSettings: wa.LocalSettings = {}; - private stateConnection: wa.StateConnection = { state: 'close' }; - public readonly storePath = join(ROOT_DIR, 'store'); - private readonly msgRetryCounterCache: CacheStore = new NodeCache(); - private readonly userDevicesCache: CacheStore = new NodeCache(); - private endSession = false; - private logBaileys = this.configService.get('LOG').BAILEYS; + this.logger.verbose(`Profile name: ${profileName}`); + return profileName; + } - private phoneNumber: string; + public async getProfileStatus() { + this.logger.verbose('Getting profile status'); + const status = await this.client.fetchStatus(this.instance.wuid); - private chatwootService = new ChatwootService(waMonitor, this.configService); + this.logger.verbose(`Profile status: ${status.status}`); + return status.status; + } - public set instanceName(name: string) { - this.logger.verbose(`Initializing instance '${name}'`); - if (!name) { - this.logger.verbose('Instance name not found, generating random name with uuid'); - this.instance.name = v4(); - return; + public get profilePictureUrl() { + this.logger.verbose('Getting profile picture url'); + return this.instance.profilePictureUrl; + } + + public get qrCode(): wa.QrCode { + this.logger.verbose('Getting qrcode'); + + return { + pairingCode: this.instance.qrcode?.pairingCode, + code: this.instance.qrcode?.code, + base64: this.instance.qrcode?.base64, + }; + } + + private async loadWebhook() { + this.logger.verbose('Loading webhook'); + const data = await this.repository.webhook.find(this.instanceName); + this.localWebhook.url = data?.url; + this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + + this.localWebhook.enabled = data?.enabled; + this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + + this.localWebhook.events = data?.events; + this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); + + this.localWebhook.webhook_by_events = data?.webhook_by_events; + this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + + this.logger.verbose('Webhook loaded'); + } + + public async setWebhook(data: WebhookRaw) { + this.logger.verbose('Setting webhook'); + await this.repository.webhook.create(data, this.instanceName); + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + Object.assign(this.localWebhook, data); + this.logger.verbose('Webhook set'); + } + + public async findWebhook() { + this.logger.verbose('Finding webhook'); + const data = await this.repository.webhook.find(this.instanceName); + + if (!data) { + this.logger.verbose('Webhook not found'); + throw new NotFoundException('Webhook not found'); + } + + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + return data; + } + + private async loadChatwoot() { + this.logger.verbose('Loading chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + this.localChatwoot.enabled = data?.enabled; + this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + + this.localChatwoot.account_id = data?.account_id; + this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); + + this.localChatwoot.token = data?.token; + this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); + + this.localChatwoot.url = data?.url; + this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); + + this.localChatwoot.name_inbox = data?.name_inbox; + this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); + + this.localChatwoot.sign_msg = data?.sign_msg; + this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + + this.localChatwoot.number = data?.number; + this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); + + this.localChatwoot.reopen_conversation = data?.reopen_conversation; + this.logger.verbose( + `Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`, + ); + + this.localChatwoot.conversation_pending = data?.conversation_pending; + this.logger.verbose( + `Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`, + ); + + this.logger.verbose('Chatwoot loaded'); + } + + public async setChatwoot(data: ChatwootRaw) { + this.logger.verbose('Setting chatwoot'); + await this.repository.chatwoot.create(data, this.instanceName); + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + Object.assign(this.localChatwoot, data); + this.logger.verbose('Chatwoot set'); + } + + public async findChatwoot() { + this.logger.verbose('Finding chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + + if (!data) { + this.logger.verbose('Chatwoot not found'); + return null; + } + + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + return data; + } + + private async loadSettings() { + this.logger.verbose('Loading settings'); + const data = await this.repository.settings.find(this.instanceName); + this.localSettings.reject_call = data?.reject_call; + this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); + + this.localSettings.msg_call = data?.msg_call; + this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); + + this.localSettings.groups_ignore = data?.groups_ignore; + this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + + this.logger.verbose('Settings loaded'); + } + + public async setSettings(data: SettingsRaw) { + this.logger.verbose('Setting settings'); + await this.repository.settings.create(data, this.instanceName); + this.logger.verbose(`Settings reject_call: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + Object.assign(this.localSettings, data); + this.logger.verbose('Settings set'); + + this.client?.ws?.close(); + } + + public async findSettings() { + this.logger.verbose('Finding settings'); + const data = await this.repository.settings.find(this.instanceName); + + if (!data) { + this.logger.verbose('Settings not found'); + return null; + } + + this.logger.verbose(`Settings url: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + return data; + } + + public async sendDataWebhook(event: Events, data: T, local = true) { + const webhookGlobal = this.configService.get('WEBHOOK'); + const webhookLocal = this.localWebhook.events; + const serverUrl = this.configService.get('SERVER').URL; + const we = event.replace(/[\.-]/gm, '_').toUpperCase(); + const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + + const expose = + this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const tokenStore = await this.repository.auth.find(this.instanceName); + const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + + const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + if (local) { + if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { + this.logger.verbose('Sending data to webhook local'); + let baseURL; + + if (this.localWebhook.webhook_by_events) { + baseURL = `${this.localWebhook.url}/${transformedWe}`; + } else { + baseURL = this.localWebhook.url; } - this.instance.name = name; - this.logger.verbose(`Instance '${this.instance.name}' initialized`); - this.logger.verbose('Sending instance status to webhook'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-local', + url: baseURL, + event, instance: this.instance.name, - status: 'created', + data, + destination: this.localWebhook.url, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } + + try { + if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { + const httpService = axios.create({ baseURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + postData['apikey'] = instanceApikey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-local', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: baseURL, + server_url: serverUrl, + }); + } + } + } + + if (webhookGlobal.GLOBAL?.ENABLED) { + if (webhookGlobal.EVENTS[we]) { + this.logger.verbose('Sending data to webhook global'); + const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; + + let globalURL; + + if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { + globalURL = `${globalWebhook.URL}/${transformedWe}`; + } else { + globalURL = globalWebhook.URL; + } + + const localUrl = this.localWebhook.url; + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-global', + url: globalURL, + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + logData['apikey'] = globalApiKey; + } + + this.logger.log(logData); + } + + try { + if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { + const httpService = axios.create({ baseURL: globalURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + postData['apikey'] = globalApiKey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-global', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: globalURL, + server_url: serverUrl, + }); + } + } + } + } + + private async connectionUpdate({ + qr, + connection, + lastDisconnect, + }: Partial) { + this.logger.verbose('Connection update'); + if (qr) { + this.logger.verbose('QR code found'); + if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { + this.logger.verbose('QR code limit reached'); + + this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); + this.sendDataWebhook(Events.QRCODE_UPDATED, { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, }); if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'created', - }, - ); - } - } - - public get instanceName() { - this.logger.verbose('Getting instance name'); - return this.instance.name; - } - - public get wuid() { - this.logger.verbose('Getting remoteJid of instance'); - return this.instance.wuid; - } - - public async getProfileName() { - this.logger.verbose('Getting profile name'); - let profileName = this.client.user?.name ?? this.client.user?.verifiedName; - if (!profileName) { - this.logger.verbose('Profile name not found, trying to get from database'); - if (this.configService.get('DATABASE').ENABLED) { - this.logger.verbose('Database enabled, trying to get from database'); - const collection = dbserver - .getClient() - .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(this.instanceName); - const data = await collection.findOne({ _id: 'creds' }); - if (data) { - this.logger.verbose('Profile name found in database'); - const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); - profileName = creds.me?.name || creds.me?.verifiedName; - } - } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { - this.logger.verbose('Profile name found in file'); - const creds = JSON.parse( - readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { - encoding: 'utf-8', - }), - ); - profileName = creds.me?.name || creds.me?.verifiedName; - } + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }, + ); } - this.logger.verbose(`Profile name: ${profileName}`); - return profileName; - } + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + state: 'refused', + statusReason: DisconnectReason.connectionClosed, + }); - public async getProfileStatus() { - this.logger.verbose('Getting profile status'); - const status = await this.client.fetchStatus(this.instance.wuid); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); - this.logger.verbose(`Profile status: ${status.status}`); - return status.status; - } - - public get profilePictureUrl() { - this.logger.verbose('Getting profile picture url'); - return this.instance.profilePictureUrl; - } - - public get qrCode(): wa.QrCode { - this.logger.verbose('Getting qrcode'); - if (this.instance.qrcode?.pairingCode) { - return { - pairingCode: this.instance.qrcode?.pairingCode, - }; + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); } - return { - code: this.instance.qrcode?.code, - base64: this.instance.qrcode?.base64, - }; - } + this.logger.verbose('endSession defined as true'); + this.endSession = true; - private async loadWebhook() { - this.logger.verbose('Loading webhook'); - const data = await this.repository.webhook.find(this.instanceName); - this.localWebhook.url = data?.url; - this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + this.logger.verbose('Emmiting event logout.instance'); + return this.eventEmitter.emit('no.connection', this.instance.name); + } - this.localWebhook.enabled = data?.enabled; - this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + this.logger.verbose('Incrementing QR code count'); + this.instance.qrcode.count++; - this.localWebhook.events = data?.events; - this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); + const optsQrcode: QRCodeToDataURLOptions = { + margin: 3, + scale: 4, + errorCorrectionLevel: 'H', + color: { light: '#ffffff', dark: '#198754' }, + }; - this.localWebhook.webhook_by_events = data?.webhook_by_events; - this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + if (this.phoneNumber) { + await delay(2000); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode( + this.phoneNumber, + ); + } else { + this.instance.qrcode.pairingCode = null; + } - this.logger.verbose('Webhook loaded'); - } - - public async setWebhook(data: WebhookRaw) { - this.logger.verbose('Setting webhook'); - await this.repository.webhook.create(data, this.instanceName); - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - Object.assign(this.localWebhook, data); - this.logger.verbose('Webhook set'); - } - - public async findWebhook() { - this.logger.verbose('Finding webhook'); - const data = await this.repository.webhook.find(this.instanceName); - - if (!data) { - this.logger.verbose('Webhook not found'); - throw new NotFoundException('Webhook not found'); + this.logger.verbose('Generating QR code'); + qrcode.toDataURL(qr, optsQrcode, (error, base64) => { + if (error) { + this.logger.error('Qrcode generate failed:' + error.toString()); + return; } - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - return data; - } + this.instance.qrcode.base64 = base64; + this.instance.qrcode.code = qr; - private async loadChatwoot() { - this.logger.verbose('Loading chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - this.localChatwoot.enabled = data?.enabled; - this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + this.sendDataWebhook(Events.QRCODE_UPDATED, { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }); - this.localChatwoot.account_id = data?.account_id; - this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); - - this.localChatwoot.token = data?.token; - this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); - - this.localChatwoot.url = data?.url; - this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); - - this.localChatwoot.name_inbox = data?.name_inbox; - this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); - - this.localChatwoot.sign_msg = data?.sign_msg; - this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); - - this.logger.verbose('Chatwoot loaded'); - } - - public async setChatwoot(data: ChatwootRaw) { - this.logger.verbose('Setting chatwoot'); - await this.repository.chatwoot.create(data, this.instanceName); - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - - Object.assign(this.localChatwoot, data); - this.logger.verbose('Chatwoot set'); - } - - public async findChatwoot() { - this.logger.verbose('Finding chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - - if (!data) { - this.logger.verbose('Chatwoot not found'); - return null; - } - - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - - return data; - } - - private async loadSettings() { - this.logger.verbose('Loading settings'); - const data = await this.repository.settings.find(this.instanceName); - this.localSettings.reject_call = data?.reject_call; - this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); - - this.localSettings.msg_call = data?.msg_call; - this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); - - this.localSettings.groups_ignore = data?.groups_ignore; - this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); - - this.logger.verbose('Settings loaded'); - } - - public async setSettings(data: SettingsRaw) { - this.logger.verbose('Setting settings'); - await this.repository.settings.create(data, this.instanceName); - this.logger.verbose(`Settings reject_call: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - Object.assign(this.localSettings, data); - this.logger.verbose('Settings set'); - } - - public async findSettings() { - this.logger.verbose('Finding settings'); - const data = await this.repository.settings.find(this.instanceName); - - if (!data) { - this.logger.verbose('Settings not found'); - throw new NotFoundException('Settings not found'); - } - - this.logger.verbose(`Settings url: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - return data; - } - - public async sendDataWebhook(event: Events, data: T, local = true) { - const webhookGlobal = this.configService.get('WEBHOOK'); - const webhookLocal = this.localWebhook.events; - const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[.-]/gm, '_').toUpperCase(); - const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - - const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; - const tokenStore = await this.repository.auth.find(this.instanceName); - const instanceApikey = tokenStore?.apikey || 'Apikey not found'; - - const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - if (local) { - if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { - this.logger.verbose('Sending data to webhook local'); - let baseURL; - - if (this.localWebhook.webhook_by_events) { - baseURL = `${this.localWebhook.url}/${transformedWe}`; - } else { - baseURL = this.localWebhook.url; - } - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-local', - url: baseURL, - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - apikey: (expose && instanceApikey) || null, - }; - - if (expose && instanceApikey) { - logData['apikey'] = instanceApikey; - } - - this.logger.log(logData); - } - - try { - if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { - const httpService = axios.create({ baseURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - }; - - if (expose && instanceApikey) { - postData['apikey'] = instanceApikey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-local', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: baseURL, - server_url: serverUrl, - }); - } - } - } - - if (webhookGlobal.GLOBAL?.ENABLED) { - if (webhookGlobal.EVENTS[we]) { - this.logger.verbose('Sending data to webhook global'); - const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; - - let globalURL; - - if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { - globalURL = `${globalWebhook.URL}/${transformedWe}`; - } else { - globalURL = globalWebhook.URL; - } - - const localUrl = this.localWebhook.url; - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-global', - url: globalURL, - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - logData['apikey'] = globalApiKey; - } - - this.logger.log(logData); - } - - try { - if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { - const httpService = axios.create({ baseURL: globalURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - postData['apikey'] = globalApiKey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-global', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: globalURL, - server_url: serverUrl, - }); - } - } - } - } - - private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { - this.logger.verbose('Connection update'); - if (qr) { - this.logger.verbose('QR code found'); - if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { - this.logger.verbose('QR code limit reached'); - - this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); - this.sendDataWebhook(Events.QRCODE_UPDATED, { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }, - ); - } - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - state: 'refused', - statusReason: DisconnectReason.connectionClosed, - }); - - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('endSession defined as true'); - this.endSession = true; - - this.logger.verbose('Emmiting event logout.instance'); - return this.eventEmitter.emit('no.connection', this.instance.name); - } - - this.logger.verbose('Incrementing QR code count'); - this.instance.qrcode.count++; - - const optsQrcode: QRCodeToDataURLOptions = { - margin: 3, - scale: 4, - errorCorrectionLevel: 'H', - color: { light: '#ffffff', dark: '#198754' }, - }; - - console.log(this.phoneNumber); - if (this.phoneNumber) { - await delay(2000); - this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); - } else { - this.instance.qrcode.pairingCode = null; - } - - this.logger.verbose('Generating QR code'); - qrcode.toDataURL(qr, optsQrcode, (error, base64) => { - if (error) { - this.logger.error('Qrcode generate failed:' + error.toString()); - return; - } - - this.instance.qrcode.base64 = base64; - this.instance.qrcode.code = qr; - - this.sendDataWebhook(Events.QRCODE_UPDATED, { - qrcode: { - instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - qrcode: { - instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }, - ); - } - }); - - this.logger.verbose('Generating QR code in terminal'); - qrcodeTerminal.generate(qr, { small: true }, (qrcode) => - this.logger.log( - `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + - qrcode, - ), - ); - } - - if (connection) { - this.logger.verbose('Connection found'); - this.stateConnection = { - state: connection, - statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, - }; - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + qrcode: { instance: this.instance.name, - ...this.stateConnection, - }); + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }, + ); + } + }); + + this.logger.verbose('Generating QR code in terminal'); + qrcodeTerminal.generate(qr, { small: true }, (qrcode) => + this.logger.log( + `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + + qrcode, + ), + ); + } + + if (connection) { + this.logger.verbose('Connection found'); + this.stateConnection = { + state: connection, + statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, + }; + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + ...this.stateConnection, + }); + } + + if (connection === 'close') { + this.logger.verbose('Connection closed'); + const shouldReconnect = + (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; + if (shouldReconnect) { + this.logger.verbose('Reconnecting to whatsapp'); + await this.connectToWhatsapp(); + } else { + this.logger.verbose('Do not reconnect to whatsapp'); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); } - if (connection === 'close') { - this.logger.verbose('Connection closed'); - const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; - if (shouldReconnect) { - this.logger.verbose('Reconnecting to whatsapp'); - await this.connectToWhatsapp(); - } else { - this.logger.verbose('Do not reconnect to whatsapp'); - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); + this.logger.verbose('Emittin event logout.instance'); + this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); + this.client?.ws?.close(); + this.client.end(new Error('Close connection')); + this.logger.verbose('Connection closed'); + } + } - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('Emittin event logout.instance'); - this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); - this.client?.ws?.close(); - this.client.end(new Error('Close connection')); - this.logger.verbose('Connection closed'); - } - } - - if (connection === 'open') { - this.logger.verbose('Connection opened'); - this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); - this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; - this.logger.info( - ` + if (connection === 'open') { + this.logger.verbose('Connection opened'); + this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); + this.instance.profilePictureUrl = ( + await this.profilePicture(this.instance.wuid) + ).profilePictureUrl; + this.logger.info( + ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ └──────────────────────────────┘`.replace(/^ +/gm, ' '), - ); + ); - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.CONNECTION_UPDATE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'open', - }, - ); - } - } + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.CONNECTION_UPDATE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'open', + }, + ); + } } + } - private async getMessage(key: proto.IMessageKey, full = false) { - this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); + private async getMessage(key: proto.IMessageKey, full = false) { + this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); + try { + const webMessageInfo = (await this.repository.message.find({ + where: { owner: this.instance.name, key: { id: key.id } }, + })) as unknown as proto.IWebMessageInfo[]; + if (full) { + this.logger.verbose('Returning full message'); + return webMessageInfo[0]; + } + if (webMessageInfo[0].message?.pollCreationMessage) { + this.logger.verbose('Returning poll message'); + const messageSecretBase64 = + webMessageInfo[0].message?.messageContextInfo?.messageSecret; + + if (typeof messageSecretBase64 === 'string') { + const messageSecret = Buffer.from(messageSecretBase64, 'base64'); + + const msg = { + messageContextInfo: { + messageSecret, + }, + pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, + }; + + return msg; + } + } + + this.logger.verbose('Returning message'); + return webMessageInfo[0].message; + } catch (error) { + return { conversation: '' }; + } + } + + private cleanStore() { + this.logger.verbose('Cronjob to clean store initialized'); + const cleanStore = this.configService.get('CLEAN_STORE'); + const database = this.configService.get('DATABASE'); + if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { + this.logger.verbose('Cronjob to clean store enabled'); + setInterval(() => { try { - const webMessageInfo = (await this.repository.message.find({ - where: { owner: this.instance.name, key: { id: key.id } }, - })) as unknown as proto.IWebMessageInfo[]; - if (full) { - this.logger.verbose('Returning full message'); - return webMessageInfo[0]; + for (const [key, value] of Object.entries(cleanStore)) { + if (value === true) { + execSync( + `rm -rf ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); + this.logger.verbose( + `Cleaned ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); } - if (webMessageInfo[0].message?.pollCreationMessage) { - this.logger.verbose('Returning poll message'); - const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; + } + } catch (error) {} + }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); + } + } - if (typeof messageSecretBase64 === 'string') { - const messageSecret = Buffer.from(messageSecretBase64, 'base64'); + private async defineAuthState() { + this.logger.verbose('Defining auth state'); + const db = this.configService.get('DATABASE'); + const redis = this.configService.get('REDIS'); - const msg = { - messageContextInfo: { - messageSecret, - }, - pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, - }; - - return msg; - } - } - - this.logger.verbose('Returning message'); - return webMessageInfo[0].message; - } catch (error) { - return { conversation: '' }; - } + if (redis?.ENABLED) { + this.logger.verbose('Redis enabled'); + this.cache.reference = this.instance.name; + return await useMultiFileAuthStateRedisDb(this.cache); } - private cleanStore() { - this.logger.verbose('Cronjob to clean store initialized'); - const cleanStore = this.configService.get('CLEAN_STORE'); + if (db.SAVE_DATA.INSTANCE && db.ENABLED) { + this.logger.verbose('Database enabled'); + return await useMultiFileAuthStateDb(this.instance.name); + } + + this.logger.verbose('Store file enabled'); + return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); + } + + public async connectToWhatsapp(number?: string): Promise { + this.logger.verbose('Connecting to whatsapp'); + try { + this.loadWebhook(); + this.loadChatwoot(); + this.loadSettings(); + + this.instance.authState = await this.defineAuthState(); + + const { version } = await fetchLatestBaileysVersion(); + this.logger.verbose('Baileys version: ' + version); + const session = this.configService.get('CONFIG_SESSION_PHONE'); + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + this.logger.verbose('Browser: ' + JSON.stringify(browser)); + + const socketConfig: UserFacingSocketConfig = { + auth: { + creds: this.instance.authState.state.creds, + keys: makeCacheableSignalKeyStore( + this.instance.authState.state.keys, + P({ level: 'error' }), + ), + }, + logger: P({ level: this.logBaileys }), + printQRInTerminal: false, + browser, + version, + markOnlineOnConnect: this.localSettings.always_online, + connectTimeoutMs: 60_000, + qrTimeout: 40_000, + defaultQueryTimeoutMs: undefined, + emitOwnEvents: false, + msgRetryCounterCache: this.msgRetryCounterCache, + getMessage: async (key) => + (await this.getMessage(key)) as Promise, + generateHighQualityLinkPreview: true, + syncFullHistory: true, + userDevicesCache: this.userDevicesCache, + transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, + patchMessageBeforeSending: (message) => { + const requiresPatch = !!( + message.buttonsMessage || + message.listMessage || + message.templateMessage + ); + if (requiresPatch) { + message = { + viewOnceMessageV2: { + message: { + messageContextInfo: { + deviceListMetadataVersion: 2, + deviceListMetadata: {}, + }, + ...message, + }, + }, + }; + } + + return message; + }, + }; + + this.endSession = false; + + this.logger.verbose('Creating socket'); + + this.client = makeWASocket(socketConfig); + + this.logger.verbose('Socket created'); + + this.eventHandler(); + + this.logger.verbose('Socket event handler initialized'); + + this.phoneNumber = number; + + return this.client; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString()); + } + } + + private readonly chatHandle = { + 'chats.upsert': async (chats: Chat[], database: Database) => { + this.logger.verbose('Event received: chats.upsert'); + + this.logger.verbose('Finding chats in database'); + const chatsRepository = await this.repository.chat.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if chats exists in database to insert'); + const chatsRaw: ChatRaw[] = []; + for await (const chat of chats) { + if (chatsRepository.find((cr) => cr.id === chat.id)) { + continue; + } + + chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); + } + + this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); + await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert( + chatsRaw, + this.instance.name, + database.SAVE_DATA.CHATS, + ); + }, + + 'chats.update': async ( + chats: Partial< + proto.IConversation & { + lastMessageRecvTimestamp?: number; + } & { + conditional: (bufferedData: BufferedEventData) => boolean; + } + >[], + ) => { + this.logger.verbose('Event received: chats.update'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { id: chat.id, owner: this.instance.wuid }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); + await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); + }, + + 'chats.delete': async (chats: string[]) => { + this.logger.verbose('Event received: chats.delete'); + + this.logger.verbose('Deleting chats in database'); + chats.forEach( + async (chat) => + await this.repository.chat.delete({ + where: { owner: this.instance.name, id: chat }, + }), + ); + + this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); + await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); + }, + }; + + private readonly contactHandle = { + 'contacts.upsert': async (contacts: Contact[], database: Database) => { + this.logger.verbose('Event received: contacts.upsert'); + + this.logger.verbose('Finding contacts in database'); + const contactsRepository = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if contacts exists in database to insert'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + if (contactsRepository.find((cr) => cr.id === contact.id)) { + continue; + } + + contactsRaw.push({ + id: contact.id, + pushName: contact?.name || contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); + + this.logger.verbose('Inserting contacts in database'); + await this.repository.contact.insert( + contactsRaw, + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); + }, + + 'contacts.update': async (contacts: Partial[], database: Database) => { + this.logger.verbose('Event received: contacts.update'); + + this.logger.verbose('Verifying if contacts exists in database to update'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + contactsRaw.push({ + id: contact.id, + pushName: contact?.name ?? contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); + + this.logger.verbose('Updating contacts in database'); + await this.repository.contact.update( + contactsRaw, + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); + }, + }; + + private readonly messageHandle = { + 'messaging-history.set': async ( + { + messages, + chats, + isLatest, + }: { + chats: Chat[]; + contacts: Contact[]; + messages: proto.IWebMessageInfo[]; + isLatest: boolean; + }, + database: Database, + ) => { + this.logger.verbose('Event received: messaging-history.set'); + if (isLatest) { + this.logger.verbose('isLatest defined as true'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { + id: chat.id, + owner: this.instance.name, + lastMsgTimestamp: chat.lastMessageRecvTimestamp, + }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_SET'); + await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert( + chatsRaw, + this.instance.name, + database.SAVE_DATA.CHATS, + ); + } + + const messagesRaw: MessageRaw[] = []; + const messagesRepository = await this.repository.message.find({ + where: { owner: this.instance.name }, + }); + for await (const [, m] of Object.entries(messages)) { + if (!m.message) { + continue; + } + if ( + messagesRepository.find( + (mr) => mr.owner === this.instance.name && mr.key.id === m.key.id, + ) + ) { + continue; + } + + if (Long.isLong(m?.messageTimestamp)) { + m.messageTimestamp = m.messageTimestamp?.toNumber(); + } + + messagesRaw.push({ + key: m.key, + pushName: m.pushName, + participant: m.participant, + message: { ...m.message }, + messageType: getContentType(m.message), + messageTimestamp: m.messageTimestamp as number, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); + this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); + + messages = undefined; + }, + + 'messages.upsert': async ( + { + messages, + type, + }: { + messages: proto.IWebMessageInfo[]; + type: MessageUpsertType; + }, + database: Database, + settings: SettingsRaw, + ) => { + this.logger.verbose('Event received: messages.upsert'); + const received = messages[0]; + + if ( + type !== 'notify' || + received.message?.protocolMessage || + received.message?.pollUpdateMessage + ) { + this.logger.verbose('message rejected'); + return; + } + + if (Long.isLong(received.messageTimestamp)) { + received.messageTimestamp = received.messageTimestamp?.toNumber(); + } + + if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + + const messageRaw: MessageRaw = { + key: received.key, + pushName: received.pushName, + message: { ...received.message }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), + }; + + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); + await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.MESSAGES_UPSERT, + { instanceName: this.instance.name }, + messageRaw, + ); + } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert( + [messageRaw], + this.instance.name, + database.SAVE_DATA.NEW_MESSAGE, + ); + + this.logger.verbose('Verifying contact from message'); + const contact = await this.repository.contact.find({ + where: { owner: this.instance.name, id: received.key.remoteJid }, + }); + + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: received.pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) + .profilePictureUrl, + owner: this.instance.name, + }; + + if (contactRaw.id === 'status@broadcast') { + this.logger.verbose('Contact is status@broadcast'); + return; + } + + if (contact?.length) { + this.logger.verbose('Contact found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: contact[0].pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) + .profilePictureUrl, + owner: this.instance.name, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.CONTACTS_UPDATE, + { instanceName: this.instance.name }, + contactRaw, + ); + } + + this.logger.verbose('Updating contact in database'); + await this.repository.contact.update( + [contactRaw], + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); + return; + } + + this.logger.verbose('Contact not found in database'); + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); + + this.logger.verbose('Inserting contact in database'); + await this.repository.contact.insert( + [contactRaw], + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); + }, + + 'messages.update': async ( + args: WAMessageUpdate[], + database: Database, + settings: SettingsRaw, + ) => { + this.logger.verbose('Event received: messages.update'); + const status: Record = { + 0: 'ERROR', + 1: 'PENDING', + 2: 'SERVER_ACK', + 3: 'DELIVERY_ACK', + 4: 'READ', + 5: 'PLAYED', + }; + for await (const { key, update } of args) { + if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { + this.logger.verbose('Message update is valid'); + + let pollUpdates: any; + if (update.pollUpdates) { + this.logger.verbose('Poll update found'); + + this.logger.verbose('Getting poll message'); + const pollCreation = await this.getMessage(key); + this.logger.verbose(pollCreation); + + if (pollCreation) { + this.logger.verbose('Getting aggregate votes in poll message'); + pollUpdates = getAggregateVotesInPollMessage({ + message: pollCreation as proto.IMessage, + pollUpdates: update.pollUpdates, + }); + } + } + + if (status[update.status] === 'READ' && !key.fromMe) return; + + if (update.message === null && update.status === undefined) { + this.logger.verbose('Message deleted'); + + this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); + await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + + const message: MessageUpdateRaw = { + ...key, + status: 'DELETED', + datetime: Date.now(), + owner: this.instance.name, + }; + + this.logger.verbose(message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + return; + } + + const message: MessageUpdateRaw = { + ...key, + status: status[update.status], + datetime: Date.now(), + owner: this.instance.name, + pollUpdates, + }; + + this.logger.verbose(message); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); + await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + } + } + }, + }; + + private readonly groupHandler = { + 'groups.upsert': (groupMetadata: GroupMetadata[]) => { + this.logger.verbose('Event received: groups.upsert'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); + this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); + }, + + 'groups.update': (groupMetadataUpdate: Partial[]) => { + this.logger.verbose('Event received: groups.update'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); + this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); + }, + + 'group-participants.update': (participantsUpdate: { + id: string; + participants: string[]; + action: ParticipantAction; + }) => { + this.logger.verbose('Event received: group-participants.update'); + + this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); + this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); + }, + }; + + private eventHandler() { + this.logger.verbose('Initializing event handler'); + this.client.ev.process(async (events) => { + if (!this.endSession) { const database = this.configService.get('DATABASE'); - if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { - this.logger.verbose('Cronjob to clean store enabled'); - setInterval(() => { - try { - for (const [key, value] of Object.entries(cleanStore)) { - if (value === true) { - execSync( - `rm -rf ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - this.logger.verbose( - `Cleaned ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - } - } - } catch (error) { - this.logger.error(error); - } - }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); - } - } + const settings = await this.findSettings(); - private async defineAuthState() { - this.logger.verbose('Defining auth state'); - const db = this.configService.get('DATABASE'); - const redis = this.configService.get('REDIS'); + if (events.call) { + this.logger.verbose('Listening event: call'); + const call = events.call[0]; - if (redis?.ENABLED) { - this.logger.verbose('Redis enabled'); - this.cache.reference = this.instance.name; - return await useMultiFileAuthStateRedisDb(this.cache); - } + if (settings?.reject_call && call.status == 'offer') { + this.logger.verbose('Rejecting call'); + this.client.rejectCall(call.id, call.from); + } - if (db.SAVE_DATA.INSTANCE && db.ENABLED) { - this.logger.verbose('Database enabled'); - return await useMultiFileAuthStateDb(this.instance.name); - } - - this.logger.verbose('Store file enabled'); - return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); - } - - public async connectToWhatsapp(number?: string): Promise { - this.logger.verbose('Connecting to whatsapp'); - try { - this.loadWebhook(); - this.loadChatwoot(); - this.loadSettings(); - - this.instance.authState = await this.defineAuthState(); - - const { version } = await fetchLatestBaileysVersion(); - this.logger.verbose('Baileys version: ' + version); - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - this.logger.verbose('Browser: ' + JSON.stringify(browser)); - - const socketConfig: UserFacingSocketConfig = { - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), - }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - browser, - version, - connectTimeoutMs: 60_000, - qrTimeout: 40_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: true, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, - patchMessageBeforeSending: (message) => { - const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); - if (requiresPatch) { - message = { - viewOnceMessageV2: { - message: { - messageContextInfo: { - deviceListMetadataVersion: 2, - deviceListMetadata: {}, - }, - ...message, - }, - }, - }; - } - - return message; - }, - }; - - this.endSession = false; - - this.logger.verbose('Creating socket'); - - this.client = makeWASocket(socketConfig); - - this.logger.verbose('Socket created'); - - this.eventHandler(); - - this.logger.verbose('Socket event handler initialized'); - - this.phoneNumber = number; - - return this.client; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString()); - } - } - - private readonly chatHandle = { - 'chats.upsert': async (chats: Chat[], database: Database) => { - this.logger.verbose('Event received: chats.upsert'); - - this.logger.verbose('Finding chats in database'); - const chatsRepository = await this.repository.chat.find({ - where: { owner: this.instance.name }, + if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { + this.logger.verbose('Sending message in call'); + const msg = await this.client.sendMessage(call.from, { + text: settings.msg_call, }); - this.logger.verbose('Verifying if chats exists in database to insert'); - const chatsRaw: ChatRaw[] = []; - for await (const chat of chats) { - if (chatsRepository.find((cr) => cr.id === chat.id)) { - continue; - } - - chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); - } - - this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); - await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); - }, - - 'chats.update': async ( - chats: Partial< - proto.IConversation & { - lastMessageRecvTimestamp?: number; - } & { - conditional: (bufferedData: BufferedEventData) => boolean; - } - >[], - ) => { - this.logger.verbose('Event received: chats.update'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { id: chat.id, owner: this.instance.wuid }; + this.logger.verbose('Sending data to event messages.upsert'); + this.client.ev.emit('messages.upsert', { + messages: [msg], + type: 'notify', }); - - this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); - await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); - }, - - 'chats.delete': async (chats: string[]) => { - this.logger.verbose('Event received: chats.delete'); - - this.logger.verbose('Deleting chats in database'); - chats.forEach( - async (chat) => - await this.repository.chat.delete({ - where: { owner: this.instance.name, id: chat }, - }), - ); - - this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); - await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); - }, - }; - - private readonly contactHandle = { - 'contacts.upsert': async (contacts: Contact[], database: Database) => { - this.logger.verbose('Event received: contacts.upsert'); - - this.logger.verbose('Finding contacts in database'); - const contactsRepository = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if contacts exists in database to insert'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - if (contactsRepository.find((cr) => cr.id === contact.id)) { - continue; - } - - contactsRaw.push({ - id: contact.id, - pushName: contact?.name || contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); - - this.logger.verbose('Inserting contacts in database'); - await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); - }, - - 'contacts.update': async (contacts: Partial[], database: Database) => { - this.logger.verbose('Event received: contacts.update'); - - this.logger.verbose('Verifying if contacts exists in database to update'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - contactsRaw.push({ - id: contact.id, - pushName: contact?.name ?? contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); - - this.logger.verbose('Updating contacts in database'); - await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); - }, - }; - - private readonly messageHandle = { - 'messaging-history.set': async ( - { - messages, - chats, - isLatest, - }: { - chats: Chat[]; - contacts: Contact[]; - messages: proto.IWebMessageInfo[]; - isLatest: boolean; - }, - database: Database, - ) => { - this.logger.verbose('Event received: messaging-history.set'); - if (isLatest) { - this.logger.verbose('isLatest defined as true'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { - id: chat.id, - owner: this.instance.name, - lastMsgTimestamp: chat.lastMessageRecvTimestamp, - }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_SET'); - await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); - } - - const messagesRaw: MessageRaw[] = []; - const messagesRepository = await this.repository.message.find({ - where: { owner: this.instance.name }, - }); - for await (const [, m] of Object.entries(messages)) { - if (!m.message) { - continue; - } - if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { - continue; - } - - if (Long.isLong(m?.messageTimestamp)) { - m.messageTimestamp = m.messageTimestamp?.toNumber(); - } - - messagesRaw.push({ - key: m.key, - pushName: m.pushName, - participant: m.participant, - message: { ...m.message }, - messageType: getContentType(m.message), - messageTimestamp: m.messageTimestamp as number, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); - this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); - - messages = undefined; - }, - - 'messages.upsert': async ( - { - messages, - type, - }: { - messages: proto.IWebMessageInfo[]; - type: MessageUpsertType; - }, - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.upsert'); - const received = messages[0]; - - if ( - type !== 'notify' || - // received.message?.protocolMessage || - received.message?.pollUpdateMessage - ) { - this.logger.verbose('message rejected'); - return; - } - - if (Long.isLong(received.messageTimestamp)) { - received.messageTimestamp = received.messageTimestamp?.toNumber(); - } - - if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - - const messageRaw: MessageRaw = { - key: received.key, - pushName: received.pushName, - message: { ...received.message }, - messageType: getContentType(received.message), - messageTimestamp: received.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(received.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); - await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, - messageRaw, - ); - } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); - - this.logger.verbose('Verifying contact from message'); - const contact = await this.repository.contact.find({ - where: { owner: this.instance.name, id: received.key.remoteJid }, - }); - - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: received.pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, - owner: this.instance.name, - }; - - if (contactRaw.id === 'status@broadcast') { - this.logger.verbose('Contact is status@broadcast'); - return; - } - - if (contact?.length) { - this.logger.verbose('Contact found in database'); - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: contact[0].pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, - owner: this.instance.name, - }; - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, - contactRaw, - ); - } - - this.logger.verbose('Updating contact in database'); - await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); - return; - } - - this.logger.verbose('Contact not found in database'); - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); - - this.logger.verbose('Inserting contact in database'); - await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); - }, - - 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { - this.logger.verbose('Event received: messages.update'); - const status: Record = { - 0: 'ERROR', - 1: 'PENDING', - 2: 'SERVER_ACK', - 3: 'DELIVERY_ACK', - 4: 'READ', - 5: 'PLAYED', - }; - for await (const { key, update } of args) { - if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { - this.logger.verbose('Message update is valid'); - - let pollUpdates: any; - if (update.pollUpdates) { - this.logger.verbose('Poll update found'); - - this.logger.verbose('Getting poll message'); - const pollCreation = await this.getMessage(key); - this.logger.verbose(pollCreation); - - if (pollCreation) { - this.logger.verbose('Getting aggregate votes in poll message'); - pollUpdates = getAggregateVotesInPollMessage({ - message: pollCreation as proto.IMessage, - pollUpdates: update.pollUpdates, - }); - } - } - - if (status[update.status] === 'READ' && !key.fromMe) return; - - if (update.message === null && update.status === undefined) { - this.logger.verbose('Message deleted'); - - this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); - await this.sendDataWebhook(Events.MESSAGES_DELETE, key); - - const message: MessageUpdateRaw = { - ...key, - status: 'DELETED', - datetime: Date.now(), - owner: this.instance.name, - }; - - this.logger.verbose(message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - return; - } - - const message: MessageUpdateRaw = { - ...key, - status: status[update.status], - datetime: Date.now(), - owner: this.instance.name, - pollUpdates, - }; - - this.logger.verbose(message); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); - await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - } - } - }, - }; - - private readonly groupHandler = { - 'groups.upsert': (groupMetadata: GroupMetadata[]) => { - this.logger.verbose('Event received: groups.upsert'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); - this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); - }, - - 'groups.update': (groupMetadataUpdate: Partial[]) => { - this.logger.verbose('Event received: groups.update'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); - this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - }, - - 'group-participants.update': (participantsUpdate: { - id: string; - participants: string[]; - action: ParticipantAction; - }) => { - this.logger.verbose('Event received: group-participants.update'); - - this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); - this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - }, - }; - - private eventHandler() { - this.logger.verbose('Initializing event handler'); - this.client.ev.process(async (events) => { - if (!this.endSession) { - const database = this.configService.get('DATABASE'); - const settings = await this.findSettings(); - - if (events.call) { - this.logger.verbose('Listening event: call'); - const call = events.call[0]; - - if (settings?.reject_call && call.status == 'offer') { - this.logger.verbose('Rejecting call'); - this.client.rejectCall(call.id, call.from); - } - - if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { - this.logger.verbose('Sending message in call'); - const msg = await this.client.sendMessage(call.from, { - text: settings.msg_call, - }); - - this.client.ev.emit('messages.upsert', { - messages: [msg], - type: 'notify', - }); - } - } - - if (events['connection.update']) { - this.logger.verbose('Listening event: connection.update'); - this.connectionUpdate(events['connection.update']); - } - - if (events['creds.update']) { - this.logger.verbose('Listening event: creds.update'); - this.instance.authState.saveCreds(); - } - - if (events['messaging-history.set']) { - this.logger.verbose('Listening event: messaging-history.set'); - const payload = events['messaging-history.set']; - this.messageHandle['messaging-history.set'](payload, database); - } - - if (events['messages.upsert']) { - this.logger.verbose('Listening event: messages.upsert'); - const payload = events['messages.upsert']; - this.messageHandle['messages.upsert'](payload, database, settings); - } - - if (events['messages.update']) { - this.logger.verbose('Listening event: messages.update'); - const payload = events['messages.update']; - this.messageHandle['messages.update'](payload, database, settings); - } - - if (events['presence.update']) { - this.logger.verbose('Listening event: presence.update'); - const payload = events['presence.update']; - - if (settings.groups_ignore && payload.id.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); - } - - if (!settings?.groups_ignore) { - if (events['groups.upsert']) { - this.logger.verbose('Listening event: groups.upsert'); - const payload = events['groups.upsert']; - this.groupHandler['groups.upsert'](payload); - } - - if (events['groups.update']) { - this.logger.verbose('Listening event: groups.update'); - const payload = events['groups.update']; - this.groupHandler['groups.update'](payload); - } - - if (events['group-participants.update']) { - this.logger.verbose('Listening event: group-participants.update'); - const payload = events['group-participants.update']; - this.groupHandler['group-participants.update'](payload); - } - } - - if (events['chats.upsert']) { - this.logger.verbose('Listening event: chats.upsert'); - const payload = events['chats.upsert']; - this.chatHandle['chats.upsert'](payload, database); - } - - if (events['chats.update']) { - this.logger.verbose('Listening event: chats.update'); - const payload = events['chats.update']; - this.chatHandle['chats.update'](payload); - } - - if (events['chats.delete']) { - this.logger.verbose('Listening event: chats.delete'); - const payload = events['chats.delete']; - this.chatHandle['chats.delete'](payload); - } - - if (events['contacts.upsert']) { - this.logger.verbose('Listening event: contacts.upsert'); - const payload = events['contacts.upsert']; - this.contactHandle['contacts.upsert'](payload, database); - } - - if (events['contacts.update']) { - this.logger.verbose('Listening event: contacts.update'); - const payload = events['contacts.update']; - this.contactHandle['contacts.update'](payload, database); - } - } - }); + } + + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); + } + + if (events['connection.update']) { + this.logger.verbose('Listening event: connection.update'); + this.connectionUpdate(events['connection.update']); + } + + if (events['creds.update']) { + this.logger.verbose('Listening event: creds.update'); + this.instance.authState.saveCreds(); + } + + if (events['messaging-history.set']) { + this.logger.verbose('Listening event: messaging-history.set'); + const payload = events['messaging-history.set']; + this.messageHandle['messaging-history.set'](payload, database); + } + + if (events['messages.upsert']) { + this.logger.verbose('Listening event: messages.upsert'); + const payload = events['messages.upsert']; + this.messageHandle['messages.upsert'](payload, database, settings); + } + + if (events['messages.update']) { + this.logger.verbose('Listening event: messages.update'); + const payload = events['messages.update']; + this.messageHandle['messages.update'](payload, database, settings); + } + + if (events['presence.update']) { + this.logger.verbose('Listening event: presence.update'); + const payload = events['presence.update']; + + if (settings.groups_ignore && payload.id.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); + } + + if (!settings?.groups_ignore) { + if (events['groups.upsert']) { + this.logger.verbose('Listening event: groups.upsert'); + const payload = events['groups.upsert']; + this.groupHandler['groups.upsert'](payload); + } + + if (events['groups.update']) { + this.logger.verbose('Listening event: groups.update'); + const payload = events['groups.update']; + this.groupHandler['groups.update'](payload); + } + + if (events['group-participants.update']) { + this.logger.verbose('Listening event: group-participants.update'); + const payload = events['group-participants.update']; + this.groupHandler['group-participants.update'](payload); + } + } + + if (events['chats.upsert']) { + this.logger.verbose('Listening event: chats.upsert'); + const payload = events['chats.upsert']; + this.chatHandle['chats.upsert'](payload, database); + } + + if (events['chats.update']) { + this.logger.verbose('Listening event: chats.update'); + const payload = events['chats.update']; + this.chatHandle['chats.update'](payload); + } + + if (events['chats.delete']) { + this.logger.verbose('Listening event: chats.delete'); + const payload = events['chats.delete']; + this.chatHandle['chats.delete'](payload); + } + + if (events['contacts.upsert']) { + this.logger.verbose('Listening event: contacts.upsert'); + const payload = events['contacts.upsert']; + this.contactHandle['contacts.upsert'](payload, database); + } + + if (events['contacts.update']) { + this.logger.verbose('Listening event: contacts.update'); + const payload = events['contacts.update']; + this.contactHandle['contacts.update'](payload, database); + } + } + }); + } + + // Check if the number is MX or AR + private formatMXOrARNumber(jid: string): string { + const countryCode = jid.substring(0, 2); + + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; + } + + return jid; + } + return jid; + } + + // Check if the number is br + private formatBRNumber(jid: string) { + const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); + if (regexp.test(jid)) { + const match = regexp.exec(jid); + if (match && match[1] === '55') { + const joker = Number.parseInt(match[3][0]); + const ddd = Number.parseInt(match[2]); + if (joker < 7 || ddd < 31) { + return match[0]; + } + return match[1] + match[2] + match[3]; + } + return jid; + } else { + return jid; + } + } + + private createJid(number: string): string { + this.logger.verbose('Creating jid with number: ' + number); + + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { + this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); + return number; } - // Check if the number is MX or AR - private formatMXOrARNumber(jid: string): string { - const countryCode = jid.substring(0, 2); - - if (Number(countryCode) === 52 || Number(countryCode) === 54) { - if (jid.length === 13) { - const number = countryCode + jid.substring(3); - return number; - } - - return jid; - } - return jid; + if (number.includes('@broadcast')) { + this.logger.verbose('Number already contains @broadcast'); + return number; } - // Check if the number is br - private formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } - return jid; - } else { - return jid; - } + number = number + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(/\:/)[0] + .split('@')[0]; + + if (number.includes('-') && number.length >= 24) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; } - private createJid(number: string): string { - this.logger.verbose('Creating jid with number: ' + number); + number = number.replace(/\D/g, ''); - if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { - this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return number; - } - - if (number.includes('@broadcast')) { - this.logger.verbose('Number already contains @broadcast'); - return number; - } - - number = number - ?.replace(/\s/g, '') - .replace(/\+/g, '') - .replace(/\(/g, '') - .replace(/\)/g, '') - .split(':')[0] - .split('@')[0]; - - if (number.length >= 18) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = number.replace(/\D/g, ''); - - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); - return `${number}@s.whatsapp.net`; + if (number.length >= 18) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; } - public async profilePicture(number: string) { - const jid = this.createJid(number); + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); + return `${number}@s.whatsapp.net`; + } - this.logger.verbose('Getting profile picture with jid: ' + jid); - try { - this.logger.verbose('Getting profile picture url'); - return { - wuid: jid, - profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), - }; - } catch (error) { - this.logger.verbose('Profile picture not found'); - return { - wuid: jid, - profilePictureUrl: null, - }; - } + public async profilePicture(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile picture with jid: ' + jid); + try { + this.logger.verbose('Getting profile picture url'); + return { + wuid: jid, + profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), + }; + } catch (error) { + this.logger.verbose('Profile picture not found'); + return { + wuid: jid, + profilePictureUrl: null, + }; + } + } + + public async getStatus(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile status with jid:' + jid); + try { + this.logger.verbose('Getting status'); + return { + wuid: jid, + status: (await this.client.fetchStatus(jid))?.status, + }; + } catch (error) { + this.logger.verbose('Status not found'); + return { + wuid: jid, + status: null, + }; + } + } + + public async fetchProfile(instanceName: string, number?: string) { + const jid = number ? this.createJid(number) : this.client?.user?.id; + + this.logger.verbose('Getting profile with jid: ' + jid); + try { + this.logger.verbose('Getting profile info'); + const info = await waMonitor.instanceInfo(instanceName); + const business = await this.fetchBusinessProfile(jid); + + if (number) { + const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); + const picture = await this.profilePicture(jid); + const status = await this.getStatus(jid); + + return { + wuid: jid, + name: info?.name, + numberExists: info?.exists, + picture: picture?.profilePictureUrl, + status: status?.status, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } else { + const info = await waMonitor.instanceInfo(instanceName); + + return { + wuid: jid, + name: info?.instance?.profileName, + numberExists: true, + picture: info?.instance?.profilePictureUrl, + status: info?.instance?.profileStatus, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } + } catch (error) { + this.logger.verbose('Profile not found'); + return { + wuid: jid, + name: null, + picture: null, + status: null, + os: null, + isBusiness: false, + }; + } + } + + private async sendMessageWithTyping( + number: string, + message: T, + options?: Options, + ) { + this.logger.verbose('Sending message with typing'); + + const numberWA = await this.whatsappNumber({ numbers: [number] }); + const isWA = numberWA[0]; + + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { + throw new BadRequestException(isWA); } - public async getStatus(number: string) { - const jid = this.createJid(number); + const sender = isWA.jid; - this.logger.verbose('Getting profile status with jid:' + jid); - try { - this.logger.verbose('Getting status'); - return { - wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, - }; - } catch (error) { - this.logger.verbose('Status not found'); - return { - wuid: jid, - status: null, - }; - } - } + try { + if (options?.delay) { + this.logger.verbose('Delaying message'); - public async fetchProfile(instanceName: string, number?: string) { - const jid = number ? this.createJid(number) : this.client?.user?.id; + await this.client.presenceSubscribe(sender); + this.logger.verbose('Subscribing to presence'); - this.logger.verbose('Getting profile with jid: ' + jid); - try { - this.logger.verbose('Getting profile info'); - const info = await waMonitor.instanceInfo(instanceName); - const business = await this.fetchBusinessProfile(jid); - - if (number) { - const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); - const picture = await this.profilePicture(jid); - const status = await this.getStatus(jid); - - return { - wuid: jid, - name: info?.name, - numberExists: info?.exists, - picture: picture?.profilePictureUrl, - status: status?.status, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } else { - const info = await waMonitor.instanceInfo(instanceName); - - return { - wuid: jid, - name: info?.instance?.profileName, - numberExists: true, - picture: info?.instance?.profilePictureUrl, - status: info?.instance?.profileStatus, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } - } catch (error) { - this.logger.verbose('Profile not found'); - return { - wuid: jid, - name: null, - picture: null, - status: null, - os: null, - isBusiness: false, - }; - } - } - - private async sendMessageWithTyping(number: string, message: T, options?: Options) { - this.logger.verbose('Sending message with typing'); - - const numberWA = await this.whatsappNumber({ numbers: [number] }); - const isWA = numberWA[0]; - - if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { - throw new BadRequestException(isWA); - } - - const sender = isWA.jid; - - try { - if (options?.delay) { - this.logger.verbose('Delaying message'); - - await this.client.presenceSubscribe(sender); - this.logger.verbose('Subscribing to presence'); - - await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); - this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); - - await delay(options.delay); - this.logger.verbose('Set delay: ' + options.delay); - - await this.client.sendPresenceUpdate('paused', sender); - this.logger.verbose('Sending presence update: paused'); - } - - const linkPreview = options?.linkPreview != false ? undefined : false; - - let quoted: WAMessage; - - if (options?.quoted) { - const m = options?.quoted; - - const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - quoted = msg; - this.logger.verbose('Quoted message'); - } - - let mentions: string[]; - if (isJidGroup(sender)) { - try { - const groupMetadata = await this.client.groupMetadata(sender); - - if (!groupMetadata) { - throw new NotFoundException('Group not found'); - } - - if (options?.mentions) { - this.logger.verbose('Mentions defined'); - - if (!Array.isArray(options.mentions.mentioned) && !options.mentions.everyOne) { - throw new BadRequestException('Mentions must be an array'); - } - - if (options.mentions.everyOne) { - this.logger.verbose('Mentions everyone'); - - this.logger.verbose('Getting group metadata'); - mentions = groupMetadata.participants.map((participant) => participant.id); - this.logger.verbose('Getting group metadata for mentions'); - } else { - this.logger.verbose('Mentions manually defined'); - mentions = options.mentions.mentioned.map((mention) => { - const jid = this.createJid(mention); - if (isJidGroup(jid)) { - return null; - // throw new BadRequestException('Mentions must be a number'); - } - return jid; - }); - } - } - } catch (error) { - throw new NotFoundException('Group not found'); - } - } - - const messageSent = await (async () => { - const option = { - quoted, - }; - - if ( - !message['audio'] && - !message['poll'] && - !message['sticker'] && - !message['conversation'] && - sender !== 'status@broadcast' - ) { - if (!message['audio']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - forward: { - key: { remoteJid: this.instance.wuid, fromMe: true }, - message, - }, - mentions, - }, - option as unknown as MiscMessageGenerationOptions, - ); - } - } - - if (message['conversation']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - text: message['conversation'], - mentions, - linkPreview: linkPreview, - } as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - } - - if (sender === 'status@broadcast') { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message['status'].content as unknown as AnyMessageContent, - { - backgroundColor: message['status'].option.backgroundColor, - font: message['status'].option.font, - statusJidList: message['status'].option.statusJidList, - } as unknown as MiscMessageGenerationOptions, - ); - } - - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - })(); - - const messageRaw: MessageRaw = { - key: messageSent.key, - pushName: messageSent.pushName, - message: { ...messageSent.message }, - messageType: getContentType(messageSent.message), - messageTimestamp: messageSent.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(messageSent.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); - await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - - // if (this.localChatwoot.enabled) { - // this.chatwootService.eventWhatsapp( - // Events.SEND_MESSAGE, - // { instanceName: this.instance.name }, - // messageRaw, - // ); - // } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, - ); - - return messageSent; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - // Instance Controller - public get connectionStatus() { - this.logger.verbose('Getting connection status'); - return this.stateConnection; - } - - // Send Message Controller - public async textMessage(data: SendTextDto) { - this.logger.verbose('Sending text message'); - return await this.sendMessageWithTyping( - data.number, - { - conversation: data.textMessage.text, - }, - data?.options, + await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); + this.logger.verbose( + 'Sending presence update: ' + options?.presence ?? 'composing', ); - } - public async pollMessage(data: SendPollDto) { - this.logger.verbose('Sending poll message'); - return await this.sendMessageWithTyping( - data.number, - { - poll: { - name: data.pollMessage.name, - selectableCount: data.pollMessage.selectableCount, - values: data.pollMessage.values, + await delay(options.delay); + this.logger.verbose('Set delay: ' + options.delay); + + await this.client.sendPresenceUpdate('paused', sender); + this.logger.verbose('Sending presence update: paused'); + } + + const linkPreview = options?.linkPreview != false ? undefined : false; + + let quoted: WAMessage; + + if (options?.quoted) { + const m = options?.quoted; + + const msg = m?.message + ? m + : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + quoted = msg; + this.logger.verbose('Quoted message'); + } + + let mentions: string[]; + if (isJidGroup(sender)) { + try { + const groupMetadata = await this.client.groupMetadata(sender); + + if (!groupMetadata) { + throw new NotFoundException('Group not found'); + } + + if (options?.mentions) { + this.logger.verbose('Mentions defined'); + + if (options.mentions?.everyOne) { + this.logger.verbose('Mentions everyone'); + + this.logger.verbose('Getting group metadata'); + mentions = groupMetadata.participants.map((participant) => participant.id); + this.logger.verbose('Getting group metadata for mentions'); + } else if (options.mentions?.mentioned?.length) { + this.logger.verbose('Mentions manually defined'); + mentions = options.mentions.mentioned.map((mention) => { + const jid = this.createJid(mention); + if (isJidGroup(jid)) { + return null; + // throw new BadRequestException('Mentions must be a number'); + } + return jid; + }); + } + } + } catch (error) { + throw new NotFoundException('Group not found'); + } + } + + const messageSent = await (async () => { + const option = { + quoted, + }; + + if ( + !message['audio'] && + !message['poll'] && + !message['sticker'] && + !message['conversation'] && + sender !== 'status@broadcast' + ) { + if (!message['audio']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + forward: { + key: { remoteJid: this.instance.wuid, fromMe: true }, + message, }, - }, - data?.options, + mentions, + }, + option as unknown as MiscMessageGenerationOptions, + ); + } + } + + if (message['conversation']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + text: message['conversation'], + mentions, + linkPreview: linkPreview, + } as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + } + + if (sender === 'status@broadcast') { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message['status'].content as unknown as AnyMessageContent, + { + backgroundColor: message['status'].option.backgroundColor, + font: message['status'].option.font, + statusJidList: message['status'].option.statusJidList, + } as unknown as MiscMessageGenerationOptions, + ); + } + + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, ); + })(); + + const messageRaw: MessageRaw = { + key: messageSent.key, + pushName: messageSent.pushName, + message: { ...messageSent.message }, + messageType: getContentType(messageSent.message), + messageTimestamp: messageSent.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(messageSent.key.id), + }; + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); + await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); + + // if (this.localChatwoot.enabled) { + // this.chatwootService.eventWhatsapp( + // Events.SEND_MESSAGE, + // { instanceName: this.instance.name }, + // messageRaw, + // ); + // } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert( + [messageRaw], + this.instance.name, + this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, + ); + + return messageSent; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + // Instance Controller + public get connectionStatus() { + this.logger.verbose('Getting connection status'); + return this.stateConnection; + } + + // Send Message Controller + public async textMessage(data: SendTextDto) { + this.logger.verbose('Sending text message'); + return await this.sendMessageWithTyping( + data.number, + { + conversation: data.textMessage.text, + }, + data?.options, + ); + } + + public async pollMessage(data: SendPollDto) { + this.logger.verbose('Sending poll message'); + return await this.sendMessageWithTyping( + data.number, + { + poll: { + name: data.pollMessage.name, + selectableCount: data.pollMessage.selectableCount, + values: data.pollMessage.values, + }, + }, + data?.options, + ); + } + + private async formatStatusMessage(status: StatusMessage) { + this.logger.verbose('Formatting status message'); + + if (!status.type) { + throw new BadRequestException('Type is required'); } - private async formatStatusMessage(status: StatusMessage) { - this.logger.verbose('Formatting status message'); - - if (!status.type) { - throw new BadRequestException('Type is required'); - } - - if (!status.content) { - throw new BadRequestException('Content is required'); - } - - if (status.allContacts) { - this.logger.verbose('All contacts defined as true'); - - this.logger.verbose('Getting contacts from database'); - const contacts = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - if (!contacts.length) { - throw new BadRequestException('Contacts not found'); - } - - this.logger.verbose('Getting contacts with push name'); - status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); - - this.logger.verbose(status.statusJidList); - } - - if (!status.statusJidList?.length && !status.allContacts) { - throw new BadRequestException('StatusJidList is required'); - } - - if (status.type === 'text') { - this.logger.verbose('Type defined as text'); - - if (!status.backgroundColor) { - throw new BadRequestException('Background color is required'); - } - - if (!status.font) { - throw new BadRequestException('Font is required'); - } - - return { - content: { - text: status.content, - }, - option: { - backgroundColor: status.backgroundColor, - font: status.font, - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'image') { - this.logger.verbose('Type defined as image'); - - return { - content: { - image: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'video') { - this.logger.verbose('Type defined as video'); - - return { - content: { - video: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'audio') { - this.logger.verbose('Type defined as audio'); - - this.logger.verbose('Processing audio'); - const convert = await this.processAudio(status.content, 'status@broadcast'); - if (typeof convert === 'string') { - this.logger.verbose('Audio processed'); - const audio = fs.readFileSync(convert).toString('base64'); - - const result = { - content: { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - option: { - statusJidList: status.statusJidList, - }, - }; - - fs.unlinkSync(convert); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - throw new BadRequestException('Type not found'); + if (!status.content) { + throw new BadRequestException('Content is required'); } - public async statusMessage(data: SendStatusDto) { - this.logger.verbose('Sending status message'); - const status = await this.formatStatusMessage(data.statusMessage); + if (status.allContacts) { + this.logger.verbose('All contacts defined as true'); - return await this.sendMessageWithTyping('status@broadcast', { - status, - }); + this.logger.verbose('Getting contacts from database'); + const contacts = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + if (!contacts.length) { + throw new BadRequestException('Contacts not found'); + } + + this.logger.verbose('Getting contacts with push name'); + status.statusJidList = contacts + .filter((contact) => contact.pushName) + .map((contact) => contact.id); + + this.logger.verbose(status.statusJidList); } - private async prepareMediaMessage(mediaMessage: MediaMessage) { - try { - this.logger.verbose('Preparing media message'); - const prepareMedia = await prepareWAMessageMedia( - { - [mediaMessage.mediatype]: isURL(mediaMessage.media) - ? { url: mediaMessage.media } - : Buffer.from(mediaMessage.media, 'base64'), - } as any, - { upload: this.client.waUploadToServer }, - ); - - const mediaType = mediaMessage.mediatype + 'Message'; - this.logger.verbose('Media type: ' + mediaType); - - if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { - this.logger.verbose('If media type is document and file name is not defined then'); - const regex = new RegExp(/.*\/(.+?)\./); - const arrayMatch = regex.exec(mediaMessage.media); - mediaMessage.fileName = arrayMatch[1]; - this.logger.verbose('File name: ' + mediaMessage.fileName); - } - - let mimetype: string; - - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); - } else { - mimetype = getMIMEType(mediaMessage.fileName); - } - - this.logger.verbose('Mimetype: ' + mimetype); - - prepareMedia[mediaType].caption = mediaMessage?.caption; - prepareMedia[mediaType].mimetype = mimetype; - prepareMedia[mediaType].fileName = mediaMessage.fileName; - - if (mediaMessage.mediatype === 'video') { - this.logger.verbose('Is media type video then set gif playback as false'); - prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( - readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), - ); - prepareMedia[mediaType].gifPlayback = false; - } - - this.logger.verbose('Generating wa message from content'); - return generateWAMessageFromContent( - '', - { [mediaType]: { ...prepareMedia[mediaType] } }, - { userJid: this.instance.wuid }, - ); - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString() || error); - } + if (!status.statusJidList?.length && !status.allContacts) { + throw new BadRequestException('StatusJidList is required'); } - private async convertToWebP(image: string, number: string) { - try { - this.logger.verbose('Converting image to WebP to sticker'); + if (status.type === 'text') { + this.logger.verbose('Type defined as text'); - let imagePath: string; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to image name: ' + hash); + if (!status.backgroundColor) { + throw new BadRequestException('Background color is required'); + } - const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; - this.logger.verbose('Output path: ' + outputPath); + if (!status.font) { + throw new BadRequestException('Font is required'); + } - if (isBase64(image)) { - this.logger.verbose('Image is base64'); + return { + content: { + text: status.content, + }, + option: { + backgroundColor: status.backgroundColor, + font: status.font, + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'image') { + this.logger.verbose('Type defined as image'); - const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); - const imageBuffer = Buffer.from(base64Data, 'base64'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); + return { + content: { + image: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'video') { + this.logger.verbose('Type defined as video'); - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } else { - this.logger.verbose('Image is url'); + return { + content: { + video: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'audio') { + this.logger.verbose('Type defined as audio'); - const timestamp = new Date().getTime(); - const url = `${image}?timestamp=${timestamp}`; - this.logger.verbose('including timestamp in url: ' + url); + this.logger.verbose('Processing audio'); + const convert = await this.processAudio(status.content, 'status@broadcast'); + if (typeof convert === 'string') { + this.logger.verbose('Audio processed'); + const audio = fs.readFileSync(convert).toString('base64'); - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting image from url'); + const result = { + content: { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + option: { + statusJidList: status.statusJidList, + }, + }; - const imageBuffer = Buffer.from(response.data, 'binary'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); + fs.unlinkSync(convert); - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } - - await sharp(imagePath).webp().toFile(outputPath); - this.logger.verbose('Image converted to WebP'); - - fs.unlinkSync(imagePath); - this.logger.verbose('Temp image deleted'); - - return outputPath; - } catch (error) { - console.error('Erro ao converter a imagem para WebP:', error); - } + return result; + } else { + throw new InternalServerErrorException(convert); + } } - public async mediaSticker(data: SendStickerDto) { - this.logger.verbose('Sending media sticker'); - const convert = await this.convertToWebP(data.stickerMessage.image, data.number); - const result = await this.sendMessageWithTyping( - data.number, - { - sticker: { url: convert }, - }, - data?.options, + throw new BadRequestException('Type not found'); + } + + public async statusMessage(data: SendStatusDto) { + this.logger.verbose('Sending status message'); + const status = await this.formatStatusMessage(data.statusMessage); + + return await this.sendMessageWithTyping('status@broadcast', { + status, + }); + } + + private async prepareMediaMessage(mediaMessage: MediaMessage) { + try { + this.logger.verbose('Preparing media message'); + const prepareMedia = await prepareWAMessageMedia( + { + [mediaMessage.mediatype]: isURL(mediaMessage.media) + ? { url: mediaMessage.media } + : Buffer.from(mediaMessage.media, 'base64'), + } as any, + { upload: this.client.waUploadToServer }, + ); + + const mediaType = mediaMessage.mediatype + 'Message'; + this.logger.verbose('Media type: ' + mediaType); + + if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { + this.logger.verbose( + 'If media type is document and file name is not defined then', + ); + const regex = new RegExp(/.*\/(.+?)\./); + const arrayMatch = regex.exec(mediaMessage.media); + mediaMessage.fileName = arrayMatch[1]; + this.logger.verbose('File name: ' + mediaMessage.fileName); + } + + let mimetype: string; + + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + } else { + mimetype = getMIMEType(mediaMessage.fileName); + } + + this.logger.verbose('Mimetype: ' + mimetype); + + prepareMedia[mediaType].caption = mediaMessage?.caption; + prepareMedia[mediaType].mimetype = mimetype; + prepareMedia[mediaType].fileName = mediaMessage.fileName; + + if (mediaMessage.mediatype === 'video') { + this.logger.verbose('Is media type video then set gif playback as false'); + prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( + readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), + ); + prepareMedia[mediaType].gifPlayback = false; + } + + this.logger.verbose('Generating wa message from content'); + return generateWAMessageFromContent( + '', + { [mediaType]: { ...prepareMedia[mediaType] } }, + { userJid: this.instance.wuid }, + ); + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString() || error); + } + } + + private async convertToWebP(image: string, number: string) { + try { + this.logger.verbose('Converting image to WebP to sticker'); + + let imagePath: string; + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to image name: ' + hash); + + const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; + this.logger.verbose('Output path: ' + outputPath); + + if (isBase64(image)) { + this.logger.verbose('Image is base64'); + + const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); + const imageBuffer = Buffer.from(base64Data, 'base64'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } else { + this.logger.verbose('Image is url'); + + const timestamp = new Date().getTime(); + const url = `${image}?timestamp=${timestamp}`; + this.logger.verbose('including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting image from url'); + + const imageBuffer = Buffer.from(response.data, 'binary'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } + + await sharp(imagePath).webp().toFile(outputPath); + this.logger.verbose('Image converted to WebP'); + + fs.unlinkSync(imagePath); + this.logger.verbose('Temp image deleted'); + + return outputPath; + } catch (error) { + console.error('Erro ao converter a imagem para WebP:', error); + } + } + + public async mediaSticker(data: SendStickerDto) { + this.logger.verbose('Sending media sticker'); + const convert = await this.convertToWebP(data.stickerMessage.image, data.number); + const result = await this.sendMessageWithTyping( + data.number, + { + sticker: { url: convert }, + }, + data?.options, + ); + + fs.unlinkSync(convert); + this.logger.verbose('Converted image deleted'); + + return result; + } + + public async mediaMessage(data: SendMediaDto) { + this.logger.verbose('Sending media message'); + const generate = await this.prepareMediaMessage(data.mediaMessage); + + return await this.sendMessageWithTyping( + data.number, + { ...generate.message }, + data?.options, + ); + } + + private async processAudio(audio: string, number: string) { + this.logger.verbose('Processing audio'); + let tempAudioPath: string; + let outputAudio: string; + + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to audio name: ' + hash); + + if (isURL(audio)) { + this.logger.verbose('Audio is url'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const timestamp = new Date().getTime(); + const url = `${audio}?timestamp=${timestamp}`; + + this.logger.verbose('Including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting audio from url'); + + fs.writeFileSync(tempAudioPath, response.data); + } else { + this.logger.verbose('Audio is base64'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const audioBuffer = Buffer.from(audio, 'base64'); + fs.writeFileSync(tempAudioPath, audioBuffer); + this.logger.verbose('Temp audio created'); + } + + this.logger.verbose('Converting audio to mp4'); + return new Promise((resolve, reject) => { + exec( + `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, + (error, _stdout, _stderr) => { + fs.unlinkSync(tempAudioPath); + this.logger.verbose('Temp audio deleted'); + + if (error) reject(error); + + this.logger.verbose('Audio converted to mp4'); + resolve(outputAudio); + }, + ); + }); + } + + public async audioWhatsapp(data: SendAudioDto) { + this.logger.verbose('Sending audio whatsapp'); + + if (!data.options?.encoding && data.options?.encoding !== false) { + data.options.encoding = true; + } + + if (data.options?.encoding) { + const convert = await this.processAudio(data.audioMessage.audio, data.number); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + const result = this.sendMessageWithTyping( + data.number, + { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + { presence: 'recording', delay: data?.options?.delay }, ); fs.unlinkSync(convert); - this.logger.verbose('Converted image deleted'); + this.logger.verbose('Converted audio deleted'); return result; + } else { + throw new InternalServerErrorException(convert); + } } - public async mediaMessage(data: SendMediaDto) { - this.logger.verbose('Sending media message'); - const generate = await this.prepareMediaMessage(data.mediaMessage); + return await this.sendMessageWithTyping( + data.number, + { + audio: isURL(data.audioMessage.audio) + ? { url: data.audioMessage.audio } + : Buffer.from(data.audioMessage.audio, 'base64'), + ptt: true, + mimetype: 'audio/ogg; codecs=opus', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); + } - return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); + public async buttonMessage(data: SendButtonDto) { + this.logger.verbose('Sending button message'); + const embeddedMedia: any = {}; + let mediatype = 'TEXT'; + + if (data.buttonMessage?.mediaMessage) { + mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; + embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; + const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); + embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; + embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; } - private async processAudio(audio: string, number: string) { - this.logger.verbose('Processing audio'); - let tempAudioPath: string; - let outputAudio: string; + const btnItems = { + text: data.buttonMessage.buttons.map((btn) => btn.buttonText), + ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + }; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to audio name: ' + hash); + if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { + throw new BadRequestException( + 'Button texts cannot be repeated', + 'Button IDs cannot be repeated.', + ); + } - if (isURL(audio)) { - this.logger.verbose('Audio is url'); + return await this.sendMessageWithTyping( + data.number, + { + buttonsMessage: { + text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, + contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, + footerText: data.buttonMessage?.footerText, + buttons: data.buttonMessage.buttons.map((button) => { + return { + buttonText: { + displayText: button.buttonText, + }, + buttonId: button.buttonId, + type: 1, + }; + }), + headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], + [embeddedMedia?.mediaKey]: embeddedMedia?.message, + }, + }, + data?.options, + ); + } - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + public async locationMessage(data: SendLocationDto) { + this.logger.verbose('Sending location message'); + return await this.sendMessageWithTyping( + data.number, + { + locationMessage: { + degreesLatitude: data.locationMessage.latitude, + degreesLongitude: data.locationMessage.longitude, + name: data.locationMessage?.name, + address: data.locationMessage?.address, + }, + }, + data?.options, + ); + } - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); + public async listMessage(data: SendListDto) { + this.logger.verbose('Sending list message'); + return await this.sendMessageWithTyping( + data.number, + { + listMessage: { + title: data.listMessage.title, + description: data.listMessage.description, + buttonText: data.listMessage?.buttonText, + footerText: data.listMessage?.footerText, + sections: data.listMessage.sections, + listType: 1, + }, + }, + data?.options, + ); + } - const timestamp = new Date().getTime(); - const url = `${audio}?timestamp=${timestamp}`; + public async contactMessage(data: SendContactDto) { + this.logger.verbose('Sending contact message'); + const message: proto.IMessage = {}; - this.logger.verbose('Including timestamp in url: ' + url); + const vcard = (contact: ContactMessage) => { + this.logger.verbose('Creating vcard'); + let result = + 'BEGIN:VCARD\n' + + 'VERSION:3.0\n' + + `N:${contact.fullName}\n` + + `FN:${contact.fullName}\n`; - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting audio from url'); + if (contact.organization) { + this.logger.verbose('Organization defined'); + result += `ORG:${contact.organization};\n`; + } - fs.writeFileSync(tempAudioPath, response.data); + if (contact.email) { + this.logger.verbose('Email defined'); + result += `EMAIL:${contact.email}\n`; + } + + if (contact.url) { + this.logger.verbose('Url defined'); + result += `URL:${contact.url}\n`; + } + + if (!contact.wuid) { + this.logger.verbose('Wuid defined'); + contact.wuid = this.createJid(contact.phoneNumber); + } + + result += + `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + + 'item1.X-ABLabel:Celular\n' + + 'END:VCARD'; + + this.logger.verbose('Vcard created'); + return result; + }; + + if (data.contactMessage.length === 1) { + message.contactMessage = { + displayName: data.contactMessage[0].fullName, + vcard: vcard(data.contactMessage[0]), + }; + } else { + message.contactsArrayMessage = { + displayName: `${data.contactMessage.length} contacts`, + contacts: data.contactMessage.map((contact) => { + return { + displayName: contact.fullName, + vcard: vcard(contact), + }; + }), + }; + } + + return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + } + + public async reactionMessage(data: SendReactionDto) { + this.logger.verbose('Sending reaction message'); + return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { + reactionMessage: { + key: data.reactionMessage.key, + text: data.reactionMessage.reaction, + }, + }); + } + + // Chat Controller + public async whatsappNumber(data: WhatsAppNumberDto) { + this.logger.verbose('Getting whatsapp number'); + + const onWhatsapp: OnWhatsAppDto[] = []; + for await (const number of data.numbers) { + let jid = this.createJid(number); + + if (isJidGroup(jid)) { + const group = await this.findGroup({ groupJid: jid }, 'inner'); + + if (!group) throw new BadRequestException('Group not found'); + + onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); + } else { + jid = !jid.startsWith('+') ? `+${jid}` : jid; + const verify = await this.client.onWhatsApp(jid); + + const result = verify[0]; + + if (!result) { + onWhatsapp.push(new OnWhatsAppDto(jid, false)); } else { - this.logger.verbose('Audio is base64'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const audioBuffer = Buffer.from(audio, 'base64'); - fs.writeFileSync(tempAudioPath, audioBuffer); - this.logger.verbose('Temp audio created'); + onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); } + } + } + return onWhatsapp; + } + + public async markMessageAsRead(data: ReadMessageDto) { + this.logger.verbose('Marking message as read'); + try { + const keys: proto.IMessageKey[] = []; + data.read_messages.forEach((read) => { + if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { + keys.push({ + remoteJid: read.remoteJid, + fromMe: read.fromMe, + id: read.id, + }); + } + }); + await this.client.readMessages(keys); + return { message: 'Read messages', read: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Read messages fail', error.toString()); + } + } + + public async archiveChat(data: ArchiveChatDto) { + this.logger.verbose('Archiving chat'); + try { + data.lastMessage.messageTimestamp = + data.lastMessage?.messageTimestamp ?? Date.now(); + await this.client.chatModify( + { + archive: data.archive, + lastMessages: [data.lastMessage], + }, + data.lastMessage.key.remoteJid, + ); + + return { + chatId: data.lastMessage.key.remoteJid, + archived: true, + }; + } catch (error) { + throw new InternalServerErrorException({ + archived: false, + message: [ + 'An error occurred while archiving the chat. Open a calling.', + error.toString(), + ], + }); + } + } + + public async deleteMessage(del: DeleteMessage) { + this.logger.verbose('Deleting message'); + try { + return await this.client.sendMessage(del.remoteJid, { delete: del }); + } catch (error) { + throw new InternalServerErrorException( + 'Error while deleting message for everyone', + error?.toString(), + ); + } + } + + public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { + this.logger.verbose('Getting base64 from media message'); + try { + const m = data?.message; + const convertToMp4 = data?.convertToMp4 ?? false; + + const msg = m?.message + ? m + : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + for (const subtype of MessageSubtype) { + if (msg.message[subtype]) { + msg.message = msg.message[subtype].message; + } + } + + let mediaMessage: any; + let mediaType: string; + + for (const type of TypeMediaMessage) { + mediaMessage = msg.message[type]; + if (mediaMessage) { + mediaType = type; + break; + } + } + + if (!mediaMessage) { + throw 'The message is not of the media type'; + } + + if (typeof mediaMessage['mediaKey'] === 'object') { + msg.message = JSON.parse(JSON.stringify(msg.message)); + } + + this.logger.verbose('Downloading media message'); + const buffer = await downloadMediaMessage( + { key: msg?.key, message: msg?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }), + reuploadRequest: this.client.updateMediaMessage, + }, + ); + const typeMessage = getContentType(msg.message); + + if (convertToMp4 && typeMessage === 'audioMessage') { this.logger.verbose('Converting audio to mp4'); - return new Promise((resolve, reject) => { - exec( - `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, - (error, _stdout, _stderr) => { - fs.unlinkSync(tempAudioPath); - this.logger.verbose('Temp audio deleted'); + const number = msg.key.remoteJid.split('@')[0]; + const convert = await this.processAudio(buffer.toString('base64'), number); - if (error) reject(error); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + this.logger.verbose('Audio converted to mp4'); - this.logger.verbose('Audio converted to mp4'); - resolve(outputAudio); - }, - ); - }); - } - - public async audioWhatsapp(data: SendAudioDto) { - this.logger.verbose('Sending audio whatsapp'); - - if (!data.options?.encoding && data.options?.encoding !== false) { - data.options.encoding = true; - } - - if (data.options?.encoding) { - const convert = await this.processAudio(data.audioMessage.audio, data.number); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - const result = this.sendMessageWithTyping( - data.number, - { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - return await this.sendMessageWithTyping( - data.number, - { - audio: isURL(data.audioMessage.audio) - ? { url: data.audioMessage.audio } - : Buffer.from(data.audioMessage.audio, 'base64'), - ptt: true, - mimetype: 'audio/ogg; codecs=opus', + const result = { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], }, - { presence: 'recording', delay: data?.options?.delay }, - ); - } + mimetype: 'audio/mp4', + base64: Buffer.from(audio, 'base64').toString('base64'), + }; - public async buttonMessage(data: SendButtonDto) { - this.logger.verbose('Sending button message'); - const embeddedMedia: any = {}; - let mediatype = 'TEXT'; + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); - if (data.buttonMessage?.mediaMessage) { - mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; - embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; - const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); - embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; - embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; + this.logger.verbose('Media message downloaded'); + return result; } + } - const btnItems = { - text: data.buttonMessage.buttons.map((btn) => btn.buttonText), - ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + this.logger.verbose('Media message downloaded'); + return { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: mediaMessage['mimetype'], + base64: buffer.toString('base64'), + }; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + public async fetchContacts(query: ContactQuery) { + this.logger.verbose('Fetching contacts'); + if (query?.where) { + query.where.owner = this.instance.name; + if (query.where?.id) { + query.where.id = this.createJid(query.where.id); + } + } else { + query = { + where: { + owner: this.instance.name, + }, + }; + } + return await this.repository.contact.find(query); + } + + public async fetchMessages(query: MessageQuery) { + this.logger.verbose('Fetching messages'); + if (query?.where) { + if (query.where?.key?.remoteJid) { + query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.message.find(query); + } + + public async fetchStatusMessage(query: MessageUpQuery) { + this.logger.verbose('Fetching status messages'); + if (query?.where) { + if (query.where?.remoteJid) { + query.where.remoteJid = this.createJid(query.where.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.messageUpdate.find(query); + } + + public async fetchChats() { + this.logger.verbose('Fetching chats'); + return await this.repository.chat.find({ where: { owner: this.instance.name } }); + } + + public async fetchPrivacySettings() { + this.logger.verbose('Fetching privacy settings'); + return await this.client.fetchPrivacySettings(); + } + + public async updatePrivacySettings(settings: PrivacySettingDto) { + this.logger.verbose('Updating privacy settings'); + try { + await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); + this.logger.verbose('Read receipts privacy updated'); + + await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); + this.logger.verbose('Profile picture privacy updated'); + + await this.client.updateStatusPrivacy(settings.privacySettings.status); + this.logger.verbose('Status privacy updated'); + + await this.client.updateOnlinePrivacy(settings.privacySettings.online); + this.logger.verbose('Online privacy updated'); + + await this.client.updateLastSeenPrivacy(settings.privacySettings.last); + this.logger.verbose('Last seen privacy updated'); + + await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); + this.logger.verbose('Groups add privacy updated'); + + this.client?.ws?.close(); + + return { + update: 'success', + data: { + readreceipts: settings.privacySettings.readreceipts, + profile: settings.privacySettings.profile, + status: settings.privacySettings.status, + online: settings.privacySettings.online, + last: settings.privacySettings.last, + groupadd: settings.privacySettings.groupadd, + }, + }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating privacy settings', + error.toString(), + ); + } + } + + public async fetchBusinessProfile(number: string): Promise { + this.logger.verbose('Fetching business profile'); + try { + const jid = number ? this.createJid(number) : this.instance.wuid; + + const profile = await this.client.getBusinessProfile(jid); + this.logger.verbose('Trying to get business profile'); + + if (!profile) { + const info = await this.whatsappNumber({ numbers: [jid] }); + + return { + isBusiness: false, + message: 'Not is business profile', + ...info?.shift(), + }; + } + + this.logger.verbose('Business profile fetched'); + return { + isBusiness: true, + ...profile, + }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating profile name', + error.toString(), + ); + } + } + + public async updateProfileName(name: string) { + this.logger.verbose('Updating profile name to ' + name); + try { + await this.client.updateProfileName(name); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating profile name', + error.toString(), + ); + } + } + + public async updateProfileStatus(status: string) { + this.logger.verbose('Updating profile status to: ' + status); + try { + await this.client.updateProfileStatus(status); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating profile status', + error.toString(), + ); + } + } + + public async updateProfilePicture(picture: string) { + this.logger.verbose('Updating profile picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(this.instance.wuid, pic); + this.logger.verbose('Profile picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating profile picture', + error.toString(), + ); + } + } + + public async removeProfilePicture() { + this.logger.verbose('Removing profile picture'); + try { + await this.client.removeProfilePicture(this.instance.wuid); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error removing profile picture', + error.toString(), + ); + } + } + + // Group + public async createGroup(create: CreateGroupDto) { + this.logger.verbose('Creating group: ' + create.subject); + try { + const participants = create.participants.map((p) => this.createJid(p)); + const { id } = await this.client.groupCreate(create.subject, participants); + this.logger.verbose('Group created: ' + id); + + if (create?.description) { + this.logger.verbose('Updating group description: ' + create.description); + await this.client.groupUpdateDescription(id, create.description); + } + + if (create?.promoteParticipants) { + this.logger.verbose('Prometing group participants: ' + create.description); + await this.updateGParticipant({ + groupJid: id, + action: 'promote', + participants: participants, + }); + } + + const group = await this.client.groupMetadata(id); + this.logger.verbose('Getting group metadata'); + + return group; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException('Error creating group', error.toString()); + } + } + + public async updateGroupPicture(picture: GroupPictureDto) { + this.logger.verbose('Updating group picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture.image)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture.image}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture.image)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture.image, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(picture.groupJid, pic); + this.logger.verbose('Group picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error update group picture', + error.toString(), + ); + } + } + + public async updateGroupSubject(data: GroupSubjectDto) { + this.logger.verbose('Updating group subject to: ' + data.subject); + try { + await this.client.groupUpdateSubject(data.groupJid, data.subject); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating group subject', + error.toString(), + ); + } + } + + public async updateGroupDescription(data: GroupDescriptionDto) { + this.logger.verbose('Updating group description to: ' + data.description); + try { + await this.client.groupUpdateDescription(data.groupJid, data.description); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException( + 'Error updating group description', + error.toString(), + ); + } + } + + public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { + this.logger.verbose('Fetching group'); + try { + return await this.client.groupMetadata(id.groupJid); + } catch (error) { + if (reply === 'inner') { + return; + } + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async fetchAllGroups(getParticipants: GetParticipant) { + this.logger.verbose('Fetching all groups'); + try { + const fetch = Object.values(await this.client.groupFetchAllParticipating()); + + const groups = fetch.map((group) => { + const result = { + id: group.id, + subject: group.subject, + subjectOwner: group.subjectOwner, + subjectTime: group.subjectTime, + size: group.size, + creation: group.creation, + owner: group.owner, + desc: group.desc, + descId: group.descId, + restrict: group.restrict, + announce: group.announce, }; - if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { - throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); + if (getParticipants.getParticipants == 'true') { + result['participants'] = group.participants; } - return await this.sendMessageWithTyping( - data.number, - { - buttonsMessage: { - text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, - contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, - footerText: data.buttonMessage?.footerText, - buttons: data.buttonMessage.buttons.map((button) => { - return { - buttonText: { - displayText: button.buttonText, - }, - buttonId: button.buttonId, - type: 1, - }; - }), - headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], - [embeddedMedia?.mediaKey]: embeddedMedia?.message, - }, - }, - data?.options, - ); + return result; + }); + + return groups; + } catch (error) { + throw new NotFoundException('Error fetching group', error.toString()); } + } - public async locationMessage(data: SendLocationDto) { - this.logger.verbose('Sending location message'); - return await this.sendMessageWithTyping( - data.number, - { - locationMessage: { - degreesLatitude: data.locationMessage.latitude, - degreesLongitude: data.locationMessage.longitude, - name: data.locationMessage?.name, - address: data.locationMessage?.address, - }, - }, - data?.options, - ); + public async inviteCode(id: GroupJid) { + this.logger.verbose('Fetching invite code for group: ' + id.groupJid); + try { + const code = await this.client.groupInviteCode(id.groupJid); + return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; + } catch (error) { + throw new NotFoundException('No invite code', error.toString()); } + } - public async listMessage(data: SendListDto) { - this.logger.verbose('Sending list message'); - return await this.sendMessageWithTyping( - data.number, - { - listMessage: { - title: data.listMessage.title, - description: data.listMessage.description, - buttonText: data.listMessage?.buttonText, - footerText: data.listMessage?.footerText, - sections: data.listMessage.sections, - listType: 1, - }, - }, - data?.options, - ); + public async inviteInfo(id: GroupInvite) { + this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); + try { + return await this.client.groupGetInviteInfo(id.inviteCode); + } catch (error) { + throw new NotFoundException('No invite info', id.inviteCode); } + } - public async contactMessage(data: SendContactDto) { - this.logger.verbose('Sending contact message'); - const message: proto.IMessage = {}; + public async sendInvite(id: GroupSendInvite) { + this.logger.verbose('Sending invite for group: ' + id.groupJid); + try { + const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); + this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); - const vcard = (contact: ContactMessage) => { - this.logger.verbose('Creating vcard'); - let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; + const inviteUrl = inviteCode.inviteUrl; + this.logger.verbose('Invite url: ' + inviteUrl); - if (contact.organization) { - this.logger.verbose('Organization defined'); - result += `ORG:${contact.organization};\n`; - } + const numbers = id.numbers.map((number) => this.createJid(number)); + const description = id.description ?? ''; - if (contact.email) { - this.logger.verbose('Email defined'); - result += `EMAIL:${contact.email}\n`; - } + const msg = `${description}\n\n${inviteUrl}`; - if (contact.url) { - this.logger.verbose('Url defined'); - result += `URL:${contact.url}\n`; - } + const message = { + conversation: msg, + }; - if (!contact.wuid) { - this.logger.verbose('Wuid defined'); - contact.wuid = this.createJid(contact.phoneNumber); - } + for await (const number of numbers) { + await this.sendMessageWithTyping(number, message); + } - result += - `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; + this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - this.logger.verbose('Vcard created'); - return result; - }; - - if (data.contactMessage.length === 1) { - message.contactMessage = { - displayName: data.contactMessage[0].fullName, - vcard: vcard(data.contactMessage[0]), - }; - } else { - message.contactsArrayMessage = { - displayName: `${data.contactMessage.length} contacts`, - contacts: data.contactMessage.map((contact) => { - return { - displayName: contact.fullName, - vcard: vcard(contact), - }; - }), - }; - } - - return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + return { send: true, inviteUrl }; + } catch (error) { + throw new NotFoundException('No send invite'); } + } - public async reactionMessage(data: SendReactionDto) { - this.logger.verbose('Sending reaction message'); - return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { - reactionMessage: { - key: data.reactionMessage.key, - text: data.reactionMessage.reaction, - }, - }); + public async revokeInviteCode(id: GroupJid) { + this.logger.verbose('Revoking invite code for group: ' + id.groupJid); + try { + const inviteCode = await this.client.groupRevokeInvite(id.groupJid); + return { revoked: true, inviteCode }; + } catch (error) { + throw new NotFoundException('Revoke error', error.toString()); } + } - // Chat Controller - public async whatsappNumber(data: WhatsAppNumberDto) { - this.logger.verbose('Getting whatsapp number'); - - const onWhatsapp: OnWhatsAppDto[] = []; - for await (const number of data.numbers) { - let jid = this.createJid(number); - - if (isJidGroup(jid)) { - const group = await this.findGroup({ groupJid: jid }, 'inner'); - - if (!group) throw new BadRequestException('Group not found'); - - onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); - } else { - jid = !jid.startsWith('+') ? `+${jid}` : jid; - const verify = await this.client.onWhatsApp(jid); - - const result = verify[0]; - - if (!result) { - onWhatsapp.push(new OnWhatsAppDto(jid, false)); - } else { - onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); - } - } - } - - return onWhatsapp; + public async findParticipants(id: GroupJid) { + this.logger.verbose('Fetching participants for group: ' + id.groupJid); + try { + const participants = (await this.client.groupMetadata(id.groupJid)).participants; + return { participants }; + } catch (error) { + throw new NotFoundException('No participants', error.toString()); } + } - public async markMessageAsRead(data: ReadMessageDto) { - this.logger.verbose('Marking message as read'); - try { - const keys: proto.IMessageKey[] = []; - data.readMessages.forEach((read) => { - if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { - keys.push({ - remoteJid: read.remoteJid, - fromMe: read.fromMe, - id: read.id, - }); - } - }); - await this.client.readMessages(keys); - return { message: 'Read messages', read: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Read messages fail', error.toString()); - } + public async updateGParticipant(update: GroupUpdateParticipantDto) { + this.logger.verbose('Updating participants'); + try { + const participants = update.participants.map((p) => this.createJid(p)); + const updateParticipants = await this.client.groupParticipantsUpdate( + update.groupJid, + participants, + update.action, + ); + return { updateParticipants: updateParticipants }; + } catch (error) { + throw new BadRequestException('Error updating participants', error.toString()); } + } - public async archiveChat(data: ArchiveChatDto) { - this.logger.verbose('Archiving chat'); - try { - data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); - await this.client.chatModify( - { - archive: data.archive, - lastMessages: [data.lastMessage], - }, - data.lastMessage.key.remoteJid, - ); - - return { - chatId: data.lastMessage.key.remoteJid, - archived: true, - }; - } catch (error) { - throw new InternalServerErrorException({ - archived: false, - message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], - }); - } + public async updateGSetting(update: GroupUpdateSettingDto) { + this.logger.verbose('Updating setting for group: ' + update.groupJid); + try { + const updateSetting = await this.client.groupSettingUpdate( + update.groupJid, + update.action, + ); + return { updateSetting: updateSetting }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); } + } - public async deleteMessage(del: DeleteMessage) { - this.logger.verbose('Deleting message'); - try { - return await this.client.sendMessage(del.remoteJid, { delete: del }); - } catch (error) { - throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); - } + public async toggleEphemeral(update: GroupToggleEphemeralDto) { + this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); + try { + const toggleEphemeral = await this.client.groupToggleEphemeral( + update.groupJid, + update.expiration, + ); + return { success: true }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); } + } - public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { - this.logger.verbose('Getting base64 from media message'); - try { - const m = data?.message; - const convertToMp4 = data?.convertToMp4 ?? false; - - const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - for (const subtype of MessageSubtype) { - if (msg.message[subtype]) { - msg.message = msg.message[subtype].message; - } - } - - let mediaMessage: any; - let mediaType: string; - - for (const type of TypeMediaMessage) { - mediaMessage = msg.message[type]; - if (mediaMessage) { - mediaType = type; - break; - } - } - - if (!mediaMessage) { - throw 'The message is not of the media type'; - } - - if (typeof mediaMessage['mediaKey'] === 'object') { - msg.message = JSON.parse(JSON.stringify(msg.message)); - } - - this.logger.verbose('Downloading media message'); - const buffer = await downloadMediaMessage( - { key: msg?.key, message: msg?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }), - reuploadRequest: this.client.updateMediaMessage, - }, - ); - const typeMessage = getContentType(msg.message); - - if (convertToMp4 && typeMessage === 'audioMessage') { - this.logger.verbose('Converting audio to mp4'); - const number = msg.key.remoteJid.split('@')[0]; - const convert = await this.processAudio(buffer.toString('base64'), number); - - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - this.logger.verbose('Audio converted to mp4'); - - const result = { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: 'audio/mp4', - base64: Buffer.from(audio, 'base64').toString('base64'), - }; - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - this.logger.verbose('Media message downloaded'); - return result; - } - } - - this.logger.verbose('Media message downloaded'); - return { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: mediaMessage['mimetype'], - base64: buffer.toString('base64'), - }; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - public async fetchContacts(query: ContactQuery) { - this.logger.verbose('Fetching contacts'); - if (query?.where) { - query.where.owner = this.instance.name; - if (query.where?.id) { - query.where.id = this.createJid(query.where.id); - } - } else { - query = { - where: { - owner: this.instance.name, - }, - }; - } - return await this.repository.contact.find(query); - } - - public async fetchMessages(query: MessageQuery) { - this.logger.verbose('Fetching messages'); - if (query?.where) { - if (query.where?.key?.remoteJid) { - query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.message.find(query); - } - - public async fetchStatusMessage(query: MessageUpQuery) { - this.logger.verbose('Fetching status messages'); - if (query?.where) { - if (query.where?.remoteJid) { - query.where.remoteJid = this.createJid(query.where.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.messageUpdate.find(query); - } - - public async fetchChats() { - this.logger.verbose('Fetching chats'); - return await this.repository.chat.find({ where: { owner: this.instance.name } }); - } - - public async fetchPrivacySettings() { - this.logger.verbose('Fetching privacy settings'); - return await this.client.fetchPrivacySettings(); - } - - public async updatePrivacySettings(settings: PrivacySettingDto) { - this.logger.verbose('Updating privacy settings'); - try { - await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); - this.logger.verbose('Read receipts privacy updated'); - - await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); - this.logger.verbose('Profile picture privacy updated'); - - await this.client.updateStatusPrivacy(settings.privacySettings.status); - this.logger.verbose('Status privacy updated'); - - await this.client.updateOnlinePrivacy(settings.privacySettings.online); - this.logger.verbose('Online privacy updated'); - - await this.client.updateLastSeenPrivacy(settings.privacySettings.last); - this.logger.verbose('Last seen privacy updated'); - - await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); - this.logger.verbose('Groups add privacy updated'); - - // reinicia a instancia - this.client?.ws?.close(); - - return { - update: 'success', - data: { - readreceipts: settings.privacySettings.readreceipts, - profile: settings.privacySettings.profile, - status: settings.privacySettings.status, - online: settings.privacySettings.online, - last: settings.privacySettings.last, - groupadd: settings.privacySettings.groupadd, - }, - }; - } catch (error) { - throw new InternalServerErrorException('Error updating privacy settings', error.toString()); - } - } - - public async fetchBusinessProfile(number: string): Promise { - this.logger.verbose('Fetching business profile'); - try { - const jid = number ? this.createJid(number) : this.instance.wuid; - - const profile = await this.client.getBusinessProfile(jid); - this.logger.verbose('Trying to get business profile'); - - if (!profile) { - const info = await this.whatsappNumber({ numbers: [jid] }); - - return { - isBusiness: false, - message: 'Not is business profile', - ...info?.shift(), - }; - } - - this.logger.verbose('Business profile fetched'); - return { - isBusiness: true, - ...profile, - }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile name', error.toString()); - } - } - - public async updateProfileName(name: string) { - this.logger.verbose('Updating profile name to ' + name); - try { - await this.client.updateProfileName(name); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile name', error.toString()); - } - } - - public async updateProfileStatus(status: string) { - this.logger.verbose('Updating profile status to: ' + status); - try { - await this.client.updateProfileStatus(status); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile status', error.toString()); - } - } - - public async updateProfilePicture(picture: string) { - this.logger.verbose('Updating profile picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(this.instance.wuid, pic); - this.logger.verbose('Profile picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile picture', error.toString()); - } - } - - public async removeProfilePicture() { - this.logger.verbose('Removing profile picture'); - try { - await this.client.removeProfilePicture(this.instance.wuid); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error removing profile picture', error.toString()); - } - } - - // Group - public async createGroup(create: CreateGroupDto) { - this.logger.verbose('Creating group: ' + create.subject); - try { - const participants = create.participants.map((p) => this.createJid(p)); - const { id } = await this.client.groupCreate(create.subject, participants); - this.logger.verbose('Group created: ' + id); - - if (create?.description) { - this.logger.verbose('Updating group description: ' + create.description); - await this.client.groupUpdateDescription(id, create.description); - } - - const group = await this.client.groupMetadata(id); - this.logger.verbose('Getting group metadata'); - - return { groupMetadata: group }; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException('Error creating group', error.toString()); - } - } - - public async updateGroupPicture(picture: GroupPictureDto) { - this.logger.verbose('Updating group picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture.image)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture.image}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture.image)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture.image, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(picture.groupJid, pic); - this.logger.verbose('Group picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error update group picture', error.toString()); - } - } - - public async updateGroupSubject(data: GroupSubjectDto) { - this.logger.verbose('Updating group subject to: ' + data.subject); - try { - await this.client.groupUpdateSubject(data.groupJid, data.subject); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating group subject', error.toString()); - } - } - - public async updateGroupDescription(data: GroupDescriptionDto) { - this.logger.verbose('Updating group description to: ' + data.description); - try { - await this.client.groupUpdateDescription(data.groupJid, data.description); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating group description', error.toString()); - } - } - - public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { - this.logger.verbose('Fetching group'); - try { - return await this.client.groupMetadata(id.groupJid); - } catch (error) { - if (reply === 'inner') { - return; - } - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async fetchAllGroups(getParticipants: GetParticipant) { - this.logger.verbose('Fetching all groups'); - try { - const fetch = Object.values(await this.client.groupFetchAllParticipating()); - - const groups = fetch.map((group) => { - const result = { - id: group.id, - subject: group.subject, - subjectOwner: group.subjectOwner, - subjectTime: group.subjectTime, - size: group.size, - creation: group.creation, - owner: group.owner, - desc: group.desc, - descId: group.descId, - restrict: group.restrict, - announce: group.announce, - }; - - if (getParticipants.getParticipants == 'true') { - result['participants'] = group.participants; - } - - return result; - }); - - return groups; - } catch (error) { - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async inviteCode(id: GroupJid) { - this.logger.verbose('Fetching invite code for group: ' + id.groupJid); - try { - const code = await this.client.groupInviteCode(id.groupJid); - return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; - } catch (error) { - throw new NotFoundException('No invite code', error.toString()); - } - } - - public async inviteInfo(id: GroupInvite) { - this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); - try { - return await this.client.groupGetInviteInfo(id.inviteCode); - } catch (error) { - throw new NotFoundException('No invite info', id.inviteCode); - } - } - - public async sendInvite(id: GroupSendInvite) { - this.logger.verbose('Sending invite for group: ' + id.groupJid); - try { - const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); - this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); - - const inviteUrl = inviteCode.inviteUrl; - this.logger.verbose('Invite url: ' + inviteUrl); - - const numbers = id.numbers.map((number) => this.createJid(number)); - const description = id.description ?? ''; - - const msg = `${description}\n\n${inviteUrl}`; - - const message = { - conversation: msg, - }; - - for await (const number of numbers) { - await this.sendMessageWithTyping(number, message); - } - - this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - - return { send: true, inviteUrl }; - } catch (error) { - throw new NotFoundException('No send invite'); - } - } - - public async revokeInviteCode(id: GroupJid) { - this.logger.verbose('Revoking invite code for group: ' + id.groupJid); - try { - const inviteCode = await this.client.groupRevokeInvite(id.groupJid); - return { revoked: true, inviteCode }; - } catch (error) { - throw new NotFoundException('Revoke error', error.toString()); - } - } - - public async findParticipants(id: GroupJid) { - this.logger.verbose('Fetching participants for group: ' + id.groupJid); - try { - const participants = (await this.client.groupMetadata(id.groupJid)).participants; - return { participants }; - } catch (error) { - throw new NotFoundException('No participants', error.toString()); - } - } - - public async updateGParticipant(update: GroupUpdateParticipantDto) { - this.logger.verbose('Updating participants'); - try { - const participants = update.participants.map((p) => this.createJid(p)); - const updateParticipants = await this.client.groupParticipantsUpdate( - update.groupJid, - participants, - update.action, - ); - return { updateParticipants: updateParticipants }; - } catch (error) { - throw new BadRequestException('Error updating participants', error.toString()); - } - } - - public async updateGSetting(update: GroupUpdateSettingDto) { - this.logger.verbose('Updating setting for group: ' + update.groupJid); - try { - const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); - return { updateSetting: updateSetting }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } - - public async toggleEphemeral(update: GroupToggleEphemeralDto) { - this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); - try { - const toggleEphemeral = await this.client.groupToggleEphemeral(update.groupJid, update.expiration); - return { success: true }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } - - public async leaveGroup(id: GroupJid) { - this.logger.verbose('Leaving group: ' + id.groupJid); - try { - await this.client.groupLeave(id.groupJid); - return { groupJid: id.groupJid, leave: true }; - } catch (error) { - throw new BadRequestException('Unable to leave the group', error.toString()); - } + public async leaveGroup(id: GroupJid) { + this.logger.verbose('Leaving group: ' + id.groupJid); + try { + await this.client.groupLeave(id.groupJid); + return { groupJid: id.groupJid, leave: true }; + } catch (error) { + throw new BadRequestException('Unable to leave the group', error.toString()); } + } } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 7e4b8352..a0d514d8 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -2,81 +2,101 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys'; export enum Events { - APPLICATION_STARTUP = 'application.startup', - QRCODE_UPDATED = 'qrcode.updated', - CONNECTION_UPDATE = 'connection.update', - STATUS_INSTANCE = 'status.instance', - MESSAGES_SET = 'messages.set', - MESSAGES_UPSERT = 'messages.upsert', - MESSAGES_UPDATE = 'messages.update', - MESSAGES_DELETE = 'messages.delete', - SEND_MESSAGE = 'send.message', - CONTACTS_SET = 'contacts.set', - CONTACTS_UPSERT = 'contacts.upsert', - CONTACTS_UPDATE = 'contacts.update', - PRESENCE_UPDATE = 'presence.update', - CHATS_SET = 'chats.set', - CHATS_UPDATE = 'chats.update', - CHATS_UPSERT = 'chats.upsert', - CHATS_DELETE = 'chats.delete', - GROUPS_UPSERT = 'groups.upsert', - GROUPS_UPDATE = 'groups.update', - GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + APPLICATION_STARTUP = 'application.startup', + QRCODE_UPDATED = 'qrcode.updated', + CONNECTION_UPDATE = 'connection.update', + STATUS_INSTANCE = 'status.instance', + MESSAGES_SET = 'messages.set', + MESSAGES_UPSERT = 'messages.upsert', + MESSAGES_UPDATE = 'messages.update', + MESSAGES_DELETE = 'messages.delete', + SEND_MESSAGE = 'send.message', + CONTACTS_SET = 'contacts.set', + CONTACTS_UPSERT = 'contacts.upsert', + CONTACTS_UPDATE = 'contacts.update', + PRESENCE_UPDATE = 'presence.update', + CHATS_SET = 'chats.set', + CHATS_UPDATE = 'chats.update', + CHATS_UPSERT = 'chats.upsert', + CHATS_DELETE = 'chats.delete', + GROUPS_UPSERT = 'groups.upsert', + GROUPS_UPDATE = 'groups.update', + GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { - export type QrCode = { - count?: number; - pairingCode?: string; - base64?: string; - code?: string; - }; - export type Instance = { - qrcode?: QrCode; - pairingCode?: string; - authState?: { state: AuthenticationState; saveCreds: () => void }; - name?: string; - wuid?: string; - profileName?: string; - profilePictureUrl?: string; - }; + export type QrCode = { + count?: number; + pairingCode?: string; + base64?: string; + code?: string; + }; + export type Instance = { + qrcode?: QrCode; + pairingCode?: string; + authState?: { state: AuthenticationState; saveCreds: () => void }; + name?: string; + wuid?: string; + profileName?: string; + profilePictureUrl?: string; + }; - export type LocalWebHook = { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; - }; + export type LocalWebHook = { + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; + }; - export type LocalChatwoot = { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - }; + export type LocalChatwoot = { + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; + }; - export type LocalSettings = { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - }; + export type LocalSettings = { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + }; - export type StateConnection = { - instance?: string; - state?: WAConnectionState | 'refused'; - statusReason?: number; - }; + export type StateConnection = { + instance?: string; + state?: WAConnectionState | 'refused'; + statusReason?: number; + }; - export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; + export type StatusMessage = + | 'ERROR' + | 'PENDING' + | 'SERVER_ACK' + | 'DELIVERY_ACK' + | 'READ' + | 'DELETED' + | 'PLAYED'; } -export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage']; +export const TypeMediaMessage = [ + 'imageMessage', + 'documentMessage', + 'audioMessage', + 'videoMessage', + 'stickerMessage', +]; export const MessageSubtype = [ - 'ephemeralMessage', - 'documentWithCaptionMessage', - 'viewOnceMessage', - 'viewOnceMessageV2', + 'ephemeralMessage', + 'documentWithCaptionMessage', + 'viewOnceMessage', + 'viewOnceMessageV2', ]; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index e783d490..b8f3b1ad 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -1,44 +1,43 @@ -import { delay } from '@whiskeysockets/baileys'; - import { Auth, configService } from '../config/env.config'; -import { eventEmitter } from '../config/event.config'; import { Logger } from '../config/logger.config'; -import { dbserver } from '../db/db.connect'; -import { RedisCache } from '../db/redis.client'; +import { eventEmitter } from '../config/event.config'; +import { MessageRepository } from './repository/message.repository'; +import { WAMonitoringService } from './services/monitor.service'; +import { ChatRepository } from './repository/chat.repository'; +import { ContactRepository } from './repository/contact.repository'; +import { MessageUpRepository } from './repository/messageUp.repository'; import { ChatController } from './controllers/chat.controller'; -import { ChatwootController } from './controllers/chatwoot.controller'; -import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; -import { SettingsController } from './controllers/settings.controller'; -import { ViewsController } from './controllers/views.controller'; -import { WebhookController } from './controllers/webhook.controller'; -import { - AuthModel, - ChatModel, - ChatwootModel, - ContactModel, - MessageModel, - MessageUpModel, - SettingsModel, - WebhookModel, -} from './models'; -import { AuthRepository } from './repository/auth.repository'; -import { ChatRepository } from './repository/chat.repository'; -import { ChatwootRepository } from './repository/chatwoot.repository'; -import { ContactRepository } from './repository/contact.repository'; -import { MessageRepository } from './repository/message.repository'; -import { MessageUpRepository } from './repository/messageUp.repository'; -import { RepositoryBroker } from './repository/repository.manager'; -import { SettingsRepository } from './repository/settings.repository'; -import { WebhookRepository } from './repository/webhook.repository'; import { AuthService } from './services/auth.service'; -import { ChatwootService } from './services/chatwoot.service'; -import { WAMonitoringService } from './services/monitor.service'; -import { SettingsService } from './services/settings.service'; +import { GroupController } from './controllers/group.controller'; +import { ViewsController } from './controllers/views.controller'; import { WebhookService } from './services/webhook.service'; +import { WebhookController } from './controllers/webhook.controller'; +import { ChatwootService } from './services/chatwoot.service'; +import { ChatwootController } from './controllers/chatwoot.controller'; +import { RepositoryBroker } from './repository/repository.manager'; +import { + AuthModel, + ChatModel, + ContactModel, + MessageModel, + MessageUpModel, + ChatwootModel, + WebhookModel, + SettingsModel, +} from './models'; +import { dbserver } from '../db/db.connect'; +import { WebhookRepository } from './repository/webhook.repository'; +import { ChatwootRepository } from './repository/chatwoot.repository'; +import { AuthRepository } from './repository/auth.repository'; import { WAStartupService } from './services/whatsapp.service'; +import { delay } from '@whiskeysockets/baileys'; import { Events } from './types/wa.types'; +import { RedisCache } from '../db/redis.client'; +import { SettingsRepository } from './repository/settings.repository'; +import { SettingsService } from './services/settings.service'; +import { SettingsController } from './controllers/settings.controller'; const logger = new Logger('WA MODULE'); @@ -52,21 +51,26 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); export const repository = new RepositoryBroker( - messageRepository, - chatRepository, - contactRepository, - messageUpdateRepository, - webhookRepository, - chatwootRepository, - settingsRepository, - authRepository, - configService, - dbserver?.getClient(), + messageRepository, + chatRepository, + contactRepository, + messageUpdateRepository, + webhookRepository, + chatwootRepository, + settingsRepository, + authRepository, + configService, + dbserver?.getClient(), ); export const cache = new RedisCache(); -export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache); +export const waMonitor = new WAMonitoringService( + eventEmitter, + configService, + repository, + cache, +); const authService = new AuthService(configService, waMonitor, repository); @@ -83,14 +87,15 @@ const settingsService = new SettingsService(waMonitor); export const settingsController = new SettingsController(settingsService); export const instanceController = new InstanceController( - waMonitor, - configService, - repository, - eventEmitter, - authService, - webhookService, - chatwootService, - cache, + waMonitor, + configService, + repository, + eventEmitter, + authService, + webhookService, + chatwootService, + settingsService, + cache, ); export const viewsController = new ViewsController(waMonitor, configService); export const sendMessageController = new SendMessageController(waMonitor); From ddc75d710fc0a96d907e0511d9c82f12e74dbd0b Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 11:08:14 -0300 Subject: [PATCH 069/177] wip --- package.json | 1 + src/config/env.config.ts | 416 +- src/validate/validate.schema.ts | 1447 ++--- .../controllers/chatwoot.controller.ts | 164 +- .../controllers/instance.controller.ts | 646 +- .../controllers/settings.controller.ts | 27 +- src/whatsapp/dto/chat.dto.ts | 89 +- src/whatsapp/dto/chatwoot.dto.ts | 18 +- src/whatsapp/dto/group.dto.ts | 40 +- src/whatsapp/dto/instance.dto.ts | 38 +- src/whatsapp/dto/settings.dto.ts | 12 +- src/whatsapp/models/chatwoot.model.ts | 43 +- src/whatsapp/models/settings.model.ts | 35 +- src/whatsapp/repository/repository.manager.ts | 228 +- src/whatsapp/routers/chatwoot.router.ts | 2 +- src/whatsapp/routers/settings.router.ts | 2 +- src/whatsapp/services/chatwoot.service.ts | 3097 +++++---- src/whatsapp/services/monitor.service.ts | 1 - src/whatsapp/services/whatsapp.service.ts | 5709 ++++++++--------- src/whatsapp/types/wa.types.ts | 157 +- src/whatsapp/whatsapp.module.ts | 112 +- 21 files changed, 5975 insertions(+), 6309 deletions(-) diff --git a/package.json b/package.json index 0e0407a1..ac392703 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "@types/express": "^4.17.17", "@types/js-yaml": "^4.0.5", "@types/jsonwebtoken": "^8.5.9", + "@types/mime-types": "^2.1.1", "@types/node": "^18.15.11", "@types/qrcode": "^1.5.0", "@types/qrcode-terminal": "^0.12.0", diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 78c90ec9..4e5871e1 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -1,114 +1,106 @@ +import { isBooleanString } from 'class-validator'; import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; -import { isBooleanString } from 'class-validator'; export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { - ORIGIN: string[]; - METHODS: HttpMethods[]; - CREDENTIALS: boolean; + ORIGIN: string[]; + METHODS: HttpMethods[]; + CREDENTIALS: boolean; }; export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; -export type LogLevel = - | 'ERROR' - | 'WARN' - | 'DEBUG' - | 'INFO' - | 'LOG' - | 'VERBOSE' - | 'DARK' - | 'WEBHOOKS'; +export type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS'; export type Log = { - LEVEL: LogLevel[]; - COLOR: boolean; - BAILEYS: LogBaileys; + LEVEL: LogLevel[]; + COLOR: boolean; + BAILEYS: LogBaileys; }; export type SaveData = { - INSTANCE: boolean; - NEW_MESSAGE: boolean; - MESSAGE_UPDATE: boolean; - CONTACTS: boolean; - CHATS: boolean; + INSTANCE: boolean; + NEW_MESSAGE: boolean; + MESSAGE_UPDATE: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type StoreConf = { - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type CleanStoreConf = { - CLEANING_INTERVAL: number; - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + CLEANING_INTERVAL: number; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type DBConnection = { - URI: string; - DB_PREFIX_NAME: string; + URI: string; + DB_PREFIX_NAME: string; }; export type Database = { - CONNECTION: DBConnection; - ENABLED: boolean; - SAVE_DATA: SaveData; + CONNECTION: DBConnection; + ENABLED: boolean; + SAVE_DATA: SaveData; }; export type Redis = { - ENABLED: boolean; - URI: string; - PREFIX_KEY: string; + ENABLED: boolean; + URI: string; + PREFIX_KEY: string; }; export type EventsWebhook = { - APPLICATION_STARTUP: boolean; - QRCODE_UPDATED: boolean; - MESSAGES_SET: boolean; - MESSAGES_UPSERT: boolean; - MESSAGES_UPDATE: boolean; - MESSAGES_DELETE: boolean; - SEND_MESSAGE: boolean; - CONTACTS_SET: boolean; - CONTACTS_UPDATE: boolean; - CONTACTS_UPSERT: boolean; - PRESENCE_UPDATE: boolean; - CHATS_SET: boolean; - CHATS_UPDATE: boolean; - CHATS_DELETE: boolean; - CHATS_UPSERT: boolean; - CONNECTION_UPDATE: boolean; - GROUPS_UPSERT: boolean; - GROUP_UPDATE: boolean; - GROUP_PARTICIPANTS_UPDATE: boolean; - CALL: boolean; - NEW_JWT_TOKEN: boolean; + APPLICATION_STARTUP: boolean; + QRCODE_UPDATED: boolean; + MESSAGES_SET: boolean; + MESSAGES_UPSERT: boolean; + MESSAGES_UPDATE: boolean; + MESSAGES_DELETE: boolean; + SEND_MESSAGE: boolean; + CONTACTS_SET: boolean; + CONTACTS_UPDATE: boolean; + CONTACTS_UPSERT: boolean; + PRESENCE_UPDATE: boolean; + CHATS_SET: boolean; + CHATS_UPDATE: boolean; + CHATS_DELETE: boolean; + CHATS_UPSERT: boolean; + CONNECTION_UPDATE: boolean; + GROUPS_UPSERT: boolean; + GROUP_UPDATE: boolean; + GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; + NEW_JWT_TOKEN: boolean; }; export type ApiKey = { KEY: string }; export type Jwt = { EXPIRIN_IN: number; SECRET: string }; export type Auth = { - API_KEY: ApiKey; - EXPOSE_IN_FETCH_INSTANCES: boolean; - JWT: Jwt; - TYPE: 'jwt' | 'apikey'; + API_KEY: ApiKey; + EXPOSE_IN_FETCH_INSTANCES: boolean; + JWT: Jwt; + TYPE: 'jwt' | 'apikey'; }; export type DelInstance = number | boolean; export type GlobalWebhook = { - URL: string; - ENABLED: boolean; - WEBHOOK_BY_EVENTS: boolean; + URL: string; + ENABLED: boolean; + WEBHOOK_BY_EVENTS: boolean; }; export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; @@ -117,162 +109,158 @@ export type QrCode = { LIMIT: number }; export type Production = boolean; export interface Env { - SERVER: HttpServer; - CORS: Cors; - SSL_CONF: SslConf; - STORE: StoreConf; - CLEAN_STORE: CleanStoreConf; - DATABASE: Database; - REDIS: Redis; - LOG: Log; - DEL_INSTANCE: DelInstance; - WEBHOOK: Webhook; - CONFIG_SESSION_PHONE: ConfigSessionPhone; - QRCODE: QrCode; - AUTHENTICATION: Auth; - PRODUCTION?: Production; + SERVER: HttpServer; + CORS: Cors; + SSL_CONF: SslConf; + STORE: StoreConf; + CLEAN_STORE: CleanStoreConf; + DATABASE: Database; + REDIS: Redis; + LOG: Log; + DEL_INSTANCE: DelInstance; + WEBHOOK: Webhook; + CONFIG_SESSION_PHONE: ConfigSessionPhone; + QRCODE: QrCode; + AUTHENTICATION: Auth; + PRODUCTION?: Production; } export type Key = keyof Env; export class ConfigService { - constructor() { - this.loadEnv(); - } - - private env: Env; - - public get(key: Key) { - return this.env[key] as T; - } - - private loadEnv() { - this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); - this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; - if (process.env?.DOCKER_ENV === 'true') { - this.env.SERVER.TYPE = 'http'; - this.env.SERVER.PORT = 8080; + constructor() { + this.loadEnv(); } - } - private envYaml(): Env { - return load( - readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' }), - ) as Env; - } + private env: Env; - private envProcess(): Env { - return { - SERVER: { - TYPE: process.env.SERVER_TYPE as 'http' | 'https', - PORT: Number.parseInt(process.env.SERVER_PORT), - URL: process.env.SERVER_URL, - }, - CORS: { - ORIGIN: process.env.CORS_ORIGIN.split(','), - METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], - CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', - }, - SSL_CONF: { - PRIVKEY: process.env?.SSL_CONF_PRIVKEY, - FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, - }, - STORE: { - MESSAGES: process.env?.STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.STORE_CONTACTS === 'true', - CHATS: process.env?.STORE_CHATS === 'true', - }, - CLEAN_STORE: { - CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) - ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) - : 7200, - MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', - CHATS: process.env?.CLEAN_STORE_CHATS === 'true', - }, - DATABASE: { - CONNECTION: { - URI: process.env.DATABASE_CONNECTION_URI, - DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, - }, - ENABLED: process.env?.DATABASE_ENABLED === 'true', - SAVE_DATA: { - INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', - NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', - MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', - CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', - CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', - }, - }, - REDIS: { - ENABLED: process.env?.REDIS_ENABLED === 'true', - URI: process.env.REDIS_URI, - PREFIX_KEY: process.env.REDIS_PREFIX_KEY, - }, - LOG: { - LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], - COLOR: process.env?.LOG_COLOR === 'true', - BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', - }, - DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 'true' - : Number.parseInt(process.env.DEL_INSTANCE) || false, - WEBHOOK: { - GLOBAL: { - URL: process.env?.WEBHOOK_GLOBAL_URL, - ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', - WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', - }, - EVENTS: { - APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', - QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', - MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', - MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', - MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', - MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', - SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', - CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', - CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', - CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', - PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', - CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', - CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', - CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', - CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', - CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', - GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', - GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', - GROUP_PARTICIPANTS_UPDATE: - process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', - CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', - NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', - }, - }, - CONFIG_SESSION_PHONE: { - CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', - NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', - }, - QRCODE: { - LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, - }, - AUTHENTICATION: { - TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', - API_KEY: { - KEY: process.env.AUTHENTICATION_API_KEY, - }, - EXPOSE_IN_FETCH_INSTANCES: - process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', - JWT: { - EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) - ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) - : 3600, - SECRET: process.env.AUTHENTICATION_JWT_SECRET, - }, - }, - }; - } + public get(key: Key) { + return this.env[key] as T; + } + + private loadEnv() { + this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); + this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; + if (process.env?.DOCKER_ENV === 'true') { + this.env.SERVER.TYPE = 'http'; + this.env.SERVER.PORT = 8080; + } + } + + private envYaml(): Env { + return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; + } + + private envProcess(): Env { + return { + SERVER: { + TYPE: process.env.SERVER_TYPE as 'http' | 'https', + PORT: Number.parseInt(process.env.SERVER_PORT), + URL: process.env.SERVER_URL, + }, + CORS: { + ORIGIN: process.env.CORS_ORIGIN.split(','), + METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], + CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', + }, + SSL_CONF: { + PRIVKEY: process.env?.SSL_CONF_PRIVKEY, + FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, + }, + STORE: { + MESSAGES: process.env?.STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.STORE_CONTACTS === 'true', + CHATS: process.env?.STORE_CHATS === 'true', + }, + CLEAN_STORE: { + CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) + ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) + : 7200, + MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', + CHATS: process.env?.CLEAN_STORE_CHATS === 'true', + }, + DATABASE: { + CONNECTION: { + URI: process.env.DATABASE_CONNECTION_URI, + DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, + }, + ENABLED: process.env?.DATABASE_ENABLED === 'true', + SAVE_DATA: { + INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', + NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', + MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', + CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', + CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', + }, + }, + REDIS: { + ENABLED: process.env?.REDIS_ENABLED === 'true', + URI: process.env.REDIS_URI, + PREFIX_KEY: process.env.REDIS_PREFIX_KEY, + }, + LOG: { + LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], + COLOR: process.env?.LOG_COLOR === 'true', + BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', + }, + DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) + ? process.env.DEL_INSTANCE === 'true' + : Number.parseInt(process.env.DEL_INSTANCE) || false, + WEBHOOK: { + GLOBAL: { + URL: process.env?.WEBHOOK_GLOBAL_URL, + ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', + WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', + }, + EVENTS: { + APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', + QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', + MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', + MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', + MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', + MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', + SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', + CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', + CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', + CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', + PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', + CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', + CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', + CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', + CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', + CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', + GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', + GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', + GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', + NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', + }, + }, + CONFIG_SESSION_PHONE: { + CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', + }, + QRCODE: { + LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, + }, + AUTHENTICATION: { + TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', + API_KEY: { + KEY: process.env.AUTHENTICATION_API_KEY, + }, + EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', + JWT: { + EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) + ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) + : 3600, + SECRET: process.env.AUTHENTICATION_JWT_SECRET, + }, + }, + }; + } } export const configService = new ConfigService(); diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index d7e2ac1e..8e021116 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -2,923 +2,896 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; import { v4 } from 'uuid'; const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => { - const properties = {}; - propertyNames.forEach( - (property) => - (properties[property] = { - minLength: 1, - description: `The "${property}" cannot be empty`, - }), - ); - return { - if: { - propertyNames: { - enum: [...propertyNames], - }, - }, - then: { properties }, - }; + const properties = {}; + propertyNames.forEach( + (property) => + (properties[property] = { + minLength: 1, + description: `The "${property}" cannot be empty`, + }), + ); + return { + if: { + propertyNames: { + enum: [...propertyNames], + }, + }, + then: { properties }, + }; }; // Instance Schema export const instanceNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - instanceName: { type: 'string' }, - webhook: { type: 'string' }, - webhook_by_events: { type: 'boolean' }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'CALL', - 'NEW_JWT_TOKEN', - ], - }, + $id: v4(), + type: 'object', + properties: { + instanceName: { type: 'string' }, + webhook: { type: 'string' }, + webhook_by_events: { type: 'boolean' }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, + }, + qrcode: { type: 'boolean', enum: [true, false] }, + number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, + token: { type: 'string' }, }, - qrcode: { type: 'boolean', enum: [true, false] }, - number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, - token: { type: 'string' }, - }, - ...isNotEmpty('instanceName'), + ...isNotEmpty('instanceName'), }; export const oldTokenSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - oldToken: { type: 'string' }, - }, - required: ['oldToken'], - ...isNotEmpty('oldToken'), + $id: v4(), + type: 'object', + properties: { + oldToken: { type: 'string' }, + }, + required: ['oldToken'], + ...isNotEmpty('oldToken'), }; const quotedOptionsSchema: JSONSchema7 = { - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id'], - ...isNotEmpty('id'), + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id'], + ...isNotEmpty('id'), + }, + message: { type: 'object' }, }, - message: { type: 'object' }, - }, }; const mentionsOptionsSchema: JSONSchema7 = { - properties: { - everyOne: { type: 'boolean', enum: [true, false] }, - mentioned: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"mentioned" must be an array of numeric strings', - }, + properties: { + everyOne: { type: 'boolean', enum: [true, false] }, + mentioned: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"mentioned" must be an array of numeric strings', + }, + }, }, - }, }; // Send Message Schema const optionsSchema: JSONSchema7 = { - properties: { - delay: { - type: 'integer', - description: 'Enter a value in milliseconds', + properties: { + delay: { + type: 'integer', + description: 'Enter a value in milliseconds', + }, + presence: { + type: 'string', + enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], + }, + quoted: { ...quotedOptionsSchema }, + mentions: { ...mentionsOptionsSchema }, }, - presence: { - type: 'string', - enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], - }, - quoted: { ...quotedOptionsSchema }, - mentions: { ...mentionsOptionsSchema }, - }, }; const numberDefinition: JSONSchema7Definition = { - type: 'string', - description: 'Invalid format', + type: 'string', + description: 'Invalid format', }; export const textMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - textMessage: { - type: 'object', - properties: { - text: { type: 'string' }, - }, - required: ['text'], - ...isNotEmpty('text'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + textMessage: { + type: 'object', + properties: { + text: { type: 'string' }, + }, + required: ['text'], + ...isNotEmpty('text'), + }, }, - }, - required: ['textMessage', 'number'], + required: ['textMessage', 'number'], }; export const pollMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - pollMessage: { - type: 'object', - properties: { - name: { type: 'string' }, - selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, - values: { - type: 'array', - minItems: 2, - maxItems: 10, - uniqueItems: true, - items: { - type: 'string', - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + pollMessage: { + type: 'object', + properties: { + name: { type: 'string' }, + selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, + values: { + type: 'array', + minItems: 2, + maxItems: 10, + uniqueItems: true, + items: { + type: 'string', + }, + }, + }, + required: ['name', 'selectableCount', 'values'], + ...isNotEmpty('name', 'selectableCount', 'values'), }, - }, - required: ['name', 'selectableCount', 'values'], - ...isNotEmpty('name', 'selectableCount', 'values'), }, - }, - required: ['pollMessage', 'number'], + required: ['pollMessage', 'number'], }; export const statusMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - statusMessage: { - type: 'object', - properties: { - type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, - content: { type: 'string' }, - caption: { type: 'string' }, - backgroundColor: { type: 'string' }, - font: { type: 'integer', minimum: 0, maximum: 5 }, - statusJidList: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"statusJidList" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + statusMessage: { + type: 'object', + properties: { + type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, + content: { type: 'string' }, + caption: { type: 'string' }, + backgroundColor: { type: 'string' }, + font: { type: 'integer', minimum: 0, maximum: 5 }, + statusJidList: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"statusJidList" must be an array of numeric strings', + }, + }, + allContacts: { type: 'boolean', enum: [true, false] }, + }, + required: ['type', 'content'], + ...isNotEmpty('type', 'content'), }, - allContacts: { type: 'boolean', enum: [true, false] }, - }, - required: ['type', 'content'], - ...isNotEmpty('type', 'content'), }, - }, - required: ['statusMessage'], + required: ['statusMessage'], }; export const mediaMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - mediaMessage: { - type: 'object', - properties: { - mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, - media: { type: 'string' }, - fileName: { type: 'string' }, - caption: { type: 'string' }, - }, - required: ['mediatype', 'media'], - ...isNotEmpty('fileName', 'caption', 'media'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + mediaMessage: { + type: 'object', + properties: { + mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, + media: { type: 'string' }, + fileName: { type: 'string' }, + caption: { type: 'string' }, + }, + required: ['mediatype', 'media'], + ...isNotEmpty('fileName', 'caption', 'media'), + }, }, - }, - required: ['mediaMessage', 'number'], + required: ['mediaMessage', 'number'], }; export const stickerMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - stickerMessage: { - type: 'object', - properties: { - image: { type: 'string' }, - }, - required: ['image'], - ...isNotEmpty('image'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + stickerMessage: { + type: 'object', + properties: { + image: { type: 'string' }, + }, + required: ['image'], + ...isNotEmpty('image'), + }, }, - }, - required: ['stickerMessage', 'number'], + required: ['stickerMessage', 'number'], }; export const audioMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - audioMessage: { - type: 'object', - properties: { - audio: { type: 'string' }, - }, - required: ['audio'], - ...isNotEmpty('audio'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + audioMessage: { + type: 'object', + properties: { + audio: { type: 'string' }, + }, + required: ['audio'], + ...isNotEmpty('audio'), + }, }, - }, - required: ['audioMessage', 'number'], + required: ['audioMessage', 'number'], }; export const buttonMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - buttonMessage: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttons: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + buttonMessage: { type: 'object', properties: { - buttonText: { type: 'string' }, - buttonId: { type: 'string' }, + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttons: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + buttonText: { type: 'string' }, + buttonId: { type: 'string' }, + }, + required: ['buttonText', 'buttonId'], + ...isNotEmpty('buttonText', 'buttonId'), + }, + }, + mediaMessage: { + type: 'object', + properties: { + media: { type: 'string' }, + fileName: { type: 'string' }, + mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, + }, + required: ['media', 'mediatype'], + ...isNotEmpty('media', 'fileName'), + }, }, - required: ['buttonText', 'buttonId'], - ...isNotEmpty('buttonText', 'buttonId'), - }, + required: ['title', 'buttons'], + ...isNotEmpty('title', 'description'), }, - mediaMessage: { - type: 'object', - properties: { - media: { type: 'string' }, - fileName: { type: 'string' }, - mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, - }, - required: ['media', 'mediatype'], - ...isNotEmpty('media', 'fileName'), - }, - }, - required: ['title', 'buttons'], - ...isNotEmpty('title', 'description'), }, - }, - required: ['number', 'buttonMessage'], + required: ['number', 'buttonMessage'], }; export const locationMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - locationMessage: { - type: 'object', - properties: { - latitude: { type: 'number' }, - longitude: { type: 'number' }, - name: { type: 'string' }, - address: { type: 'string' }, - }, - required: ['latitude', 'longitude'], - ...isNotEmpty('name', 'addresss'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + locationMessage: { + type: 'object', + properties: { + latitude: { type: 'number' }, + longitude: { type: 'number' }, + name: { type: 'string' }, + address: { type: 'string' }, + }, + required: ['latitude', 'longitude'], + ...isNotEmpty('name', 'addresss'), + }, }, - }, - required: ['number', 'locationMessage'], + required: ['number', 'locationMessage'], }; export const listMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - listMessage: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttonText: { type: 'string' }, - sections: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + listMessage: { type: 'object', properties: { - title: { type: 'string' }, - rows: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - rowId: { type: 'string' }, - }, - required: ['title', 'description', 'rowId'], - ...isNotEmpty('title', 'description', 'rowId'), + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttonText: { type: 'string' }, + sections: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + rows: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + rowId: { type: 'string' }, + }, + required: ['title', 'description', 'rowId'], + ...isNotEmpty('title', 'description', 'rowId'), + }, + }, + }, + required: ['title', 'rows'], + ...isNotEmpty('title'), + }, }, - }, }, - required: ['title', 'rows'], - ...isNotEmpty('title'), - }, + required: ['title', 'description', 'buttonText', 'sections'], + ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - }, - required: ['title', 'description', 'buttonText', 'sections'], - ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - }, - required: ['number', 'listMessage'], + required: ['number', 'listMessage'], }; export const contactMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - contactMessage: { - type: 'array', - items: { - type: 'object', - properties: { - fullName: { type: 'string' }, - wuid: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"wuid" must be a numeric string', - }, - phoneNumber: { type: 'string', minLength: 10 }, - organization: { type: 'string' }, - email: { type: 'string' }, - url: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + contactMessage: { + type: 'array', + items: { + type: 'object', + properties: { + fullName: { type: 'string' }, + wuid: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"wuid" must be a numeric string', + }, + phoneNumber: { type: 'string', minLength: 10 }, + organization: { type: 'string' }, + email: { type: 'string' }, + url: { type: 'string' }, + }, + required: ['fullName', 'phoneNumber'], + ...isNotEmpty('fullName'), + }, + minItems: 1, + uniqueItems: true, }, - required: ['fullName', 'phoneNumber'], - ...isNotEmpty('fullName'), - }, - minItems: 1, - uniqueItems: true, }, - }, - required: ['number', 'contactMessage'], + required: ['number', 'contactMessage'], }; export const reactionMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reactionMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'remoteJid', 'fromMe'], - ...isNotEmpty('id', 'remoteJid'), + $id: v4(), + type: 'object', + properties: { + reactionMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'remoteJid', 'fromMe'], + ...isNotEmpty('id', 'remoteJid'), + }, + reaction: { type: 'string' }, + }, + required: ['key', 'reaction'], + ...isNotEmpty('reaction'), }, - reaction: { type: 'string' }, - }, - required: ['key', 'reaction'], - ...isNotEmpty('reaction'), }, - }, - required: ['reactionMessage'], + required: ['reactionMessage'], }; // Chat Schema export const whatsappNumberSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - description: '"numbers" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + description: '"numbers" must be an array of numeric strings', + }, + }, }, - }, }; export const readMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - read_messages: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + read_messages: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, }, - }, - required: ['read_messages'], + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - privacySettings: { - type: 'object', - properties: { - readreceipts: { type: 'string', enum: ['all', 'none'] }, - profile: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], + $id: v4(), + type: 'object', + properties: { + privacySettings: { + type: 'object', + properties: { + readreceipts: { type: 'string', enum: ['all', 'none'] }, + profile: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + status: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + online: { type: 'string', enum: ['all', 'match_last_seen'] }, + last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, + groupadd: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + }, + required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], + ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - status: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - online: { type: 'string', enum: ['all', 'match_last_seen'] }, - last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, - groupadd: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - }, - required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], - ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - }, - required: ['privacySettings'], + required: ['privacySettings'], }; export const archiveChatSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - lastMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), + $id: v4(), + type: 'object', + properties: { + lastMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, + messageTimestamp: { type: 'integer', minLength: 1 }, + }, + required: ['key'], + ...isNotEmpty('messageTimestamp'), }, - messageTimestamp: { type: 'integer', minLength: 1 }, - }, - required: ['key'], - ...isNotEmpty('messageTimestamp'), + archive: { type: 'boolean', enum: [true, false] }, }, - archive: { type: 'boolean', enum: [true, false] }, - }, - required: ['lastMessage', 'archive'], + required: ['lastMessage', 'archive'], }; export const deleteMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - participant: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid', 'participant'), + $id: v4(), + type: 'object', + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + participant: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid', 'participant'), }; export const contactValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - pushName: { type: 'string', minLength: 1 }, - id: { type: 'string', minLength: 1 }, - }, - ...isNotEmpty('_id', 'id', 'pushName'), + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + pushName: { type: 'string', minLength: 1 }, + id: { type: 'string', minLength: 1 }, + }, + ...isNotEmpty('_id', 'id', 'pushName'), + }, }, - }, }; export const profileNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - name: { type: 'string' }, - }, - ...isNotEmpty('name'), + $id: v4(), + type: 'object', + properties: { + name: { type: 'string' }, + }, + ...isNotEmpty('name'), }; export const profileStatusSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - status: { type: 'string' }, - }, - ...isNotEmpty('status'), + $id: v4(), + type: 'object', + properties: { + status: { type: 'string' }, + }, + ...isNotEmpty('status'), }; export const profilePictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { type: 'string' }, - picture: { type: 'string' }, - }, + $id: v4(), + type: 'object', + properties: { + number: { type: 'string' }, + picture: { type: 'string' }, + }, }; export const profileSchema: JSONSchema7 = { - type: 'object', - properties: { - wuid: { type: 'string' }, - name: { type: 'string' }, - picture: { type: 'string' }, - status: { type: 'string' }, - isBusiness: { type: 'boolean' }, - }, + type: 'object', + properties: { + wuid: { type: 'string' }, + name: { type: 'string' }, + picture: { type: 'string' }, + status: { type: 'string' }, + isBusiness: { type: 'boolean' }, + }, }; export const messageValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - key: { - type: 'object', - if: { - propertyNames: { - enum: ['fromMe', 'remoteJid', 'id'], - }, - }, - then: { + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', properties: { - remoteJid: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - id: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - fromMe: { type: 'boolean', enum: [true, false] }, + _id: { type: 'string', minLength: 1 }, + key: { + type: 'object', + if: { + propertyNames: { + enum: ['fromMe', 'remoteJid', 'id'], + }, + }, + then: { + properties: { + remoteJid: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + id: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + }, + }, + message: { type: 'object' }, }, - }, + ...isNotEmpty('_id'), }, - message: { type: 'object' }, - }, - ...isNotEmpty('_id'), + limit: { type: 'integer' }, }, - limit: { type: 'integer' }, - }, }; export const messageUpSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string' }, - remoteJid: { type: 'string' }, - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - participant: { type: 'string' }, - status: { - type: 'string', - enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string' }, + remoteJid: { type: 'string' }, + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + participant: { type: 'string' }, + status: { + type: 'string', + enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], + }, + }, + ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), }, - }, - ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), + limit: { type: 'integer' }, }, - limit: { type: 'integer' }, - }, }; // Group Schema export const createGroupSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - subject: { type: 'string' }, - description: { type: 'string' }, - profilePicture: { type: 'string' }, - promoteParticipants: { type: 'boolean', enum: [true, false] }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + subject: { type: 'string' }, + description: { type: 'string' }, + profilePicture: { type: 'string' }, + promoteParticipants: { type: 'boolean', enum: [true, false] }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, }, - }, - required: ['subject', 'participants'], - ...isNotEmpty('subject', 'description', 'profilePicture'), + required: ['subject', 'participants'], + ...isNotEmpty('subject', 'description', 'profilePicture'), }; export const groupJidSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, - }, - required: ['groupJid'], - ...isNotEmpty('groupJid'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, + }, + required: ['groupJid'], + ...isNotEmpty('groupJid'), }; export const getParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - getParticipants: { type: 'string', enum: ['true', 'false'] }, - }, - required: ['getParticipants'], - ...isNotEmpty('getParticipants'), + $id: v4(), + type: 'object', + properties: { + getParticipants: { type: 'string', enum: ['true', 'false'] }, + }, + required: ['getParticipants'], + ...isNotEmpty('getParticipants'), }; export const groupSendInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"numbers" must be an array of numeric strings', - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"numbers" must be an array of numeric strings', + }, + }, }, - }, - required: ['groupJid', 'description', 'numbers'], - ...isNotEmpty('groupJid', 'description', 'numbers'), + required: ['groupJid', 'description', 'numbers'], + ...isNotEmpty('groupJid', 'description', 'numbers'), }; export const groupInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, - }, - required: ['inviteCode'], - ...isNotEmpty('inviteCode'), + $id: v4(), + type: 'object', + properties: { + inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, + }, + required: ['inviteCode'], + ...isNotEmpty('inviteCode'), }; export const updateParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['add', 'remove', 'promote', 'demote'], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['add', 'remove', 'promote', 'demote'], + }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, - }, - required: ['groupJid', 'action', 'participants'], - ...isNotEmpty('groupJid', 'action'), + required: ['groupJid', 'action', 'participants'], + ...isNotEmpty('groupJid', 'action'), }; export const updateSettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], + }, }, - }, - required: ['groupJid', 'action'], - ...isNotEmpty('groupJid', 'action'), + required: ['groupJid', 'action'], + ...isNotEmpty('groupJid', 'action'), }; export const toggleEphemeralSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - expiration: { - type: 'number', - enum: [0, 86400, 604800, 7776000], + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + expiration: { + type: 'number', + enum: [0, 86400, 604800, 7776000], + }, }, - }, - required: ['groupJid', 'expiration'], - ...isNotEmpty('groupJid', 'expiration'), + required: ['groupJid', 'expiration'], + ...isNotEmpty('groupJid', 'expiration'), }; export const updateGroupPictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - image: { type: 'string' }, - }, - required: ['groupJid', 'image'], - ...isNotEmpty('groupJid', 'image'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + image: { type: 'string' }, + }, + required: ['groupJid', 'image'], + ...isNotEmpty('groupJid', 'image'), }; export const updateGroupSubjectSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - subject: { type: 'string' }, - }, - required: ['groupJid', 'subject'], - ...isNotEmpty('groupJid', 'subject'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + subject: { type: 'string' }, + }, + required: ['groupJid', 'subject'], + ...isNotEmpty('groupJid', 'subject'), }; export const updateGroupDescriptionSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - }, - required: ['groupJid', 'description'], - ...isNotEmpty('groupJid', 'description'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + }, + required: ['groupJid', 'description'], + ...isNotEmpty('groupJid', 'description'), }; // Webhook Schema export const webhookSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - url: { type: 'string' }, - enabled: { type: 'boolean', enum: [true, false] }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'CALL', - 'NEW_JWT_TOKEN', - ], - }, + $id: v4(), + type: 'object', + properties: { + url: { type: 'string' }, + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, + }, }, - }, - required: ['url', 'enabled'], - ...isNotEmpty('url'), + required: ['url', 'enabled'], + ...isNotEmpty('url'), }; export const chatwootSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - enabled: { type: 'boolean', enum: [true, false] }, - account_id: { type: 'string' }, - token: { type: 'string' }, - url: { type: 'string' }, - sign_msg: { type: 'boolean', enum: [true, false] }, - reopen_conversation: { type: 'boolean', enum: [true, false] }, - conversation_pending: { type: 'boolean', enum: [true, false] }, - }, - required: [ - 'enabled', - 'account_id', - 'token', - 'url', - 'sign_msg', - 'reopen_conversation', - 'conversation_pending', - ], - ...isNotEmpty( - 'account_id', - 'token', - 'url', - 'sign_msg', - 'reopen_conversation', - 'conversation_pending', - ), + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + account_id: { type: 'string' }, + token: { type: 'string' }, + url: { type: 'string' }, + sign_msg: { type: 'boolean', enum: [true, false] }, + reopen_conversation: { type: 'boolean', enum: [true, false] }, + conversation_pending: { type: 'boolean', enum: [true, false] }, + }, + required: ['enabled', 'account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'], + ...isNotEmpty('account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'), }; export const settingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reject_call: { type: 'boolean', enum: [true, false] }, - msg_call: { type: 'string' }, - groups_ignore: { type: 'boolean', enum: [true, false] }, - always_online: { type: 'boolean', enum: [true, false] }, - read_messages: { type: 'boolean', enum: [true, false] }, - read_status: { type: 'boolean', enum: [true, false] }, - }, - required: [ - 'reject_call', - 'groups_ignore', - 'always_online', - 'read_messages', - 'read_status', - ], - ...isNotEmpty( - 'reject_call', - 'groups_ignore', - 'always_online', - 'read_messages', - 'read_status', - ), + $id: v4(), + type: 'object', + properties: { + reject_call: { type: 'boolean', enum: [true, false] }, + msg_call: { type: 'string' }, + groups_ignore: { type: 'boolean', enum: [true, false] }, + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, + }, + required: ['reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'], + ...isNotEmpty('reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'), }; diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index ad92e607..67591cb3 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -1,105 +1,99 @@ import { isURL } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; -import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; -import { waMonitor } from '../whatsapp.module'; + import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChatwootService } from '../services/chatwoot.service'; +import { waMonitor } from '../whatsapp.module'; const logger = new Logger('ChatwootController'); export class ChatwootController { - constructor( - private readonly chatwootService: ChatwootService, - private readonly configService: ConfigService, - ) {} + constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} - public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { - logger.verbose( - 'requested createChatwoot from ' + instance.instanceName + ' instance', - ); + public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { + logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); - if (data.enabled) { - if (!isURL(data.url, { require_tld: false })) { - throw new BadRequestException('url is not valid'); - } + if (data.enabled) { + if (!isURL(data.url, { require_tld: false })) { + throw new BadRequestException('url is not valid'); + } - if (!data.account_id) { - throw new BadRequestException('account_id is required'); - } + if (!data.account_id) { + throw new BadRequestException('account_id is required'); + } - if (!data.token) { - throw new BadRequestException('token is required'); - } + if (!data.token) { + throw new BadRequestException('token is required'); + } - if (data.sign_msg !== true && data.sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } + if (data.sign_msg !== true && data.sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + } + + if (!data.enabled) { + logger.verbose('chatwoot disabled'); + data.account_id = ''; + data.token = ''; + data.url = ''; + data.sign_msg = false; + data.reopen_conversation = false; + data.conversation_pending = false; + } + + data.name_inbox = instance.instanceName; + + const result = this.chatwootService.create(instance, data); + + const urlServer = this.configService.get('SERVER').URL; + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; } - if (!data.enabled) { - logger.verbose('chatwoot disabled'); - data.account_id = ''; - data.token = ''; - data.url = ''; - data.sign_msg = false; - data.reopen_conversation = false; - data.conversation_pending = false; + public async findChatwoot(instance: InstanceDto) { + logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); + const result = await this.chatwootService.find(instance); + + const urlServer = this.configService.get('SERVER').URL; + + if (Object.keys(result).length === 0) { + return { + enabled: false, + url: '', + account_id: '', + token: '', + sign_msg: false, + name_inbox: '', + webhook_url: '', + }; + } + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; } - data.name_inbox = instance.instanceName; + public async receiveWebhook(instance: InstanceDto, data: any) { + logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); + const chatwootService = new ChatwootService(waMonitor, this.configService); - const result = this.chatwootService.create(instance, data); - - const urlServer = this.configService.get('SERVER').URL; - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; - } - - public async findChatwoot(instance: InstanceDto) { - logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); - const result = await this.chatwootService.find(instance); - - const urlServer = this.configService.get('SERVER').URL; - - if (Object.keys(result).length === 0) { - return { - enabled: false, - url: '', - account_id: '', - token: '', - sign_msg: false, - name_inbox: '', - webhook_url: '', - }; + return chatwootService.receiveWebhook(instance, data); } - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; + public async newInstance(data: any) { + const chatwootService = new ChatwootService(waMonitor, this.configService); - return response; - } - - public async receiveWebhook(instance: InstanceDto, data: any) { - logger.verbose( - 'requested receiveWebhook from ' + instance.instanceName + ' instance', - ); - const chatwootService = new ChatwootService(waMonitor, this.configService); - - return chatwootService.receiveWebhook(instance, data); - } - - public async newInstance(data: any) { - const chatwootService = new ChatwootService(waMonitor, this.configService); - - return chatwootService.newInstance(data); - } + return chatwootService.newInstance(data); + } } diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index d9c351f7..f0a89ee8 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -1,376 +1,356 @@ import { delay } from '@whiskeysockets/baileys'; +import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; -import { Auth, ConfigService, HttpServer } from '../../config/env.config'; + +import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; -import { WAMonitoringService } from '../services/monitor.service'; -import { WAStartupService } from '../services/whatsapp.service'; -import { WebhookService } from '../services/webhook.service'; import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; -import { wa } from '../types/wa.types'; -import { RedisCache } from '../../db/redis.client'; -import { isURL } from 'class-validator'; +import { WAMonitoringService } from '../services/monitor.service'; import { SettingsService } from '../services/settings.service'; +import { WebhookService } from '../services/webhook.service'; +import { WAStartupService } from '../services/whatsapp.service'; +import { wa } from '../types/wa.types'; export class InstanceController { - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly eventEmitter: EventEmitter2, - private readonly authService: AuthService, - private readonly webhookService: WebhookService, - private readonly chatwootService: ChatwootService, - private readonly settingsService: SettingsService, - private readonly cache: RedisCache, - ) {} + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly eventEmitter: EventEmitter2, + private readonly authService: AuthService, + private readonly webhookService: WebhookService, + private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, + private readonly cache: RedisCache, + ) {} - private readonly logger = new Logger(InstanceController.name); + private readonly logger = new Logger(InstanceController.name); - public async createInstance({ - instanceName, - webhook, - webhook_by_events, - events, - qrcode, - number, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - chatwoot_reopen_conversation, - chatwoot_conversation_pending, - reject_call, - msg_call, - groups_ignore, - always_online, - read_messages, - read_status, - }: InstanceDto) { - try { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException( - 'The instance name must be lowercase and without special characters', - ); - } - - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } - - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); - - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } - - this.logger.verbose('creating settings'); - const settings: wa.LocalSettings = { - reject_call: reject_call || false, - msg_call: msg_call || '', - groups_ignore: groups_ignore || false, - always_online: always_online || false, - read_messages: read_messages || false, - read_status: read_status || false, - }; - - this.logger.verbose('settings: ' + JSON.stringify(settings)); - - this.settingsService.create(instance, settings); - - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - settings, - qrcode: getQrcode, - }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } - - if ( - chatwoot_reopen_conversation !== true && - chatwoot_reopen_conversation !== false - ) { - throw new BadRequestException('reopen_conversation is required'); - } - - if ( - chatwoot_conversation_pending !== true && - chatwoot_conversation_pending !== false - ) { - throw new BadRequestException('conversation_pending is required'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - reopen_conversation: chatwoot_reopen_conversation || false, - conversation_pending: chatwoot_conversation_pending || false, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - number, - ); - } catch (error) { - this.logger.log(error); - } - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, + public async createInstance({ + instanceName, webhook, webhook_by_events, - events: getEvents, - settings, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - reopen_conversation: chatwoot_reopen_conversation || false, - conversation_pending: chatwoot_conversation_pending || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; - } catch (error) { - console.log(error); - return { error: true, message: error.toString() }; - } - } + events, + qrcode, + number, + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + chatwoot_reopen_conversation, + chatwoot_conversation_pending, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, + }: InstanceDto) { + try { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { - try { - this.logger.verbose( - 'requested connectToWhatsapp from ' + instanceName + ' instance', - ); + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException('The instance name must be lowercase and without special characters'); + } - const instance = this.waMonitor.waInstances[instanceName]; - const state = instance?.connectionStatus?.state; + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); - this.logger.verbose('state: ' + state); + this.logger.verbose('creating instance'); + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); - if (state == 'open') { - return await this.connectionState({ instanceName }); - } + this.logger.verbose('instance: ' + instance.instanceName + ' created'); - if (state == 'connecting') { - return instance.qrCode; - } + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); - if (state == 'close') { - this.logger.verbose('connecting'); - await instance.connectToWhatsapp(number); + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); - await delay(5000); - return instance.qrCode; - } + this.logger.verbose('hash: ' + hash + ' generated'); - return { - instance: { - instanceName: instanceName, - status: state, - }, - qrcode: instance?.qrCode, - }; - } catch (error) { - this.logger.error(error); - } - } + let getEvents: string[]; - public async restartInstance({ instanceName }: InstanceDto) { - try { - this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } - this.logger.verbose('logging out instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + this.logger.verbose('creating webhook'); + try { + this.webhookService.create(instance, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); - return { error: false, message: 'Instance restarted' }; - } catch (error) { - this.logger.error(error); - } - } + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } - public async connectionState({ instanceName }: InstanceDto) { - this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); - return { - instance: { - instanceName: instanceName, - state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, - }, - }; - } + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; - public async fetchInstances({ instanceName }: InstanceDto) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); - if (instanceName) { - this.logger.verbose('instanceName: ' + instanceName); - return this.waMonitor.instanceInfo(instanceName); + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + settings, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + + if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) { + throw new BadRequestException('reopen_conversation is required'); + } + + if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) { + throw new BadRequestException('conversation_pending is required'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + }); + + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); + } catch (error) { + this.logger.log(error); + } + + return { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + settings, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, + }; + } catch (error) { + console.log(error); + return { error: true, message: error.toString() }; + } } - return this.waMonitor.instanceInfo(); - } + public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { + try { + this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); - public async logout({ instanceName }: InstanceDto) { - this.logger.verbose('requested logout from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); + const instance = this.waMonitor.waInstances[instanceName]; + const state = instance?.connectionStatus?.state; - if (instance.state === 'close') { - throw new BadRequestException( - 'The "' + instanceName + '" instance is not connected', - ); + this.logger.verbose('state: ' + state); + + if (state == 'open') { + return await this.connectionState({ instanceName }); + } + + if (state == 'connecting') { + return instance.qrCode; + } + + if (state == 'close') { + this.logger.verbose('connecting'); + await instance.connectToWhatsapp(number); + + await delay(5000); + return instance.qrCode; + } + + return { + instance: { + instanceName: instanceName, + status: state, + }, + qrcode: instance?.qrCode, + }; + } catch (error) { + this.logger.error(error); + } } - try { - this.logger.verbose('logging out instance: ' + instanceName); - await this.waMonitor.waInstances[instanceName]?.client?.logout( - 'Log out instance: ' + instanceName, - ); + public async restartInstance({ instanceName }: InstanceDto) { + try { + this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - this.logger.verbose('close connection instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + this.logger.verbose('logging out instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - return { error: false, message: 'Instance logged out' }; - } catch (error) { - throw new InternalServerErrorException(error.toString()); + return { error: false, message: 'Instance restarted' }; + } catch (error) { + this.logger.error(error); + } } - } - public async deleteInstance({ instanceName }: InstanceDto) { - this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); - - if (instance.state === 'open') { - throw new BadRequestException( - 'The "' + instanceName + '" instance needs to be disconnected', - ); + public async connectionState({ instanceName }: InstanceDto) { + this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); + return { + instance: { + instanceName: instanceName, + state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, + }, + }; } - try { - if (instance.state === 'connecting') { - this.logger.verbose('logging out instance: ' + instanceName); - await this.logout({ instanceName }); - delete this.waMonitor.waInstances[instanceName]; - return { error: false, message: 'Instance deleted' }; - } else { - this.logger.verbose('deleting instance: ' + instanceName); + public async fetchInstances({ instanceName }: InstanceDto) { + this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); + if (instanceName) { + this.logger.verbose('instanceName: ' + instanceName); + return this.waMonitor.instanceInfo(instanceName); + } - delete this.waMonitor.waInstances[instanceName]; - this.eventEmitter.emit('remove.instance', instanceName, 'inner'); - return { error: false, message: 'Instance deleted' }; - } - } catch (error) { - throw new BadRequestException(error.toString()); + return this.waMonitor.instanceInfo(); } - } - public async refreshToken(_: InstanceDto, oldToken: OldToken) { - this.logger.verbose('requested refreshToken'); - return await this.authService.refreshToken(oldToken); - } + public async logout({ instanceName }: InstanceDto) { + this.logger.verbose('requested logout from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); + + if (instance.state === 'close') { + throw new BadRequestException('The "' + instanceName + '" instance is not connected'); + } + + try { + this.logger.verbose('logging out instance: ' + instanceName); + await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); + + this.logger.verbose('close connection instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + + return { error: false, message: 'Instance logged out' }; + } catch (error) { + throw new InternalServerErrorException(error.toString()); + } + } + + public async deleteInstance({ instanceName }: InstanceDto) { + this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); + + if (instance.state === 'open') { + throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); + } + try { + if (instance.state === 'connecting') { + this.logger.verbose('logging out instance: ' + instanceName); + + await this.logout({ instanceName }); + delete this.waMonitor.waInstances[instanceName]; + return { error: false, message: 'Instance deleted' }; + } else { + this.logger.verbose('deleting instance: ' + instanceName); + + delete this.waMonitor.waInstances[instanceName]; + this.eventEmitter.emit('remove.instance', instanceName, 'inner'); + return { error: false, message: 'Instance deleted' }; + } + } catch (error) { + throw new BadRequestException(error.toString()); + } + } + + public async refreshToken(_: InstanceDto, oldToken: OldToken) { + this.logger.verbose('requested refreshToken'); + return await this.authService.refreshToken(oldToken); + } } diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index f538abe6..1a82a0b2 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -1,25 +1,24 @@ -import { isURL } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; +// import { isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; +// import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { SettingsService } from '../services/settings.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsController'); export class SettingsController { - constructor(private readonly settingsService: SettingsService) {} + constructor(private readonly settingsService: SettingsService) {} - public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose( - 'requested createSettings from ' + instance.instanceName + ' instance', - ); + public async createSettings(instance: InstanceDto, data: SettingsDto) { + logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.create(instance, data); - } + return this.settingsService.create(instance, data); + } - public async findSettings(instance: InstanceDto) { - logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.find(instance); - } + public async findSettings(instance: InstanceDto) { + logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); + return this.settingsService.find(instance); + } } diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 4681ef76..487a30d4 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,93 +1,84 @@ -import { - WAPrivacyOnlineValue, - WAPrivacyValue, - WAReadReceiptsValue, - proto, -} from '@whiskeysockets/baileys'; +import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; export class OnWhatsAppDto { - constructor( - public readonly jid: string, - public readonly exists: boolean, - public readonly name?: string, - ) {} + constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} } export class getBase64FromMediaMessageDto { - message: proto.WebMessageInfo; - convertToMp4?: boolean; + message: proto.WebMessageInfo; + convertToMp4?: boolean; } export class WhatsAppNumberDto { - numbers: string[]; + numbers: string[]; } export class NumberDto { - number: string; + number: string; } export class NumberBusiness { - wid?: string; - jid?: string; - exists?: boolean; - isBusiness: boolean; - name?: string; - message?: string; - description?: string; - email?: string; - website?: string[]; - address?: string; + wid?: string; + jid?: string; + exists?: boolean; + isBusiness: boolean; + name?: string; + message?: string; + description?: string; + email?: string; + website?: string[]; + address?: string; } export class ProfileNameDto { - name: string; + name: string; } export class ProfileStatusDto { - status: string; + status: string; } export class ProfilePictureDto { - number?: string; - // url or base64 - picture?: string; + number?: string; + // url or base64 + picture?: string; } class Key { - id: string; - fromMe: boolean; - remoteJid: string; + id: string; + fromMe: boolean; + remoteJid: string; } export class ReadMessageDto { - read_messages: Key[]; + read_messages: Key[]; } class LastMessage { - key: Key; - messageTimestamp?: number; + key: Key; + messageTimestamp?: number; } export class ArchiveChatDto { - lastMessage: LastMessage; - archive: boolean; + lastMessage: LastMessage; + archive: boolean; } class PrivacySetting { - readreceipts: WAReadReceiptsValue; - profile: WAPrivacyValue; - status: WAPrivacyValue; - online: WAPrivacyOnlineValue; - last: WAPrivacyValue; - groupadd: WAPrivacyValue; + readreceipts: WAReadReceiptsValue; + profile: WAPrivacyValue; + status: WAPrivacyValue; + online: WAPrivacyOnlineValue; + last: WAPrivacyValue; + groupadd: WAPrivacyValue; } export class PrivacySettingDto { - privacySettings: PrivacySetting; + privacySettings: PrivacySetting; } export class DeleteMessage { - id: string; - fromMe: boolean; - remoteJid: string; - participant?: string; + id: string; + fromMe: boolean; + remoteJid: string; + participant?: string; } diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index b270c869..212e0090 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -1,11 +1,11 @@ export class ChatwootDto { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index 6dfdc45c..62a1b890 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,52 +1,52 @@ export class CreateGroupDto { - subject: string; - participants: string[]; - description?: string; - promoteParticipants?: boolean; + subject: string; + participants: string[]; + description?: string; + promoteParticipants?: boolean; } export class GroupPictureDto { - groupJid: string; - image: string; + groupJid: string; + image: string; } export class GroupSubjectDto { - groupJid: string; - subject: string; + groupJid: string; + subject: string; } export class GroupDescriptionDto { - groupJid: string; - description: string; + groupJid: string; + description: string; } export class GroupJid { - groupJid: string; + groupJid: string; } export class GetParticipant { - getParticipants: string; + getParticipants: string; } export class GroupInvite { - inviteCode: string; + inviteCode: string; } export class GroupSendInvite { - groupJid: string; - description: string; - numbers: string[]; + groupJid: string; + description: string; + numbers: string[]; } export class GroupUpdateParticipantDto extends GroupJid { - action: 'add' | 'remove' | 'promote' | 'demote'; - participants: string[]; + action: 'add' | 'remove' | 'promote' | 'demote'; + participants: string[]; } export class GroupUpdateSettingDto extends GroupJid { - action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; + action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; } export class GroupToggleEphemeralDto extends GroupJid { - expiration: 0 | 86400 | 604800 | 7776000; + expiration: 0 | 86400 | 604800 | 7776000; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index c317060f..827b1243 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,21 +1,21 @@ export class InstanceDto { - instanceName: string; - qrcode?: boolean; - number?: string; - token?: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; - chatwoot_account_id?: string; - chatwoot_token?: string; - chatwoot_url?: string; - chatwoot_sign_msg?: boolean; - chatwoot_reopen_conversation?: boolean; - chatwoot_conversation_pending?: boolean; + instanceName: string; + qrcode?: boolean; + number?: string; + token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + chatwoot_account_id?: string; + chatwoot_token?: string; + chatwoot_url?: string; + chatwoot_sign_msg?: boolean; + chatwoot_reopen_conversation?: boolean; + chatwoot_conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 594ab3a4..9094b888 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -1,8 +1,8 @@ export class SettingsDto { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index bac226e9..3b1a99a2 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -1,33 +1,30 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { - _id?: string; - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; + _id?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } const chatwootSchema = new Schema({ - _id: { type: String, _id: true }, - enabled: { type: Boolean, required: true }, - account_id: { type: String, required: true }, - token: { type: String, required: true }, - url: { type: String, required: true }, - name_inbox: { type: String, required: true }, - sign_msg: { type: Boolean, required: true }, - number: { type: String, required: true }, + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + account_id: { type: String, required: true }, + token: { type: String, required: true }, + url: { type: String, required: true }, + name_inbox: { type: String, required: true }, + sign_msg: { type: Boolean, required: true }, + number: { type: String, required: true }, }); -export const ChatwootModel = dbserver?.model( - ChatwootRaw.name, - chatwootSchema, - 'chatwoot', -); +export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot'); export type IChatwootModel = typeof ChatwootModel; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b6d2488d..935f8f3d 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -1,29 +1,26 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class SettingsRaw { - _id?: string; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; + _id?: string; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ - _id: { type: String, _id: true }, - reject_call: { type: Boolean, required: true }, - msg_call: { type: String, required: true }, - groups_ignore: { type: Boolean, required: true }, - always_online: { type: Boolean, required: true }, - read_messages: { type: Boolean, required: true }, - read_status: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + reject_call: { type: Boolean, required: true }, + msg_call: { type: String, required: true }, + groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); -export const SettingsModel = dbserver?.model( - SettingsRaw.name, - settingsSchema, - 'settings', -); +export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings'); export type ISettingsModel = typeof SettingsModel; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index d506cc46..46d92418 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -1,121 +1,117 @@ -import { MessageRepository } from './message.repository'; -import { ChatRepository } from './chat.repository'; -import { ContactRepository } from './contact.repository'; -import { MessageUpRepository } from './messageUp.repository'; -import { MongoClient } from 'mongodb'; -import { WebhookRepository } from './webhook.repository'; -import { ChatwootRepository } from './chatwoot.repository'; -import { SettingsRepository } from './settings.repository'; - -import { AuthRepository } from './auth.repository'; -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { join } from 'path'; import fs from 'fs'; +import { MongoClient } from 'mongodb'; +import { join } from 'path'; + +import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { AuthRepository } from './auth.repository'; +import { ChatRepository } from './chat.repository'; +import { ChatwootRepository } from './chatwoot.repository'; +import { ContactRepository } from './contact.repository'; +import { MessageRepository } from './message.repository'; +import { MessageUpRepository } from './messageUp.repository'; +import { SettingsRepository } from './settings.repository'; +import { WebhookRepository } from './webhook.repository'; export class RepositoryBroker { - constructor( - public readonly message: MessageRepository, - public readonly chat: ChatRepository, - public readonly contact: ContactRepository, - public readonly messageUpdate: MessageUpRepository, - public readonly webhook: WebhookRepository, - public readonly chatwoot: ChatwootRepository, - public readonly settings: SettingsRepository, - public readonly auth: AuthRepository, - private configService: ConfigService, - dbServer?: MongoClient, - ) { - this.dbClient = dbServer; - this.__init_repo_without_db__(); - } - - private dbClient?: MongoClient; - private readonly logger = new Logger('RepositoryBroker'); - - public get dbServer() { - return this.dbClient; - } - - private __init_repo_without_db__() { - this.logger.verbose('initializing repository without db'); - if (!this.configService.get('DATABASE').ENABLED) { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - try { - const authDir = join( - storePath, - 'auth', - this.configService.get('AUTHENTICATION').TYPE, - ); - const chatsDir = join(storePath, 'chats'); - const contactsDir = join(storePath, 'contacts'); - const messagesDir = join(storePath, 'messages'); - const messageUpDir = join(storePath, 'message-up'); - const webhookDir = join(storePath, 'webhook'); - const chatwootDir = join(storePath, 'chatwoot'); - const settingsDir = join(storePath, 'settings'); - const tempDir = join(storePath, 'temp'); - - if (!fs.existsSync(authDir)) { - this.logger.verbose('creating auth dir: ' + authDir); - fs.mkdirSync(authDir, { recursive: true }); - } - if (!fs.existsSync(chatsDir)) { - this.logger.verbose('creating chats dir: ' + chatsDir); - fs.mkdirSync(chatsDir, { recursive: true }); - } - if (!fs.existsSync(contactsDir)) { - this.logger.verbose('creating contacts dir: ' + contactsDir); - fs.mkdirSync(contactsDir, { recursive: true }); - } - if (!fs.existsSync(messagesDir)) { - this.logger.verbose('creating messages dir: ' + messagesDir); - fs.mkdirSync(messagesDir, { recursive: true }); - } - if (!fs.existsSync(messageUpDir)) { - this.logger.verbose('creating message-up dir: ' + messageUpDir); - fs.mkdirSync(messageUpDir, { recursive: true }); - } - if (!fs.existsSync(webhookDir)) { - this.logger.verbose('creating webhook dir: ' + webhookDir); - fs.mkdirSync(webhookDir, { recursive: true }); - } - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(settingsDir)) { - this.logger.verbose('creating settings dir: ' + settingsDir); - fs.mkdirSync(settingsDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } - } else { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - - const tempDir = join(storePath, 'temp'); - const chatwootDir = join(storePath, 'chatwoot'); - - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - try { - } catch (error) { - this.logger.error(error); - } + constructor( + public readonly message: MessageRepository, + public readonly chat: ChatRepository, + public readonly contact: ContactRepository, + public readonly messageUpdate: MessageUpRepository, + public readonly webhook: WebhookRepository, + public readonly chatwoot: ChatwootRepository, + public readonly settings: SettingsRepository, + public readonly auth: AuthRepository, + private configService: ConfigService, + dbServer?: MongoClient, + ) { + this.dbClient = dbServer; + this.__init_repo_without_db__(); + } + + private dbClient?: MongoClient; + private readonly logger = new Logger('RepositoryBroker'); + + public get dbServer() { + return this.dbClient; + } + + private __init_repo_without_db__() { + this.logger.verbose('initializing repository without db'); + if (!this.configService.get('DATABASE').ENABLED) { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + try { + const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); + const chatsDir = join(storePath, 'chats'); + const contactsDir = join(storePath, 'contacts'); + const messagesDir = join(storePath, 'messages'); + const messageUpDir = join(storePath, 'message-up'); + const webhookDir = join(storePath, 'webhook'); + const chatwootDir = join(storePath, 'chatwoot'); + const settingsDir = join(storePath, 'settings'); + const tempDir = join(storePath, 'temp'); + + if (!fs.existsSync(authDir)) { + this.logger.verbose('creating auth dir: ' + authDir); + fs.mkdirSync(authDir, { recursive: true }); + } + if (!fs.existsSync(chatsDir)) { + this.logger.verbose('creating chats dir: ' + chatsDir); + fs.mkdirSync(chatsDir, { recursive: true }); + } + if (!fs.existsSync(contactsDir)) { + this.logger.verbose('creating contacts dir: ' + contactsDir); + fs.mkdirSync(contactsDir, { recursive: true }); + } + if (!fs.existsSync(messagesDir)) { + this.logger.verbose('creating messages dir: ' + messagesDir); + fs.mkdirSync(messagesDir, { recursive: true }); + } + if (!fs.existsSync(messageUpDir)) { + this.logger.verbose('creating message-up dir: ' + messageUpDir); + fs.mkdirSync(messageUpDir, { recursive: true }); + } + if (!fs.existsSync(webhookDir)) { + this.logger.verbose('creating webhook dir: ' + webhookDir); + fs.mkdirSync(webhookDir, { recursive: true }); + } + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(settingsDir)) { + this.logger.verbose('creating settings dir: ' + settingsDir); + fs.mkdirSync(settingsDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } else { + try { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + const chatwootDir = join(storePath, 'chatwoot'); + + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } } - } } diff --git a/src/whatsapp/routers/chatwoot.router.ts b/src/whatsapp/routers/chatwoot.router.ts index 6527099e..4556f4ec 100644 --- a/src/whatsapp/routers/chatwoot.router.ts +++ b/src/whatsapp/routers/chatwoot.router.ts @@ -5,7 +5,7 @@ import { chatwootSchema, instanceNameSchema } from '../../validate/validate.sche import { RouterBroker } from '../abstract/abstract.router'; import { ChatwootDto } from '../dto/chatwoot.dto'; import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootService } from '../services/chatwoot.service'; +// import { ChatwootService } from '../services/chatwoot.service'; import { chatwootController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts index feb37cd0..be364885 100644 --- a/src/whatsapp/routers/settings.router.ts +++ b/src/whatsapp/routers/settings.router.ts @@ -5,7 +5,7 @@ import { instanceNameSchema, settingsSchema } from '../../validate/validate.sche import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; -import { SettingsService } from '../services/settings.service'; +// import { SettingsService } from '../services/settings.service'; import { settingsController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 2d470c37..a2bd9bff 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1,1671 +1,1584 @@ -import { InstanceDto } from '../dto/instance.dto'; -import path from 'path'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; import ChatwootClient from '@figuro/chatwoot-sdk'; -import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import axios from 'axios'; import FormData from 'form-data'; -import { SendTextDto } from '../dto/sendMessage.dto'; +import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import mimeTypes from 'mime-types'; -import { SendAudioDto } from '../dto/sendMessage.dto'; -import { SendMediaDto } from '../dto/sendMessage.dto'; -import { ROOT_DIR } from '../../config/path.config'; +// import { type } from 'os'; +import path from 'path'; + import { ConfigService, HttpServer } from '../../config/env.config'; -import { type } from 'os'; +import { Logger } from '../../config/logger.config'; +import { ROOT_DIR } from '../../config/path.config'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; +import { WAMonitoringService } from './monitor.service'; export class ChatwootService { - private messageCacheFile: string; - private messageCache: Set; + private messageCacheFile: string; + private messageCache: Set; - private readonly logger = new Logger(ChatwootService.name); + private readonly logger = new Logger(ChatwootService.name); - private provider: any; + private provider: any; - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - ) { - this.messageCache = new Set(); - } - - private loadMessageCache(): Set { - this.logger.verbose('load message cache'); - try { - const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); - const cacheArray = cacheData.split('\n'); - return new Set(cacheArray); - } catch (error) { - return new Set(); - } - } - - private saveMessageCache() { - this.logger.verbose('save message cache'); - const cacheData = Array.from(this.messageCache).join('\n'); - writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); - this.logger.verbose('message cache saved'); - } - - private clearMessageCache() { - this.logger.verbose('clear message cache'); - this.messageCache.clear(); - this.saveMessageCache(); - } - - private async getProvider(instance: InstanceDto) { - this.logger.verbose('get provider to instance: ' + instance.instanceName); - try { - const provider = await this.waMonitor.waInstances[ - instance.instanceName - ].findChatwoot(); - - if (!provider) { - this.logger.warn('provider not found'); - return null; - } - - this.logger.verbose('provider found'); - - return provider; - } catch (error) { - this.logger.error('provider not found'); - return null; - } - } - - private async clientCw(instance: InstanceDto) { - this.logger.verbose('get client to instance: ' + instance.instanceName); - const provider = await this.getProvider(instance); - - if (!provider) { - this.logger.error('provider not found'); - return null; + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { + this.messageCache = new Set(); } - this.logger.verbose('provider found'); - - this.provider = provider; - - this.logger.verbose('create client to instance: ' + instance.instanceName); - const client = new ChatwootClient({ - config: { - basePath: provider.url, - with_credentials: true, - credentials: 'include', - token: provider.token, - }, - }); - - this.logger.verbose('client created'); - - return client; - } - - public create(instance: InstanceDto, data: ChatwootDto) { - this.logger.verbose('create chatwoot: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); - - this.logger.verbose('chatwoot created'); - return data; - } - - public async find(instance: InstanceDto): Promise { - this.logger.verbose('find chatwoot: ' + instance.instanceName); - try { - return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); - } catch (error) { - this.logger.error('chatwoot not found'); - return { enabled: null, url: '' }; - } - } - - public async getContact(instance: InstanceDto, id: number) { - this.logger.verbose('get contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await client.contact.getContactable({ - accountId: this.provider.account_id, - id, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact found'); - return contact; - } - - public async initInstanceChatwoot( - instance: InstanceDto, - inboxName: string, - webhookUrl: string, - qrcode: boolean, - number: string, - ) { - this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inbox in chatwoot'); - const findInbox: any = await client.inboxes.list({ - accountId: this.provider.account_id, - }); - - this.logger.verbose('check duplicate inbox'); - const checkDuplicate = findInbox.payload - .map((inbox) => inbox.name) - .includes(inboxName); - - let inboxId: number; - - if (!checkDuplicate) { - this.logger.verbose('create inbox in chatwoot'); - const data = { - type: 'api', - webhook_url: webhookUrl, - }; - - const inbox = await client.inboxes.create({ - accountId: this.provider.account_id, - data: { - name: inboxName, - channel: data as any, - }, - }); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } else { - this.logger.verbose('find inbox in chatwoot'); - const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } - - this.logger.verbose('find contact in chatwoot and create if not exists'); - const contact = - (await this.findContact(instance, '123456')) || - ((await this.createContact( - instance, - '123456', - inboxId, - false, - 'EvolutionAPI', - )) as any); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact.id || contact.payload.contact.id; - - if (qrcode) { - this.logger.verbose('create conversation in chatwoot'); - const data = { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }; - - if (this.provider.conversation_pending) { - data['status'] = 'pending'; - } - - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('create message for init instance in chatwoot'); - - let contentMsg = '/init'; - - if (number) { - contentMsg = `/init:${number}`; - } - - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: contentMsg, - message_type: 'outgoing', - }, - }); - - if (!message) { - this.logger.warn('conversation not found'); - return null; - } - } - - this.logger.verbose('instance chatwoot initialized'); - return true; - } - - public async createContact( - instance: InstanceDto, - phoneNumber: string, - inboxId: number, - isGroup: boolean, - name?: string, - avatar_url?: string, - ) { - this.logger.verbose('create contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let data: any = {}; - if (!isGroup) { - this.logger.verbose('create contact in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - phone_number: `+${phoneNumber}`, - avatar_url: avatar_url, - }; - } else { - this.logger.verbose('create contact group in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - identifier: phoneNumber, - avatar_url: avatar_url, - }; - } - - this.logger.verbose('create contact in chatwoot'); - const contact = await client.contacts.create({ - accountId: this.provider.account_id, - data, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact created'); - return contact; - } - - public async updateContact(instance: InstanceDto, id: number, data: any) { - this.logger.verbose('update contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('update contact in chatwoot'); - const contact = await client.contacts.update({ - accountId: this.provider.account_id, - id, - data, - }); - - this.logger.verbose('contact updated'); - return contact; - } - - public async findContact(instance: InstanceDto, phoneNumber: string) { - this.logger.verbose('find contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let query: any; - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('format phone number'); - query = `+${phoneNumber}`; - } else { - this.logger.verbose('format group id'); - query = phoneNumber; - } - - this.logger.verbose('find contact in chatwoot'); - const contact: any = await client.contacts.search({ - accountId: this.provider.account_id, - q: query, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('return contact'); - return contact.payload.find((contact) => contact.phone_number === query); - } else { - this.logger.verbose('return group'); - return contact.payload.find((contact) => contact.identifier === query); - } - } - - public async createConversation(instance: InstanceDto, body: any) { - this.logger.verbose('create conversation to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const isGroup = body.key.remoteJid.includes('@g.us'); - - this.logger.verbose('is group: ' + isGroup); - - const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - - this.logger.verbose('chat id: ' + chatId); - - let nameContact: string; - - nameContact = !body.key.fromMe ? body.pushName : chatId; - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - if (isGroup) { - this.logger.verbose('get group name'); - const group = await this.waMonitor.waInstances[ - instance.instanceName - ].client.groupMetadata(chatId); - - nameContact = `${group.subject} (GROUP)`; - - this.logger.verbose('find or create participant in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(body.key.participant.split('@')[0]); - - const findParticipant = await this.findContact( - instance, - body.key.participant.split('@')[0], - ); - - if (findParticipant) { - if (!findParticipant.name || findParticipant.name === chatId) { - await this.updateContact(instance, findParticipant.id, { - name: body.pushName, - avatar_url: picture_url.profilePictureUrl || null, - }); - } - } else { - await this.createContact( - instance, - body.key.participant.split('@')[0], - filterInbox.id, - false, - body.pushName, - picture_url.profilePictureUrl || null, - ); + private loadMessageCache(): Set { + this.logger.verbose('load message cache'); + try { + const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); + const cacheArray = cacheData.split('\n'); + return new Set(cacheArray); + } catch (error) { + return new Set(); } - } - - this.logger.verbose('find or create contact in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(chatId); - - const findContact = await this.findContact(instance, chatId); - - let contact: any; - if (body.key.fromMe) { - if (findContact) { - contact = findContact; - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } else { - if (findContact) { - if (!findContact.name || findContact.name === chatId) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); - } else { - contact = findContact; - } - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = - contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; - - if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { - this.logger.verbose('update contact name in chatwoot'); - await this.updateContact(instance, contactId, { - name: nameContact, - }); - } - - this.logger.verbose('get contact conversations in chatwoot'); - const contactConversations = (await client.contacts.listConversations({ - accountId: this.provider.account_id, - id: contactId, - })) as any; - - if (contactConversations) { - let conversation: any; - if (this.provider.reopen_conversation) { - conversation = contactConversations.payload.find( - (conversation) => conversation.inbox_id == filterInbox.id, - ); - } else { - conversation = contactConversations.payload.find( - (conversation) => - conversation.status !== 'resolved' && - conversation.inbox_id == filterInbox.id, - ); - } - this.logger.verbose('return conversation if exists'); - - if (conversation) { - this.logger.verbose('conversation found'); - return conversation.id; - } - } - - this.logger.verbose('create conversation in chatwoot'); - const data = { - contact_id: contactId.toString(), - inbox_id: filterInbox.id.toString(), - }; - - if (this.provider.conversation_pending) { - data['status'] = 'pending'; - } - - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('conversation created'); - return conversation.id; - } catch (error) { - this.logger.error(error); - } - } - - public async getInbox(instance: InstanceDto) { - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; } - this.logger.verbose('find inboxes in chatwoot'); - const inbox = (await client.inboxes.list({ - accountId: this.provider.account_id, - })) as any; - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; + private saveMessageCache() { + this.logger.verbose('save message cache'); + const cacheData = Array.from(this.messageCache).join('\n'); + writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); + this.logger.verbose('message cache saved'); } - this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find( - (inbox) => inbox.name === instance.instanceName, - ); - - if (!findByName) { - this.logger.warn('inbox not found'); - return null; + private clearMessageCache() { + this.logger.verbose('clear message cache'); + this.messageCache.clear(); + this.saveMessageCache(); } - this.logger.verbose('return inbox'); - return findByName; - } - - public async createMessage( - instance: InstanceDto, - conversationId: number, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - privateMessage?: boolean, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create message to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversationId, - data: { - content: content, - message_type: messageType, - attachments: attachments, - private: privateMessage || false, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('message created'); - - return message; - } - - public async createBotMessage( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create bot message to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); - - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', - ); - - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: content, - message_type: messageType, - attachments: attachments, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('bot message created'); - - return message; - } - - private async sendData( - conversationId: number, - file: string, - messageType: 'incoming' | 'outgoing' | undefined, - content?: string, - ) { - this.logger.verbose('send data to chatwoot'); - - const data = new FormData(); - - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } - - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); - - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, - }; - - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - unlinkSync(file); - } - } - - public async createBotQr( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - file?: string, - ) { - this.logger.verbose('create bot qr to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); - - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', - ); - - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } - - this.logger.verbose('send data to chatwoot'); - const data = new FormData(); - - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } - - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); - - if (file) { - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - } - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, - }; - - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - } - } - - public async sendAttachment( - waInstance: any, - number: string, - media: any, - caption?: string, - ) { - this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); - - try { - this.logger.verbose('get media type'); - const parts = media.split('/'); - - const fileName = decodeURIComponent(parts[parts.length - 1]); - this.logger.verbose('file name: ' + fileName); - - const mimeType = mimeTypes.lookup(fileName).toString(); - this.logger.verbose('mime type: ' + mimeType); - - let type = 'document'; - - switch (mimeType.split('/')[0]) { - case 'image': - type = 'image'; - break; - case 'video': - type = 'video'; - break; - case 'audio': - type = 'audio'; - break; - default: - type = 'document'; - break; - } - - this.logger.verbose('type: ' + type); - - if (type === 'audio') { - this.logger.verbose('send audio to instance: ' + waInstance.instanceName); - const data: SendAudioDto = { - number: number, - audioMessage: { - audio: media, - }, - options: { - delay: 1200, - presence: 'recording', - }, - }; - - await waInstance?.audioWhatsapp(data); - - this.logger.verbose('audio sent'); - return; - } - - this.logger.verbose('send media to instance: ' + waInstance.instanceName); - const data: SendMediaDto = { - number: number, - mediaMessage: { - mediatype: type as any, - fileName: fileName, - media: media, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - if (caption) { - this.logger.verbose('caption found'); - data.mediaMessage.caption = caption; - } - - await waInstance?.mediaMessage(data); - - this.logger.verbose('media sent'); - return; - } catch (error) { - this.logger.error(error); - } - } - - public async receiveWebhook(instance: InstanceDto, body: any) { - try { - this.logger.verbose( - 'receive webhook to chatwoot instance: ' + instance.instanceName, - ); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('check if is bot'); - if (!body?.conversation || body.private) return { message: 'bot' }; - - this.logger.verbose('check if is group'); - const chatId = - body.conversation.meta.sender?.phone_number?.replace('+', '') || - body.conversation.meta.sender?.identifier; - const messageReceived = body.content; - const senderName = body?.sender?.name; - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (chatId === '123456' && body.message_type === 'outgoing') { - this.logger.verbose('check if is command'); - - const command = messageReceived.replace('/', ''); - - if (command.includes('init') || command.includes('iniciar')) { - this.logger.verbose('command init found'); - const state = waInstance?.connectionStatus?.state; - - if (state !== 'open') { - this.logger.verbose('connect to whatsapp'); - const number = command.split(':')[1]; - await waInstance.connectToWhatsapp(number); - } else { - this.logger.verbose('whatsapp already connected'); - await this.createBotMessage( - instance, - `🚨 ${body.inbox.name} instance is connected.`, - 'incoming', - ); - } - } - - if (command === 'status') { - this.logger.verbose('command status found'); - - const state = waInstance?.connectionStatus?.state; - - if (!state) { - this.logger.verbose('state not found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance not found.`, - 'incoming', - ); - } - - if (state) { - this.logger.verbose('state: ' + state + ' found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance status: *${state}*`, - 'incoming', - ); - } - } - - if (command === 'disconnect' || command === 'desconectar') { - this.logger.verbose('command disconnect found'); - - const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgLogout, 'incoming'); - - this.logger.verbose('disconnect to whatsapp'); - await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); - await waInstance?.client?.ws?.close(); - } - - if (command.includes('new_instance')) { - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const data = { - instanceName: command.split(':')[1], - qrcode: true, - chatwoot_account_id: this.provider.account_id, - chatwoot_token: this.provider.token, - chatwoot_url: this.provider.url, - chatwoot_sign_msg: this.provider.sign_msg, - }; - - if (command.split(':')[2]) { - data['number'] = command.split(':')[2]; - } - - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: data, - }; - - await axios.request(config); - } - } - - if ( - body.message_type === 'outgoing' && - body?.conversation?.messages?.length && - chatId !== '123456' - ) { - this.logger.verbose('check if is group'); - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - this.logger.verbose('cache file path: ' + this.messageCacheFile); - - this.messageCache = this.loadMessageCache(); - this.logger.verbose('cache file loaded'); - this.logger.verbose(this.messageCache); - - this.logger.verbose('check if message is cached'); - if (this.messageCache.has(body.id.toString())) { - this.logger.verbose('message is cached'); - return { message: 'bot' }; - } - - this.logger.verbose('clear cache'); - this.clearMessageCache(); - - this.logger.verbose('Format message to send'); - let formatText: string; - if (senderName === null || senderName === undefined) { - formatText = messageReceived; - } else { - formatText = this.provider.sign_msg - ? `*${senderName}:*\n\n${messageReceived}` - : messageReceived; - } - - for (const message of body.conversation.messages) { - this.logger.verbose('check if message is media'); - if (message.attachments && message.attachments.length > 0) { - this.logger.verbose('message is media'); - for (const attachment of message.attachments) { - this.logger.verbose('send media to whatsapp'); - if (!messageReceived) { - this.logger.verbose('message do not have text'); - formatText = null; - } - - await this.sendAttachment( - waInstance, - chatId, - attachment.data_url, - formatText, - ); + private async getProvider(instance: InstanceDto) { + this.logger.verbose('get provider to instance: ' + instance.instanceName); + try { + const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + + if (!provider) { + this.logger.warn('provider not found'); + return null; } - } else { - this.logger.verbose('message is text'); - this.logger.verbose('send text to whatsapp'); - const data: SendTextDto = { - number: chatId, - textMessage: { - text: formatText, - }, - options: { - delay: 1200, - presence: 'composing', - }, + this.logger.verbose('provider found'); + + return provider; + } catch (error) { + this.logger.error('provider not found'); + return null; + } + } + + private async clientCw(instance: InstanceDto) { + this.logger.verbose('get client to instance: ' + instance.instanceName); + const provider = await this.getProvider(instance); + + if (!provider) { + this.logger.error('provider not found'); + return null; + } + + this.logger.verbose('provider found'); + + this.provider = provider; + + this.logger.verbose('create client to instance: ' + instance.instanceName); + const client = new ChatwootClient({ + config: { + basePath: provider.url, + with_credentials: true, + credentials: 'include', + token: provider.token, + }, + }); + + this.logger.verbose('client created'); + + return client; + } + + public create(instance: InstanceDto, data: ChatwootDto) { + this.logger.verbose('create chatwoot: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + + this.logger.verbose('chatwoot created'); + return data; + } + + public async find(instance: InstanceDto): Promise { + this.logger.verbose('find chatwoot: ' + instance.instanceName); + try { + return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + } catch (error) { + this.logger.error('chatwoot not found'); + return { enabled: null, url: '' }; + } + } + + public async getContact(instance: InstanceDto, id: number) { + this.logger.verbose('get contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + if (!id) { + this.logger.warn('id is required'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await client.contact.getContactable({ + accountId: this.provider.account_id, + id, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('contact found'); + return contact; + } + + public async initInstanceChatwoot( + instance: InstanceDto, + inboxName: string, + webhookUrl: string, + qrcode: boolean, + number: string, + ) { + this.logger.verbose('init instance chatwoot: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find inbox in chatwoot'); + const findInbox: any = await client.inboxes.list({ + accountId: this.provider.account_id, + }); + + this.logger.verbose('check duplicate inbox'); + const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); + + let inboxId: number; + + if (!checkDuplicate) { + this.logger.verbose('create inbox in chatwoot'); + const data = { + type: 'api', + webhook_url: webhookUrl, }; - await waInstance?.textMessage(data); - } + const inbox = await client.inboxes.create({ + accountId: this.provider.account_id, + data: { + name: inboxName, + channel: data as any, + }, + }); + + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } + + inboxId = inbox.id; + } else { + this.logger.verbose('find inbox in chatwoot'); + const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); + + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } + + inboxId = inbox.id; } - } - if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is template'); + this.logger.verbose('find contact in chatwoot and create if not exists'); + const contact = + (await this.findContact(instance, '123456')) || + ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); - const data: SendTextDto = { - number: chatId, - textMessage: { - text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), - }, - options: { - delay: 1200, - presence: 'composing', - }, + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = contact.id || contact.payload.contact.id; + + if (qrcode) { + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('create message for init instance in chatwoot'); + + let contentMsg = '/init'; + + if (number) { + contentMsg = `/init:${number}`; + } + + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: contentMsg, + message_type: 'outgoing', + }, + }); + + if (!message) { + this.logger.warn('conversation not found'); + return null; + } + } + + this.logger.verbose('instance chatwoot initialized'); + return true; + } + + public async createContact( + instance: InstanceDto, + phoneNumber: string, + inboxId: number, + isGroup: boolean, + name?: string, + avatar_url?: string, + ) { + this.logger.verbose('create contact to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + let data: any = {}; + if (!isGroup) { + this.logger.verbose('create contact in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + phone_number: `+${phoneNumber}`, + avatar_url: avatar_url, + }; + } else { + this.logger.verbose('create contact group in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + identifier: phoneNumber, + avatar_url: avatar_url, + }; + } + + this.logger.verbose('create contact in chatwoot'); + const contact = await client.contacts.create({ + accountId: this.provider.account_id, + data, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('contact created'); + return contact; + } + + public async updateContact(instance: InstanceDto, id: number, data: any) { + this.logger.verbose('update contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + if (!id) { + this.logger.warn('id is required'); + return null; + } + + this.logger.verbose('update contact in chatwoot'); + const contact = await client.contacts.update({ + accountId: this.provider.account_id, + id, + data, + }); + + this.logger.verbose('contact updated'); + return contact; + } + + public async findContact(instance: InstanceDto, phoneNumber: string) { + this.logger.verbose('find contact to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + let query: any; + + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('format phone number'); + query = `+${phoneNumber}`; + } else { + this.logger.verbose('format group id'); + query = phoneNumber; + } + + this.logger.verbose('find contact in chatwoot'); + const contact: any = await client.contacts.search({ + accountId: this.provider.account_id, + q: query, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('return contact'); + return contact.payload.find((contact) => contact.phone_number === query); + } else { + this.logger.verbose('return group'); + return contact.payload.find((contact) => contact.identifier === query); + } + } + + public async createConversation(instance: InstanceDto, body: any) { + this.logger.verbose('create conversation to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + const isGroup = body.key.remoteJid.includes('@g.us'); + + this.logger.verbose('is group: ' + isGroup); + + const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; + + this.logger.verbose('chat id: ' + chatId); + + let nameContact: string; + + nameContact = !body.key.fromMe ? body.pushName : chatId; + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + if (isGroup) { + this.logger.verbose('get group name'); + const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); + + nameContact = `${group.subject} (GROUP)`; + + this.logger.verbose('find or create participant in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( + body.key.participant.split('@')[0], + ); + + const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); + + if (findParticipant) { + if (!findParticipant.name || findParticipant.name === chatId) { + await this.updateContact(instance, findParticipant.id, { + name: body.pushName, + avatar_url: picture_url.profilePictureUrl || null, + }); + } + } else { + await this.createContact( + instance, + body.key.participant.split('@')[0], + filterInbox.id, + false, + body.pushName, + picture_url.profilePictureUrl || null, + ); + } + } + + this.logger.verbose('find or create contact in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); + + const findContact = await this.findContact(instance, chatId); + + let contact: any; + if (body.key.fromMe) { + if (findContact) { + contact = findContact; + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } else { + if (findContact) { + if (!findContact.name || findContact.name === chatId) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = findContact; + } + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; + + if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { + this.logger.verbose('update contact name in chatwoot'); + await this.updateContact(instance, contactId, { + name: nameContact, + }); + } + + this.logger.verbose('get contact conversations in chatwoot'); + const contactConversations = (await client.contacts.listConversations({ + accountId: this.provider.account_id, + id: contactId, + })) as any; + + if (contactConversations) { + let conversation: any; + if (this.provider.reopen_conversation) { + conversation = contactConversations.payload.find( + (conversation) => conversation.inbox_id == filterInbox.id, + ); + } else { + conversation = contactConversations.payload.find( + (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, + ); + } + this.logger.verbose('return conversation if exists'); + + if (conversation) { + this.logger.verbose('conversation found'); + return conversation.id; + } + } + + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: filterInbox.id.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('conversation created'); + return conversation.id; + } catch (error) { + this.logger.error(error); + } + } + + public async getInbox(instance: InstanceDto) { + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find inboxes in chatwoot'); + const inbox = (await client.inboxes.list({ + accountId: this.provider.account_id, + })) as any; + + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find inbox by name'); + const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); + + if (!findByName) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('return inbox'); + return findByName; + } + + public async createMessage( + instance: InstanceDto, + conversationId: number, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + privateMessage?: boolean, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversationId, + data: { + content: content, + message_type: messageType, + attachments: attachments, + private: privateMessage || false, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('message created'); + + return message; + } + + public async createBotMessage( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create bot message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: content, + message_type: messageType, + attachments: attachments, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('bot message created'); + + return message; + } + + private async sendData( + conversationId: number, + file: string, + messageType: 'incoming' | 'outgoing' | undefined, + content?: string, + ) { + this.logger.verbose('send data to chatwoot'); + + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, }; - this.logger.verbose('send text to whatsapp'); + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); - await waInstance?.textMessage(data); - } + this.logger.verbose('remove temp file'); + unlinkSync(file); - return { message: 'bot' }; - } catch (error) { - this.logger.error(error); - - return { message: 'bot' }; + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + unlinkSync(file); + } } - } - private isMediaMessage(message: any) { - this.logger.verbose('check if is media message'); - const media = [ - 'imageMessage', - 'documentMessage', - 'documentWithCaptionMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', - ]; + public async createBotQr( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + file?: string, + ) { + this.logger.verbose('create bot qr to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); - const messageKeys = Object.keys(message); + if (!client) { + this.logger.warn('client not found'); + return null; + } - const result = messageKeys.some((key) => media.includes(key)); + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); - this.logger.verbose('is media message: ' + result); - return result; - } + if (!contact) { + this.logger.warn('contact not found'); + return null; + } - private getTypeMessage(msg: any) { - this.logger.verbose('get type message'); + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); - const types = { - conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, - extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: undefined, - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: - msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage, - liveLocationMessage: msg.liveLocationMessage, - }; + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } - this.logger.verbose('type message: ' + types); + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); - return types; - } + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } - private getMessageContent(types: any) { - this.logger.verbose('get message content'); - const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); - const result = typeKey ? types[typeKey] : undefined; + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } - if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { - const latitude = result.degreesLatitude; - const longitude = result.degreesLongitude; + this.logger.verbose('send data to chatwoot'); + const data = new FormData(); - const formattedLocation = `**Location:** + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + if (file) { + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + } + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + } + } + + public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { + this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); + + try { + this.logger.verbose('get media type'); + const parts = media.split('/'); + + const fileName = decodeURIComponent(parts[parts.length - 1]); + this.logger.verbose('file name: ' + fileName); + + const mimeType = mimeTypes.lookup(fileName).toString(); + this.logger.verbose('mime type: ' + mimeType); + + let type = 'document'; + + switch (mimeType.split('/')[0]) { + case 'image': + type = 'image'; + break; + case 'video': + type = 'video'; + break; + case 'audio': + type = 'audio'; + break; + default: + type = 'document'; + break; + } + + this.logger.verbose('type: ' + type); + + if (type === 'audio') { + this.logger.verbose('send audio to instance: ' + waInstance.instanceName); + const data: SendAudioDto = { + number: number, + audioMessage: { + audio: media, + }, + options: { + delay: 1200, + presence: 'recording', + }, + }; + + await waInstance?.audioWhatsapp(data); + + this.logger.verbose('audio sent'); + return; + } + + this.logger.verbose('send media to instance: ' + waInstance.instanceName); + const data: SendMediaDto = { + number: number, + mediaMessage: { + mediatype: type as any, + fileName: fileName, + media: media, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + if (caption) { + this.logger.verbose('caption found'); + data.mediaMessage.caption = caption; + } + + await waInstance?.mediaMessage(data); + + this.logger.verbose('media sent'); + return; + } catch (error) { + this.logger.error(error); + } + } + + public async receiveWebhook(instance: InstanceDto, body: any) { + try { + this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('check if is bot'); + if (!body?.conversation || body.private) return { message: 'bot' }; + + this.logger.verbose('check if is group'); + const chatId = + body.conversation.meta.sender?.phone_number?.replace('+', '') || + body.conversation.meta.sender?.identifier; + const messageReceived = body.content; + const senderName = body?.sender?.name; + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (chatId === '123456' && body.message_type === 'outgoing') { + this.logger.verbose('check if is command'); + + const command = messageReceived.replace('/', ''); + + if (command.includes('init') || command.includes('iniciar')) { + this.logger.verbose('command init found'); + const state = waInstance?.connectionStatus?.state; + + if (state !== 'open') { + this.logger.verbose('connect to whatsapp'); + const number = command.split(':')[1]; + await waInstance.connectToWhatsapp(number); + } else { + this.logger.verbose('whatsapp already connected'); + await this.createBotMessage( + instance, + `🚨 ${body.inbox.name} instance is connected.`, + 'incoming', + ); + } + } + + if (command === 'status') { + this.logger.verbose('command status found'); + + const state = waInstance?.connectionStatus?.state; + + if (!state) { + this.logger.verbose('state not found'); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); + } + + if (state) { + this.logger.verbose('state: ' + state + ' found'); + await this.createBotMessage( + instance, + `⚠️ ${body.inbox.name} instance status: *${state}*`, + 'incoming', + ); + } + } + + if (command === 'disconnect' || command === 'desconectar') { + this.logger.verbose('command disconnect found'); + + const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgLogout, 'incoming'); + + this.logger.verbose('disconnect to whatsapp'); + await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); + await waInstance?.client?.ws?.close(); + } + + if (command.includes('new_instance')) { + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const data = { + instanceName: command.split(':')[1], + qrcode: true, + chatwoot_account_id: this.provider.account_id, + chatwoot_token: this.provider.token, + chatwoot_url: this.provider.url, + chatwoot_sign_msg: this.provider.sign_msg, + }; + + if (command.split(':')[2]) { + data['number'] = command.split(':')[2]; + } + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: data, + }; + + await axios.request(config); + } + } + + if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { + this.logger.verbose('check if is group'); + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + this.logger.verbose('cache file path: ' + this.messageCacheFile); + + this.messageCache = this.loadMessageCache(); + this.logger.verbose('cache file loaded'); + this.logger.verbose(this.messageCache); + + this.logger.verbose('check if message is cached'); + if (this.messageCache.has(body.id.toString())) { + this.logger.verbose('message is cached'); + return { message: 'bot' }; + } + + this.logger.verbose('clear cache'); + this.clearMessageCache(); + + this.logger.verbose('Format message to send'); + let formatText: string; + if (senderName === null || senderName === undefined) { + formatText = messageReceived; + } else { + formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; + } + + for (const message of body.conversation.messages) { + this.logger.verbose('check if message is media'); + if (message.attachments && message.attachments.length > 0) { + this.logger.verbose('message is media'); + for (const attachment of message.attachments) { + this.logger.verbose('send media to whatsapp'); + if (!messageReceived) { + this.logger.verbose('message do not have text'); + formatText = null; + } + + await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); + } + } else { + this.logger.verbose('message is text'); + + this.logger.verbose('send text to whatsapp'); + const data: SendTextDto = { + number: chatId, + textMessage: { + text: formatText, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + await waInstance?.textMessage(data); + } + } + } + + if (body.message_type === 'template' && body.event === 'message_created') { + this.logger.verbose('check if is template'); + + const data: SendTextDto = { + number: chatId, + textMessage: { + text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + this.logger.verbose('send text to whatsapp'); + + await waInstance?.textMessage(data); + } + + return { message: 'bot' }; + } catch (error) { + this.logger.error(error); + + return { message: 'bot' }; + } + } + + private isMediaMessage(message: any) { + this.logger.verbose('check if is media message'); + const media = [ + 'imageMessage', + 'documentMessage', + 'documentWithCaptionMessage', + 'audioMessage', + 'videoMessage', + 'stickerMessage', + ]; + + const messageKeys = Object.keys(message); + + const result = messageKeys.some((key) => media.includes(key)); + + this.logger.verbose('is media message: ' + result); + return result; + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + imageMessage: msg.imageMessage?.caption, + videoMessage: msg.videoMessage?.caption, + extendedTextMessage: msg.extendedTextMessage?.text, + messageContextInfo: msg.messageContextInfo?.stanzaId, + stickerMessage: undefined, + documentMessage: msg.documentMessage?.caption, + documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { + const latitude = result.degreesLatitude; + const longitude = result.degreesLongitude; + + const formattedLocation = `**Location:** **latitude:** ${latitude} **longitude:** ${longitude} https://www.google.com/maps/search/?api=1&query=${latitude},${longitude} `; - this.logger.verbose('message content: ' + formattedLocation); + this.logger.verbose('message content: ' + formattedLocation); - return formattedLocation; - } - - if (typeKey === 'contactMessage') { - const vCardData = result.split('\n'); - const contactInfo = {}; - - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; + return formattedLocation; } - }); - let formattedContact = `**Contact:** + if (typeKey === 'contactMessage') { + const vCardData = result.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + let formattedContact = `**Contact:** **name:** ${contactInfo['FN']}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); + + this.logger.verbose('message content: ' + formattedContact); + return formattedContact; } - }); - this.logger.verbose('message content: ' + formattedContact); - return formattedContact; - } + if (typeKey === 'contactsArrayMessage') { + const formattedContacts = result.contacts.map((contact) => { + const vCardData = contact.vcard.split('\n'); + const contactInfo = {}; - if (typeKey === 'contactsArrayMessage') { - const formattedContacts = result.contacts.map((contact) => { - const vCardData = contact.vcard.split('\n'); - const contactInfo = {}; + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); - - let formattedContact = `**Contact:** + let formattedContact = `**Contact:** **name:** ${contact.displayName}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); - return formattedContact; - }); + return formattedContact; + }); - const formattedContactsArray = formattedContacts.join('\n\n'); + const formattedContactsArray = formattedContacts.join('\n\n'); - this.logger.verbose('formatted contacts: ' + formattedContactsArray); + this.logger.verbose('formatted contacts: ' + formattedContactsArray); - return formattedContactsArray; - } - - this.logger.verbose('message content: ' + result); - - return result; - } - - private getConversationMessage(msg: any) { - this.logger.verbose('get conversation message'); - - const types = this.getTypeMessage(msg); - - const messageContent = this.getMessageContent(types); - - this.logger.verbose('conversation message: ' + messageContent); - - return messageContent; - } - - public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { - this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (!waInstance) { - this.logger.warn('wa instance not found'); - return null; - } - - if (event === 'messages.upsert') { - this.logger.verbose('event messages.upsert'); - - if (body.key.remoteJid === 'status@broadcast') { - this.logger.verbose('status broadcast found'); - return; + return formattedContactsArray; } + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { this.logger.verbose('get conversation message'); - const bodyMessage = await this.getConversationMessage(body.message); - const isMedia = this.isMediaMessage(body.message); + const types = this.getTypeMessage(msg); - if (!bodyMessage && !isMedia) { - this.logger.warn('no body message found'); - return; - } + const messageContent = this.getMessageContent(types); - this.logger.verbose('get conversation in chatwoot'); - const getConversion = await this.createConversation(instance, body); + this.logger.verbose('conversation message: ' + messageContent); - if (!getConversion) { - this.logger.warn('conversation not found'); - return; - } - - const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; - - this.logger.verbose('message type: ' + messageType); - - this.logger.verbose('is media: ' + isMedia); - - this.logger.verbose('check if is media'); - if (isMedia) { - this.logger.verbose('message is media'); - - this.logger.verbose('get base64 from media message'); - const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ - message: { - ...body, - }, - }); - - const random = Math.random().toString(36).substring(7); - const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; - - const fileData = Buffer.from(downloadBase64.base64, 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; - - this.logger.verbose('temp file name: ' + nameFile); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - content, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - bodyMessage, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - content, - messageType, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - bodyMessage, - messageType, - ); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - if (event === 'status.instance') { - this.logger.verbose('event status.instance'); - const data = body; - const inbox = await this.getInbox(instance); - - if (!inbox) { - this.logger.warn('inbox not found'); - return; - } - - const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgStatus, 'incoming'); - } - - if (event === 'connection.update') { - this.logger.verbose('event connection.update'); - - if (body.status === 'open') { - const msgConnection = `🚀 Connection successfully established!`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgConnection, 'incoming'); - } - } - - if (event === 'qrcode.updated') { - this.logger.verbose('event qrcode.updated'); - if (body.statusCode === 500) { - this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; - - this.logger.verbose('send message to chatwoot'); - return await this.createBotMessage(instance, erroQRcode, 'incoming'); - } else { - this.logger.verbose('qrcode success'); - const fileData = Buffer.from( - body?.qrcode.base64.replace('data:image/png;base64,', ''), - 'base64', - ); - - const fileName = `${path.join( - waInstance?.storePath, - 'temp', - `${`${instance}.png`}`, - )}`; - - this.logger.verbose('temp file name: ' + fileName); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr( - instance, - 'QRCode successfully generated!', - 'incoming', - fileName, - ); - - let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; - - if (body?.qrcode?.pairingCode) { - msgQrCode = - msgQrCode + - `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( - 0, - 4, - )}-${body.qrcode.pairingCode.substring(4, 8)}`; - } - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgQrCode, 'incoming'); - } - } - } catch (error) { - this.logger.error(error); + return messageContent; } - } - public async newInstance(data: any) { - try { - const instanceName = data.instanceName; - const qrcode = true; - const number = data.number; - const accountId = data.accountId; - const chatwootToken = data.token; - const chatwootUrl = data.url; - const signMsg = true; - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { + this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); - const requestData = { - instanceName, - qrcode, - chatwoot_account_id: accountId, - chatwoot_token: chatwootToken, - chatwoot_url: chatwootUrl, - chatwoot_sign_msg: signMsg, - }; + if (!client) { + this.logger.warn('client not found'); + return null; + } - if (number) { - requestData['number'] = number; - } + const waInstance = this.waMonitor.waInstances[instance.instanceName]; - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: requestData, - }; + if (!waInstance) { + this.logger.warn('wa instance not found'); + return null; + } - // await axios.request(config); + if (event === 'messages.upsert') { + this.logger.verbose('event messages.upsert'); - return true; - } catch (error) { - this.logger.error(error); - return null; + if (body.key.remoteJid === 'status@broadcast') { + this.logger.verbose('status broadcast found'); + return; + } + + this.logger.verbose('get conversation message'); + const bodyMessage = await this.getConversationMessage(body.message); + + const isMedia = this.isMediaMessage(body.message); + + if (!bodyMessage && !isMedia) { + this.logger.warn('no body message found'); + return; + } + + this.logger.verbose('get conversation in chatwoot'); + const getConversion = await this.createConversation(instance, body); + + if (!getConversion) { + this.logger.warn('conversation not found'); + return; + } + + const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; + + this.logger.verbose('message type: ' + messageType); + + this.logger.verbose('is media: ' + isMedia); + + this.logger.verbose('check if is media'); + if (isMedia) { + this.logger.verbose('message is media'); + + this.logger.verbose('get base64 from media message'); + const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ + message: { + ...body, + }, + }); + + const random = Math.random().toString(36).substring(7); + const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; + + const fileData = Buffer.from(downloadBase64.base64, 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; + + this.logger.verbose('temp file name: ' + nameFile); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, content); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, content, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join( + ROOT_DIR, + 'store', + 'chatwoot', + `${instance.instanceName}_cache.txt`, + ); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + if (event === 'status.instance') { + this.logger.verbose('event status.instance'); + const data = body; + const inbox = await this.getInbox(instance); + + if (!inbox) { + this.logger.warn('inbox not found'); + return; + } + + const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgStatus, 'incoming'); + } + + if (event === 'connection.update') { + this.logger.verbose('event connection.update'); + + if (body.status === 'open') { + const msgConnection = `🚀 Connection successfully established!`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgConnection, 'incoming'); + } + } + + if (event === 'qrcode.updated') { + this.logger.verbose('event qrcode.updated'); + if (body.statusCode === 500) { + this.logger.verbose('qrcode error'); + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; + + this.logger.verbose('send message to chatwoot'); + return await this.createBotMessage(instance, erroQRcode, 'incoming'); + } else { + this.logger.verbose('qrcode success'); + const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; + + this.logger.verbose('temp file name: ' + fileName); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('send qrcode to chatwoot'); + await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); + + let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + + if (body?.qrcode?.pairingCode) { + msgQrCode = + msgQrCode + + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( + 0, + 4, + )}-${body.qrcode.pairingCode.substring(4, 8)}`; + } + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgQrCode, 'incoming'); + } + } + } catch (error) { + this.logger.error(error); + } + } + + public async newInstance(data: any) { + try { + const instanceName = data.instanceName; + const qrcode = true; + const number = data.number; + const accountId = data.accountId; + const chatwootToken = data.token; + const chatwootUrl = data.url; + const signMsg = true; + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const requestData = { + instanceName, + qrcode, + chatwoot_account_id: accountId, + chatwoot_token: chatwootToken, + chatwoot_url: chatwootUrl, + chatwoot_sign_msg: signMsg, + }; + + if (number) { + requestData['number'] = number; + } + + // eslint-disable-next-line + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: requestData, + }; + + // await axios.request(config); + + return true; + } catch (error) { + this.logger.error(error); + return null; + } } - } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 1108d77c..1504366a 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -2,7 +2,6 @@ import { execSync } from 'child_process'; import EventEmitter2 from 'eventemitter2'; import { opendirSync, readdirSync, rmSync } from 'fs'; import { Db } from 'mongodb'; -import mongoose from 'mongoose'; import { join } from 'path'; import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config'; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4c9bf62d..1678822f 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,3067 +1,2926 @@ +import ffmpegPath from '@ffmpeg-installer/ffmpeg'; +import { Boom } from '@hapi/boom'; import makeWASocket, { - AnyMessageContent, - BufferedEventData, - BufferJSON, - CacheStore, - makeCacheableSignalKeyStore, - Chat, - ConnectionState, - Contact, - delay, - DisconnectReason, - downloadMediaMessage, - fetchLatestBaileysVersion, - generateWAMessageFromContent, - getContentType, - getDevice, - GroupMetadata, - isJidGroup, - isJidUser, - MessageUpsertType, - MiscMessageGenerationOptions, - ParticipantAction, - prepareWAMessageMedia, - proto, - useMultiFileAuthState, - UserFacingSocketConfig, - WABrowserDescription, - WAMediaUpload, - WAMessage, - WAMessageUpdate, - WASocket, - getAggregateVotesInPollMessage, + AnyMessageContent, + BufferedEventData, + BufferJSON, + CacheStore, + Chat, + ConnectionState, + Contact, + delay, + DisconnectReason, + downloadMediaMessage, + fetchLatestBaileysVersion, + generateWAMessageFromContent, + getAggregateVotesInPollMessage, + getContentType, + getDevice, + GroupMetadata, + isJidGroup, + isJidUser, + makeCacheableSignalKeyStore, + MessageUpsertType, + MiscMessageGenerationOptions, + ParticipantAction, + prepareWAMessageMedia, + proto, + useMultiFileAuthState, + UserFacingSocketConfig, + WABrowserDescription, + WAMediaUpload, + WAMessage, + WAMessageUpdate, + WASocket, } from '@whiskeysockets/baileys'; -import { - Auth, - CleanStoreConf, - ConfigService, - ConfigSessionPhone, - Database, - HttpServer, - QrCode, - Redis, - Webhook, -} from '../../config/env.config'; -import fs from 'fs'; -import { Logger } from '../../config/logger.config'; -import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; -import { existsSync, readFileSync } from 'fs'; -import { join } from 'path'; import axios from 'axios'; -import { v4 } from 'uuid'; +import { exec, execSync } from 'child_process'; +import { arrayUnique, isBase64, isURL } from 'class-validator'; +import EventEmitter2 from 'eventemitter2'; +import fs, { existsSync, readFileSync } from 'fs'; +import Long from 'long'; +import NodeCache from 'node-cache'; +import { getMIMEType } from 'node-mime-types'; +import { release } from 'os'; +import { join } from 'path'; +import P from 'pino'; import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; import qrcodeTerminal from 'qrcode-terminal'; -import { Events, TypeMediaMessage, wa, MessageSubtype } from '../types/wa.types'; -import { Boom } from '@hapi/boom'; -import EventEmitter2 from 'eventemitter2'; -import { release } from 'os'; -import P from 'pino'; -import { execSync, exec } from 'child_process'; -import ffmpegPath from '@ffmpeg-installer/ffmpeg'; -import { RepositoryBroker } from '../repository/repository.manager'; -import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; -import { ContactRaw } from '../models/contact.model'; -import { ChatRaw } from '../models/chat.model'; -import { getMIMEType } from 'node-mime-types'; -import { - ContactMessage, - MediaMessage, - Options, - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendReactionDto, - SendTextDto, - SendPollDto, - SendStickerDto, - SendStatusDto, - StatusMessage, -} from '../dto/sendMessage.dto'; -import { arrayUnique, isBase64, isURL } from 'class-validator'; -import { - ArchiveChatDto, - DeleteMessage, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, - getBase64FromMediaMessageDto, -} from '../dto/chat.dto'; -import { MessageQuery } from '../repository/message.repository'; -import { ContactQuery } from '../repository/contact.repository'; -import { - BadRequestException, - InternalServerErrorException, - NotFoundException, -} from '../../exceptions'; -import { - CreateGroupDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, - GroupToggleEphemeralDto, - GroupSubjectDto, - GroupDescriptionDto, - GroupSendInvite, - GetParticipant, -} from '../dto/group.dto'; -import { MessageUpQuery } from '../repository/messageUp.repository'; -import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; -import Long from 'long'; -import { WebhookRaw } from '../models/webhook.model'; -import { ChatwootRaw } from '../models/chatwoot.model'; -import { SettingsRaw } from '../models'; -import { dbserver } from '../../db/db.connect'; -import NodeCache from 'node-cache'; -import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import sharp from 'sharp'; +import { v4 } from 'uuid'; + +import { + Auth, + CleanStoreConf, + ConfigService, + ConfigSessionPhone, + Database, + HttpServer, + Log, + QrCode, + Redis, + Webhook, +} from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; +import { dbserver } from '../../db/db.connect'; import { RedisCache } from '../../db/redis.client'; -import { Log } from '../../config/env.config'; -import { ChatwootService } from './chatwoot.service'; +import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; +import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; +import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; +import { + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, +} from '../dto/chat.dto'; +import { + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, +} from '../dto/group.dto'; +import { + ContactMessage, + MediaMessage, + Options, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, + StatusMessage, +} from '../dto/sendMessage.dto'; +import { SettingsRaw } from '../models'; +import { ChatRaw } from '../models/chat.model'; +import { ChatwootRaw } from '../models/chatwoot.model'; +import { ContactRaw } from '../models/contact.model'; +import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; +import { WebhookRaw } from '../models/webhook.model'; +import { ContactQuery } from '../repository/contact.repository'; +import { MessageQuery } from '../repository/message.repository'; +import { MessageUpQuery } from '../repository/messageUp.repository'; +import { RepositoryBroker } from '../repository/repository.manager'; +import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; import { waMonitor } from '../whatsapp.module'; +import { ChatwootService } from './chatwoot.service'; export class WAStartupService { - constructor( - private readonly configService: ConfigService, - private readonly eventEmitter: EventEmitter2, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('WAStartupService initialized'); - this.cleanStore(); - this.instance.qrcode = { count: 0 }; - } - - private readonly logger = new Logger(WAStartupService.name); - private readonly instance: wa.Instance = {}; - public client: WASocket; - private readonly localWebhook: wa.LocalWebHook = {}; - private readonly localChatwoot: wa.LocalChatwoot = {}; - private readonly localSettings: wa.LocalSettings = {}; - private stateConnection: wa.StateConnection = { state: 'close' }; - public readonly storePath = join(ROOT_DIR, 'store'); - private readonly msgRetryCounterCache: CacheStore = new NodeCache(); - private readonly userDevicesCache: CacheStore = new NodeCache(); - private endSession = false; - private logBaileys = this.configService.get('LOG').BAILEYS; - - private phoneNumber: string; - - private chatwootService = new ChatwootService(waMonitor, this.configService); - - public set instanceName(name: string) { - this.logger.verbose(`Initializing instance '${name}'`); - if (!name) { - this.logger.verbose('Instance name not found, generating random name with uuid'); - this.instance.name = v4(); - return; - } - this.instance.name = name; - this.logger.verbose(`Instance '${this.instance.name}' initialized`); - this.logger.verbose('Sending instance status to webhook'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'created', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'created', - }, - ); - } - } - - public get instanceName() { - this.logger.verbose('Getting instance name'); - return this.instance.name; - } - - public get wuid() { - this.logger.verbose('Getting remoteJid of instance'); - return this.instance.wuid; - } - - public async getProfileName() { - this.logger.verbose('Getting profile name'); - let profileName = this.client.user?.name ?? this.client.user?.verifiedName; - if (!profileName) { - this.logger.verbose('Profile name not found, trying to get from database'); - if (this.configService.get('DATABASE').ENABLED) { - this.logger.verbose('Database enabled, trying to get from database'); - const collection = dbserver - .getClient() - .db( - this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + - '-instances', - ) - .collection(this.instanceName); - const data = await collection.findOne({ _id: 'creds' }); - if (data) { - this.logger.verbose('Profile name found in database'); - const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); - profileName = creds.me?.name || creds.me?.verifiedName; - } - } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { - this.logger.verbose('Profile name found in file'); - const creds = JSON.parse( - readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { - encoding: 'utf-8', - }), - ); - profileName = creds.me?.name || creds.me?.verifiedName; - } + constructor( + private readonly configService: ConfigService, + private readonly eventEmitter: EventEmitter2, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('WAStartupService initialized'); + this.cleanStore(); + this.instance.qrcode = { count: 0 }; } - this.logger.verbose(`Profile name: ${profileName}`); - return profileName; - } + private readonly logger = new Logger(WAStartupService.name); + private readonly instance: wa.Instance = {}; + public client: WASocket; + private readonly localWebhook: wa.LocalWebHook = {}; + private readonly localChatwoot: wa.LocalChatwoot = {}; + private readonly localSettings: wa.LocalSettings = {}; + private stateConnection: wa.StateConnection = { state: 'close' }; + public readonly storePath = join(ROOT_DIR, 'store'); + private readonly msgRetryCounterCache: CacheStore = new NodeCache(); + private readonly userDevicesCache: CacheStore = new NodeCache(); + private endSession = false; + private logBaileys = this.configService.get('LOG').BAILEYS; - public async getProfileStatus() { - this.logger.verbose('Getting profile status'); - const status = await this.client.fetchStatus(this.instance.wuid); + private phoneNumber: string; - this.logger.verbose(`Profile status: ${status.status}`); - return status.status; - } + private chatwootService = new ChatwootService(waMonitor, this.configService); - public get profilePictureUrl() { - this.logger.verbose('Getting profile picture url'); - return this.instance.profilePictureUrl; - } - - public get qrCode(): wa.QrCode { - this.logger.verbose('Getting qrcode'); - - return { - pairingCode: this.instance.qrcode?.pairingCode, - code: this.instance.qrcode?.code, - base64: this.instance.qrcode?.base64, - }; - } - - private async loadWebhook() { - this.logger.verbose('Loading webhook'); - const data = await this.repository.webhook.find(this.instanceName); - this.localWebhook.url = data?.url; - this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); - - this.localWebhook.enabled = data?.enabled; - this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); - - this.localWebhook.events = data?.events; - this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); - - this.localWebhook.webhook_by_events = data?.webhook_by_events; - this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); - - this.logger.verbose('Webhook loaded'); - } - - public async setWebhook(data: WebhookRaw) { - this.logger.verbose('Setting webhook'); - await this.repository.webhook.create(data, this.instanceName); - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - Object.assign(this.localWebhook, data); - this.logger.verbose('Webhook set'); - } - - public async findWebhook() { - this.logger.verbose('Finding webhook'); - const data = await this.repository.webhook.find(this.instanceName); - - if (!data) { - this.logger.verbose('Webhook not found'); - throw new NotFoundException('Webhook not found'); - } - - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - return data; - } - - private async loadChatwoot() { - this.logger.verbose('Loading chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - this.localChatwoot.enabled = data?.enabled; - this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); - - this.localChatwoot.account_id = data?.account_id; - this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); - - this.localChatwoot.token = data?.token; - this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); - - this.localChatwoot.url = data?.url; - this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); - - this.localChatwoot.name_inbox = data?.name_inbox; - this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); - - this.localChatwoot.sign_msg = data?.sign_msg; - this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); - - this.localChatwoot.number = data?.number; - this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); - - this.localChatwoot.reopen_conversation = data?.reopen_conversation; - this.logger.verbose( - `Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`, - ); - - this.localChatwoot.conversation_pending = data?.conversation_pending; - this.logger.verbose( - `Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`, - ); - - this.logger.verbose('Chatwoot loaded'); - } - - public async setChatwoot(data: ChatwootRaw) { - this.logger.verbose('Setting chatwoot'); - await this.repository.chatwoot.create(data, this.instanceName); - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); - this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); - - Object.assign(this.localChatwoot, data); - this.logger.verbose('Chatwoot set'); - } - - public async findChatwoot() { - this.logger.verbose('Finding chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - - if (!data) { - this.logger.verbose('Chatwoot not found'); - return null; - } - - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); - this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); - - return data; - } - - private async loadSettings() { - this.logger.verbose('Loading settings'); - const data = await this.repository.settings.find(this.instanceName); - this.localSettings.reject_call = data?.reject_call; - this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); - - this.localSettings.msg_call = data?.msg_call; - this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); - - this.localSettings.groups_ignore = data?.groups_ignore; - this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); - - this.localSettings.always_online = data?.always_online; - this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); - - this.localSettings.read_messages = data?.read_messages; - this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); - - this.localSettings.read_status = data?.read_status; - this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); - - this.logger.verbose('Settings loaded'); - } - - public async setSettings(data: SettingsRaw) { - this.logger.verbose('Setting settings'); - await this.repository.settings.create(data, this.instanceName); - this.logger.verbose(`Settings reject_call: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - this.logger.verbose(`Settings always_online: ${data.always_online}`); - this.logger.verbose(`Settings read_messages: ${data.read_messages}`); - this.logger.verbose(`Settings read_status: ${data.read_status}`); - Object.assign(this.localSettings, data); - this.logger.verbose('Settings set'); - - this.client?.ws?.close(); - } - - public async findSettings() { - this.logger.verbose('Finding settings'); - const data = await this.repository.settings.find(this.instanceName); - - if (!data) { - this.logger.verbose('Settings not found'); - return null; - } - - this.logger.verbose(`Settings url: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - this.logger.verbose(`Settings always_online: ${data.always_online}`); - this.logger.verbose(`Settings read_messages: ${data.read_messages}`); - this.logger.verbose(`Settings read_status: ${data.read_status}`); - return data; - } - - public async sendDataWebhook(event: Events, data: T, local = true) { - const webhookGlobal = this.configService.get('WEBHOOK'); - const webhookLocal = this.localWebhook.events; - const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[\.-]/gm, '_').toUpperCase(); - const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - - const expose = - this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; - const tokenStore = await this.repository.auth.find(this.instanceName); - const instanceApikey = tokenStore?.apikey || 'Apikey not found'; - - const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - if (local) { - if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { - this.logger.verbose('Sending data to webhook local'); - let baseURL; - - if (this.localWebhook.webhook_by_events) { - baseURL = `${this.localWebhook.url}/${transformedWe}`; - } else { - baseURL = this.localWebhook.url; + public set instanceName(name: string) { + this.logger.verbose(`Initializing instance '${name}'`); + if (!name) { + this.logger.verbose('Instance name not found, generating random name with uuid'); + this.instance.name = v4(); + return; } - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-local', - url: baseURL, - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - apikey: (expose && instanceApikey) || null, - }; - - if (expose && instanceApikey) { - logData['apikey'] = instanceApikey; - } - - this.logger.log(logData); - } - - try { - if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { - const httpService = axios.create({ baseURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - }; - - if (expose && instanceApikey) { - postData['apikey'] = instanceApikey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-local', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: baseURL, - server_url: serverUrl, - }); - } - } - } - - if (webhookGlobal.GLOBAL?.ENABLED) { - if (webhookGlobal.EVENTS[we]) { - this.logger.verbose('Sending data to webhook global'); - const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; - - let globalURL; - - if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { - globalURL = `${globalWebhook.URL}/${transformedWe}`; - } else { - globalURL = globalWebhook.URL; - } - - const localUrl = this.localWebhook.url; - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-global', - url: globalURL, - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - logData['apikey'] = globalApiKey; - } - - this.logger.log(logData); - } - - try { - if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { - const httpService = axios.create({ baseURL: globalURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - postData['apikey'] = globalApiKey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-global', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: globalURL, - server_url: serverUrl, - }); - } - } - } - } - - private async connectionUpdate({ - qr, - connection, - lastDisconnect, - }: Partial) { - this.logger.verbose('Connection update'); - if (qr) { - this.logger.verbose('QR code found'); - if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { - this.logger.verbose('QR code limit reached'); - - this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); - this.sendDataWebhook(Events.QRCODE_UPDATED, { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }, - ); - } - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - state: 'refused', - statusReason: DisconnectReason.connectionClosed, - }); - - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.instance.name = name; + this.logger.verbose(`Instance '${this.instance.name}' initialized`); + this.logger.verbose('Sending instance status to webhook'); this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('endSession defined as true'); - this.endSession = true; - - this.logger.verbose('Emmiting event logout.instance'); - return this.eventEmitter.emit('no.connection', this.instance.name); - } - - this.logger.verbose('Incrementing QR code count'); - this.instance.qrcode.count++; - - const optsQrcode: QRCodeToDataURLOptions = { - margin: 3, - scale: 4, - errorCorrectionLevel: 'H', - color: { light: '#ffffff', dark: '#198754' }, - }; - - if (this.phoneNumber) { - await delay(2000); - this.instance.qrcode.pairingCode = await this.client.requestPairingCode( - this.phoneNumber, - ); - } else { - this.instance.qrcode.pairingCode = null; - } - - this.logger.verbose('Generating QR code'); - qrcode.toDataURL(qr, optsQrcode, (error, base64) => { - if (error) { - this.logger.error('Qrcode generate failed:' + error.toString()); - return; - } - - this.instance.qrcode.base64 = base64; - this.instance.qrcode.code = qr; - - this.sendDataWebhook(Events.QRCODE_UPDATED, { - qrcode: { instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, + status: 'created', }); if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - qrcode: { - instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }, - ); + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'created', + }, + ); } - }); - - this.logger.verbose('Generating QR code in terminal'); - qrcodeTerminal.generate(qr, { small: true }, (qrcode) => - this.logger.log( - `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + - qrcode, - ), - ); } - if (connection) { - this.logger.verbose('Connection found'); - this.stateConnection = { - state: connection, - statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, - }; - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - ...this.stateConnection, - }); + public get instanceName() { + this.logger.verbose('Getting instance name'); + return this.instance.name; } - if (connection === 'close') { - this.logger.verbose('Connection closed'); - const shouldReconnect = - (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; - if (shouldReconnect) { - this.logger.verbose('Reconnecting to whatsapp'); - await this.connectToWhatsapp(); - } else { - this.logger.verbose('Do not reconnect to whatsapp'); - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); + public get wuid() { + this.logger.verbose('Getting remoteJid of instance'); + return this.instance.wuid; + } - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); + public async getProfileName() { + this.logger.verbose('Getting profile name'); + let profileName = this.client.user?.name ?? this.client.user?.verifiedName; + if (!profileName) { + this.logger.verbose('Profile name not found, trying to get from database'); + if (this.configService.get('DATABASE').ENABLED) { + this.logger.verbose('Database enabled, trying to get from database'); + const collection = dbserver + .getClient() + .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(this.instanceName); + const data = await collection.findOne({ _id: 'creds' }); + if (data) { + this.logger.verbose('Profile name found in database'); + const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); + profileName = creds.me?.name || creds.me?.verifiedName; + } + } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { + this.logger.verbose('Profile name found in file'); + const creds = JSON.parse( + readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { + encoding: 'utf-8', + }), + ); + profileName = creds.me?.name || creds.me?.verifiedName; + } } - this.logger.verbose('Emittin event logout.instance'); - this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); + this.logger.verbose(`Profile name: ${profileName}`); + return profileName; + } + + public async getProfileStatus() { + this.logger.verbose('Getting profile status'); + const status = await this.client.fetchStatus(this.instance.wuid); + + this.logger.verbose(`Profile status: ${status.status}`); + return status.status; + } + + public get profilePictureUrl() { + this.logger.verbose('Getting profile picture url'); + return this.instance.profilePictureUrl; + } + + public get qrCode(): wa.QrCode { + this.logger.verbose('Getting qrcode'); + + return { + pairingCode: this.instance.qrcode?.pairingCode, + code: this.instance.qrcode?.code, + base64: this.instance.qrcode?.base64, + }; + } + + private async loadWebhook() { + this.logger.verbose('Loading webhook'); + const data = await this.repository.webhook.find(this.instanceName); + this.localWebhook.url = data?.url; + this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + + this.localWebhook.enabled = data?.enabled; + this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + + this.localWebhook.events = data?.events; + this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); + + this.localWebhook.webhook_by_events = data?.webhook_by_events; + this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + + this.logger.verbose('Webhook loaded'); + } + + public async setWebhook(data: WebhookRaw) { + this.logger.verbose('Setting webhook'); + await this.repository.webhook.create(data, this.instanceName); + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + Object.assign(this.localWebhook, data); + this.logger.verbose('Webhook set'); + } + + public async findWebhook() { + this.logger.verbose('Finding webhook'); + const data = await this.repository.webhook.find(this.instanceName); + + if (!data) { + this.logger.verbose('Webhook not found'); + throw new NotFoundException('Webhook not found'); + } + + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + return data; + } + + private async loadChatwoot() { + this.logger.verbose('Loading chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + this.localChatwoot.enabled = data?.enabled; + this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + + this.localChatwoot.account_id = data?.account_id; + this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); + + this.localChatwoot.token = data?.token; + this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); + + this.localChatwoot.url = data?.url; + this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); + + this.localChatwoot.name_inbox = data?.name_inbox; + this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); + + this.localChatwoot.sign_msg = data?.sign_msg; + this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + + this.localChatwoot.number = data?.number; + this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); + + this.localChatwoot.reopen_conversation = data?.reopen_conversation; + this.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`); + + this.localChatwoot.conversation_pending = data?.conversation_pending; + this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`); + + this.logger.verbose('Chatwoot loaded'); + } + + public async setChatwoot(data: ChatwootRaw) { + this.logger.verbose('Setting chatwoot'); + await this.repository.chatwoot.create(data, this.instanceName); + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + Object.assign(this.localChatwoot, data); + this.logger.verbose('Chatwoot set'); + } + + public async findChatwoot() { + this.logger.verbose('Finding chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + + if (!data) { + this.logger.verbose('Chatwoot not found'); + return null; + } + + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + return data; + } + + private async loadSettings() { + this.logger.verbose('Loading settings'); + const data = await this.repository.settings.find(this.instanceName); + this.localSettings.reject_call = data?.reject_call; + this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); + + this.localSettings.msg_call = data?.msg_call; + this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); + + this.localSettings.groups_ignore = data?.groups_ignore; + this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + + this.logger.verbose('Settings loaded'); + } + + public async setSettings(data: SettingsRaw) { + this.logger.verbose('Setting settings'); + await this.repository.settings.create(data, this.instanceName); + this.logger.verbose(`Settings reject_call: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + Object.assign(this.localSettings, data); + this.logger.verbose('Settings set'); + this.client?.ws?.close(); - this.client.end(new Error('Close connection')); - this.logger.verbose('Connection closed'); - } } - if (connection === 'open') { - this.logger.verbose('Connection opened'); - this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); - this.instance.profilePictureUrl = ( - await this.profilePicture(this.instance.wuid) - ).profilePictureUrl; - this.logger.info( - ` + public async findSettings() { + this.logger.verbose('Finding settings'); + const data = await this.repository.settings.find(this.instanceName); + + if (!data) { + this.logger.verbose('Settings not found'); + return null; + } + + this.logger.verbose(`Settings url: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + return data; + } + + public async sendDataWebhook(event: Events, data: T, local = true) { + const webhookGlobal = this.configService.get('WEBHOOK'); + const webhookLocal = this.localWebhook.events; + const serverUrl = this.configService.get('SERVER').URL; + const we = event.replace(/[.-]/gm, '_').toUpperCase(); + const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + + const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const tokenStore = await this.repository.auth.find(this.instanceName); + const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + + const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + if (local) { + if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { + this.logger.verbose('Sending data to webhook local'); + let baseURL: string; + + if (this.localWebhook.webhook_by_events) { + baseURL = `${this.localWebhook.url}/${transformedWe}`; + } else { + baseURL = this.localWebhook.url; + } + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-local', + url: baseURL, + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } + + try { + if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { + const httpService = axios.create({ baseURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + postData['apikey'] = instanceApikey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-local', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: baseURL, + server_url: serverUrl, + }); + } + } + } + + if (webhookGlobal.GLOBAL?.ENABLED) { + if (webhookGlobal.EVENTS[we]) { + this.logger.verbose('Sending data to webhook global'); + const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; + + let globalURL; + + if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { + globalURL = `${globalWebhook.URL}/${transformedWe}`; + } else { + globalURL = globalWebhook.URL; + } + + const localUrl = this.localWebhook.url; + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-global', + url: globalURL, + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + logData['apikey'] = globalApiKey; + } + + this.logger.log(logData); + } + + try { + if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { + const httpService = axios.create({ baseURL: globalURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + postData['apikey'] = globalApiKey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-global', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: globalURL, + server_url: serverUrl, + }); + } + } + } + } + + private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { + this.logger.verbose('Connection update'); + if (qr) { + this.logger.verbose('QR code found'); + if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { + this.logger.verbose('QR code limit reached'); + + this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); + this.sendDataWebhook(Events.QRCODE_UPDATED, { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }, + ); + } + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + state: 'refused', + statusReason: DisconnectReason.connectionClosed, + }); + + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); + } + + this.logger.verbose('endSession defined as true'); + this.endSession = true; + + this.logger.verbose('Emmiting event logout.instance'); + return this.eventEmitter.emit('no.connection', this.instance.name); + } + + this.logger.verbose('Incrementing QR code count'); + this.instance.qrcode.count++; + + const optsQrcode: QRCodeToDataURLOptions = { + margin: 3, + scale: 4, + errorCorrectionLevel: 'H', + color: { light: '#ffffff', dark: '#198754' }, + }; + + if (this.phoneNumber) { + await delay(2000); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); + } else { + this.instance.qrcode.pairingCode = null; + } + + this.logger.verbose('Generating QR code'); + qrcode.toDataURL(qr, optsQrcode, (error, base64) => { + if (error) { + this.logger.error('Qrcode generate failed:' + error.toString()); + return; + } + + this.instance.qrcode.base64 = base64; + this.instance.qrcode.code = qr; + + this.sendDataWebhook(Events.QRCODE_UPDATED, { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }, + ); + } + }); + + this.logger.verbose('Generating QR code in terminal'); + qrcodeTerminal.generate(qr, { small: true }, (qrcode) => + this.logger.log( + `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + + qrcode, + ), + ); + } + + if (connection) { + this.logger.verbose('Connection found'); + this.stateConnection = { + state: connection, + statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, + }; + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + ...this.stateConnection, + }); + } + + if (connection === 'close') { + this.logger.verbose('Connection closed'); + const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; + if (shouldReconnect) { + this.logger.verbose('Reconnecting to whatsapp'); + await this.connectToWhatsapp(); + } else { + this.logger.verbose('Do not reconnect to whatsapp'); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); + } + + this.logger.verbose('Emittin event logout.instance'); + this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); + this.client?.ws?.close(); + this.client.end(new Error('Close connection')); + this.logger.verbose('Connection closed'); + } + } + + if (connection === 'open') { + this.logger.verbose('Connection opened'); + this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); + this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; + this.logger.info( + ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ └──────────────────────────────┘`.replace(/^ +/gm, ' '), - ); + ); - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.CONNECTION_UPDATE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'open', - }, - ); - } - } - } - - private async getMessage(key: proto.IMessageKey, full = false) { - this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); - try { - const webMessageInfo = (await this.repository.message.find({ - where: { owner: this.instance.name, key: { id: key.id } }, - })) as unknown as proto.IWebMessageInfo[]; - if (full) { - this.logger.verbose('Returning full message'); - return webMessageInfo[0]; - } - if (webMessageInfo[0].message?.pollCreationMessage) { - this.logger.verbose('Returning poll message'); - const messageSecretBase64 = - webMessageInfo[0].message?.messageContextInfo?.messageSecret; - - if (typeof messageSecretBase64 === 'string') { - const messageSecret = Buffer.from(messageSecretBase64, 'base64'); - - const msg = { - messageContextInfo: { - messageSecret, - }, - pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, - }; - - return msg; + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.CONNECTION_UPDATE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'open', + }, + ); + } } - } - - this.logger.verbose('Returning message'); - return webMessageInfo[0].message; - } catch (error) { - return { conversation: '' }; } - } - private cleanStore() { - this.logger.verbose('Cronjob to clean store initialized'); - const cleanStore = this.configService.get('CLEAN_STORE'); - const database = this.configService.get('DATABASE'); - if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { - this.logger.verbose('Cronjob to clean store enabled'); - setInterval(() => { + private async getMessage(key: proto.IMessageKey, full = false) { + this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); try { - for (const [key, value] of Object.entries(cleanStore)) { - if (value === true) { - execSync( - `rm -rf ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - this.logger.verbose( - `Cleaned ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); + const webMessageInfo = (await this.repository.message.find({ + where: { owner: this.instance.name, key: { id: key.id } }, + })) as unknown as proto.IWebMessageInfo[]; + if (full) { + this.logger.verbose('Returning full message'); + return webMessageInfo[0]; } - } - } catch (error) {} - }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); - } - } + if (webMessageInfo[0].message?.pollCreationMessage) { + this.logger.verbose('Returning poll message'); + const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; - private async defineAuthState() { - this.logger.verbose('Defining auth state'); - const db = this.configService.get('DATABASE'); - const redis = this.configService.get('REDIS'); + if (typeof messageSecretBase64 === 'string') { + const messageSecret = Buffer.from(messageSecretBase64, 'base64'); - if (redis?.ENABLED) { - this.logger.verbose('Redis enabled'); - this.cache.reference = this.instance.name; - return await useMultiFileAuthStateRedisDb(this.cache); + const msg = { + messageContextInfo: { + messageSecret, + }, + pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, + }; + + return msg; + } + } + + this.logger.verbose('Returning message'); + return webMessageInfo[0].message; + } catch (error) { + return { conversation: '' }; + } } - if (db.SAVE_DATA.INSTANCE && db.ENABLED) { - this.logger.verbose('Database enabled'); - return await useMultiFileAuthStateDb(this.instance.name); + private cleanStore() { + this.logger.verbose('Cronjob to clean store initialized'); + const cleanStore = this.configService.get('CLEAN_STORE'); + const database = this.configService.get('DATABASE'); + if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { + this.logger.verbose('Cronjob to clean store enabled'); + setInterval(() => { + try { + for (const [key, value] of Object.entries(cleanStore)) { + if (value === true) { + execSync( + `rm -rf ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); + this.logger.verbose( + `Cleaned ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.name, + )}/*.json`, + ); + } + } + } catch (error) { + this.logger.error(error); + } + }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); + } } - this.logger.verbose('Store file enabled'); - return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); - } + private async defineAuthState() { + this.logger.verbose('Defining auth state'); + const db = this.configService.get('DATABASE'); + const redis = this.configService.get('REDIS'); - public async connectToWhatsapp(number?: string): Promise { - this.logger.verbose('Connecting to whatsapp'); - try { - this.loadWebhook(); - this.loadChatwoot(); - this.loadSettings(); + if (redis?.ENABLED) { + this.logger.verbose('Redis enabled'); + this.cache.reference = this.instance.name; + return await useMultiFileAuthStateRedisDb(this.cache); + } - this.instance.authState = await this.defineAuthState(); + if (db.SAVE_DATA.INSTANCE && db.ENABLED) { + this.logger.verbose('Database enabled'); + return await useMultiFileAuthStateDb(this.instance.name); + } - const { version } = await fetchLatestBaileysVersion(); - this.logger.verbose('Baileys version: ' + version); - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - this.logger.verbose('Browser: ' + JSON.stringify(browser)); + this.logger.verbose('Store file enabled'); + return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); + } - const socketConfig: UserFacingSocketConfig = { - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore( - this.instance.authState.state.keys, - P({ level: 'error' }), - ), - }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - browser, - version, - markOnlineOnConnect: this.localSettings.always_online, - connectTimeoutMs: 60_000, - qrTimeout: 40_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => - (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: true, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, - patchMessageBeforeSending: (message) => { - const requiresPatch = !!( - message.buttonsMessage || - message.listMessage || - message.templateMessage - ); - if (requiresPatch) { - message = { - viewOnceMessageV2: { - message: { - messageContextInfo: { - deviceListMetadataVersion: 2, - deviceListMetadata: {}, - }, - ...message, + public async connectToWhatsapp(number?: string): Promise { + this.logger.verbose('Connecting to whatsapp'); + try { + this.loadWebhook(); + this.loadChatwoot(); + this.loadSettings(); + + this.instance.authState = await this.defineAuthState(); + + const { version } = await fetchLatestBaileysVersion(); + this.logger.verbose('Baileys version: ' + version); + const session = this.configService.get('CONFIG_SESSION_PHONE'); + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + this.logger.verbose('Browser: ' + JSON.stringify(browser)); + + const socketConfig: UserFacingSocketConfig = { + auth: { + creds: this.instance.authState.state.creds, + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + }, + logger: P({ level: this.logBaileys }), + printQRInTerminal: false, + browser, + version, + markOnlineOnConnect: this.localSettings.always_online, + connectTimeoutMs: 60_000, + qrTimeout: 40_000, + defaultQueryTimeoutMs: undefined, + emitOwnEvents: false, + msgRetryCounterCache: this.msgRetryCounterCache, + getMessage: async (key) => (await this.getMessage(key)) as Promise, + generateHighQualityLinkPreview: true, + syncFullHistory: true, + userDevicesCache: this.userDevicesCache, + transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, + patchMessageBeforeSending: (message) => { + const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); + if (requiresPatch) { + message = { + viewOnceMessageV2: { + message: { + messageContextInfo: { + deviceListMetadataVersion: 2, + deviceListMetadata: {}, + }, + ...message, + }, + }, + }; + } + + return message; }, - }, }; - } - return message; - }, - }; + this.endSession = false; - this.endSession = false; + this.logger.verbose('Creating socket'); - this.logger.verbose('Creating socket'); + this.client = makeWASocket(socketConfig); - this.client = makeWASocket(socketConfig); + this.logger.verbose('Socket created'); - this.logger.verbose('Socket created'); + this.eventHandler(); - this.eventHandler(); + this.logger.verbose('Socket event handler initialized'); - this.logger.verbose('Socket event handler initialized'); + this.phoneNumber = number; - this.phoneNumber = number; - - return this.client; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString()); + return this.client; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString()); + } } - } - private readonly chatHandle = { - 'chats.upsert': async (chats: Chat[], database: Database) => { - this.logger.verbose('Event received: chats.upsert'); + private readonly chatHandle = { + 'chats.upsert': async (chats: Chat[], database: Database) => { + this.logger.verbose('Event received: chats.upsert'); - this.logger.verbose('Finding chats in database'); - const chatsRepository = await this.repository.chat.find({ - where: { owner: this.instance.name }, - }); + this.logger.verbose('Finding chats in database'); + const chatsRepository = await this.repository.chat.find({ + where: { owner: this.instance.name }, + }); - this.logger.verbose('Verifying if chats exists in database to insert'); - const chatsRaw: ChatRaw[] = []; - for await (const chat of chats) { - if (chatsRepository.find((cr) => cr.id === chat.id)) { - continue; - } + this.logger.verbose('Verifying if chats exists in database to insert'); + const chatsRaw: ChatRaw[] = []; + for await (const chat of chats) { + if (chatsRepository.find((cr) => cr.id === chat.id)) { + continue; + } - chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); - } - - this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); - await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); - }, - - 'chats.update': async ( - chats: Partial< - proto.IConversation & { - lastMessageRecvTimestamp?: number; - } & { - conditional: (bufferedData: BufferedEventData) => boolean; - } - >[], - ) => { - this.logger.verbose('Event received: chats.update'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { id: chat.id, owner: this.instance.wuid }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); - await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); - }, - - 'chats.delete': async (chats: string[]) => { - this.logger.verbose('Event received: chats.delete'); - - this.logger.verbose('Deleting chats in database'); - chats.forEach( - async (chat) => - await this.repository.chat.delete({ - where: { owner: this.instance.name, id: chat }, - }), - ); - - this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); - await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); - }, - }; - - private readonly contactHandle = { - 'contacts.upsert': async (contacts: Contact[], database: Database) => { - this.logger.verbose('Event received: contacts.upsert'); - - this.logger.verbose('Finding contacts in database'); - const contactsRepository = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if contacts exists in database to insert'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - if (contactsRepository.find((cr) => cr.id === contact.id)) { - continue; - } - - contactsRaw.push({ - id: contact.id, - pushName: contact?.name || contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); - - this.logger.verbose('Inserting contacts in database'); - await this.repository.contact.insert( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - - 'contacts.update': async (contacts: Partial[], database: Database) => { - this.logger.verbose('Event received: contacts.update'); - - this.logger.verbose('Verifying if contacts exists in database to update'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - contactsRaw.push({ - id: contact.id, - pushName: contact?.name ?? contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); - - this.logger.verbose('Updating contacts in database'); - await this.repository.contact.update( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - }; - - private readonly messageHandle = { - 'messaging-history.set': async ( - { - messages, - chats, - isLatest, - }: { - chats: Chat[]; - contacts: Contact[]; - messages: proto.IWebMessageInfo[]; - isLatest: boolean; - }, - database: Database, - ) => { - this.logger.verbose('Event received: messaging-history.set'); - if (isLatest) { - this.logger.verbose('isLatest defined as true'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { - id: chat.id, - owner: this.instance.name, - lastMsgTimestamp: chat.lastMessageRecvTimestamp, - }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_SET'); - await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); - } - - const messagesRaw: MessageRaw[] = []; - const messagesRepository = await this.repository.message.find({ - where: { owner: this.instance.name }, - }); - for await (const [, m] of Object.entries(messages)) { - if (!m.message) { - continue; - } - if ( - messagesRepository.find( - (mr) => mr.owner === this.instance.name && mr.key.id === m.key.id, - ) - ) { - continue; - } - - if (Long.isLong(m?.messageTimestamp)) { - m.messageTimestamp = m.messageTimestamp?.toNumber(); - } - - messagesRaw.push({ - key: m.key, - pushName: m.pushName, - participant: m.participant, - message: { ...m.message }, - messageType: getContentType(m.message), - messageTimestamp: m.messageTimestamp as number, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); - this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); - - messages = undefined; - }, - - 'messages.upsert': async ( - { - messages, - type, - }: { - messages: proto.IWebMessageInfo[]; - type: MessageUpsertType; - }, - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.upsert'); - const received = messages[0]; - - if ( - type !== 'notify' || - received.message?.protocolMessage || - received.message?.pollUpdateMessage - ) { - this.logger.verbose('message rejected'); - return; - } - - if (Long.isLong(received.messageTimestamp)) { - received.messageTimestamp = received.messageTimestamp?.toNumber(); - } - - if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - - const messageRaw: MessageRaw = { - key: received.key, - pushName: received.pushName, - message: { ...received.message }, - messageType: getContentType(received.message), - messageTimestamp: received.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(received.key.id), - }; - - if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { - await this.client.readMessages([received.key]); - } - - if (this.localSettings.read_status && received.key.id === 'status@broadcast') { - await this.client.readMessages([received.key]); - } - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); - await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, - messageRaw, - ); - } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - database.SAVE_DATA.NEW_MESSAGE, - ); - - this.logger.verbose('Verifying contact from message'); - const contact = await this.repository.contact.find({ - where: { owner: this.instance.name, id: received.key.remoteJid }, - }); - - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: received.pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, - owner: this.instance.name, - }; - - if (contactRaw.id === 'status@broadcast') { - this.logger.verbose('Contact is status@broadcast'); - return; - } - - if (contact?.length) { - this.logger.verbose('Contact found in database'); - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: contact[0].pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, - owner: this.instance.name, - }; - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, - contactRaw, - ); - } - - this.logger.verbose('Updating contact in database'); - await this.repository.contact.update( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - return; - } - - this.logger.verbose('Contact not found in database'); - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); - - this.logger.verbose('Inserting contact in database'); - await this.repository.contact.insert( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); - }, - - 'messages.update': async ( - args: WAMessageUpdate[], - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.update'); - const status: Record = { - 0: 'ERROR', - 1: 'PENDING', - 2: 'SERVER_ACK', - 3: 'DELIVERY_ACK', - 4: 'READ', - 5: 'PLAYED', - }; - for await (const { key, update } of args) { - if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { - this.logger.verbose('Message update is valid'); - - let pollUpdates: any; - if (update.pollUpdates) { - this.logger.verbose('Poll update found'); - - this.logger.verbose('Getting poll message'); - const pollCreation = await this.getMessage(key); - this.logger.verbose(pollCreation); - - if (pollCreation) { - this.logger.verbose('Getting aggregate votes in poll message'); - pollUpdates = getAggregateVotesInPollMessage({ - message: pollCreation as proto.IMessage, - pollUpdates: update.pollUpdates, - }); + chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); } - } - if (status[update.status] === 'READ' && !key.fromMe) return; + this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); + await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); - if (update.message === null && update.status === undefined) { - this.logger.verbose('Message deleted'); + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + }, - this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); - await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + 'chats.update': async ( + chats: Partial< + proto.IConversation & { + lastMessageRecvTimestamp?: number; + } & { + conditional: (bufferedData: BufferedEventData) => boolean; + } + >[], + ) => { + this.logger.verbose('Event received: chats.update'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { id: chat.id, owner: this.instance.wuid }; + }); - const message: MessageUpdateRaw = { - ...key, - status: 'DELETED', - datetime: Date.now(), - owner: this.instance.name, + this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); + await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); + }, + + 'chats.delete': async (chats: string[]) => { + this.logger.verbose('Event received: chats.delete'); + + this.logger.verbose('Deleting chats in database'); + chats.forEach( + async (chat) => + await this.repository.chat.delete({ + where: { owner: this.instance.name, id: chat }, + }), + ); + + this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); + await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); + }, + }; + + private readonly contactHandle = { + 'contacts.upsert': async (contacts: Contact[], database: Database) => { + this.logger.verbose('Event received: contacts.upsert'); + + this.logger.verbose('Finding contacts in database'); + const contactsRepository = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if contacts exists in database to insert'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + if (contactsRepository.find((cr) => cr.id === contact.id)) { + continue; + } + + contactsRaw.push({ + id: contact.id, + pushName: contact?.name || contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); + + this.logger.verbose('Inserting contacts in database'); + await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + + 'contacts.update': async (contacts: Partial[], database: Database) => { + this.logger.verbose('Event received: contacts.update'); + + this.logger.verbose('Verifying if contacts exists in database to update'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + contactsRaw.push({ + id: contact.id, + pushName: contact?.name ?? contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); + + this.logger.verbose('Updating contacts in database'); + await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + }; + + private readonly messageHandle = { + 'messaging-history.set': async ( + { + messages, + chats, + isLatest, + }: { + chats: Chat[]; + contacts: Contact[]; + messages: proto.IWebMessageInfo[]; + isLatest: boolean; + }, + database: Database, + ) => { + this.logger.verbose('Event received: messaging-history.set'); + if (isLatest) { + this.logger.verbose('isLatest defined as true'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { + id: chat.id, + owner: this.instance.name, + lastMsgTimestamp: chat.lastMessageRecvTimestamp, + }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_SET'); + await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + } + + const messagesRaw: MessageRaw[] = []; + const messagesRepository = await this.repository.message.find({ + where: { owner: this.instance.name }, + }); + for await (const [, m] of Object.entries(messages)) { + if (!m.message) { + continue; + } + if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { + continue; + } + + if (Long.isLong(m?.messageTimestamp)) { + m.messageTimestamp = m.messageTimestamp?.toNumber(); + } + + messagesRaw.push({ + key: m.key, + pushName: m.pushName, + participant: m.participant, + message: { ...m.message }, + messageType: getContentType(m.message), + messageTimestamp: m.messageTimestamp as number, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); + this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); + + messages = undefined; + }, + + 'messages.upsert': async ( + { + messages, + type, + }: { + messages: proto.IWebMessageInfo[]; + type: MessageUpsertType; + }, + database: Database, + settings: SettingsRaw, + ) => { + this.logger.verbose('Event received: messages.upsert'); + const received = messages[0]; + + if (type !== 'notify' || received.message?.protocolMessage || received.message?.pollUpdateMessage) { + this.logger.verbose('message rejected'); + return; + } + + if (Long.isLong(received.messageTimestamp)) { + received.messageTimestamp = received.messageTimestamp?.toNumber(); + } + + if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + + const messageRaw: MessageRaw = { + key: received.key, + pushName: received.pushName, + message: { ...received.message }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), }; - this.logger.verbose(message); + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); + await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.MESSAGES_UPSERT, + { instanceName: this.instance.name }, + messageRaw, + ); + } this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - return; - } + await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); - const message: MessageUpdateRaw = { - ...key, - status: status[update.status], - datetime: Date.now(), - owner: this.instance.name, - pollUpdates, - }; - - this.logger.verbose(message); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); - await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - } - } - }, - }; - - private readonly groupHandler = { - 'groups.upsert': (groupMetadata: GroupMetadata[]) => { - this.logger.verbose('Event received: groups.upsert'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); - this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); - }, - - 'groups.update': (groupMetadataUpdate: Partial[]) => { - this.logger.verbose('Event received: groups.update'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); - this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - }, - - 'group-participants.update': (participantsUpdate: { - id: string; - participants: string[]; - action: ParticipantAction; - }) => { - this.logger.verbose('Event received: group-participants.update'); - - this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); - this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - }, - }; - - private eventHandler() { - this.logger.verbose('Initializing event handler'); - this.client.ev.process(async (events) => { - if (!this.endSession) { - const database = this.configService.get('DATABASE'); - const settings = await this.findSettings(); - - if (events.call) { - this.logger.verbose('Listening event: call'); - const call = events.call[0]; - - if (settings?.reject_call && call.status == 'offer') { - this.logger.verbose('Rejecting call'); - this.client.rejectCall(call.id, call.from); - } - - if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { - this.logger.verbose('Sending message in call'); - const msg = await this.client.sendMessage(call.from, { - text: settings.msg_call, + this.logger.verbose('Verifying contact from message'); + const contact = await this.repository.contact.find({ + where: { owner: this.instance.name, id: received.key.remoteJid }, }); - this.logger.verbose('Sending data to event messages.upsert'); - this.client.ev.emit('messages.upsert', { - messages: [msg], - type: 'notify', - }); - } - - this.logger.verbose('Sending data to webhook in event CALL'); - this.sendDataWebhook(Events.CALL, call); - } - - if (events['connection.update']) { - this.logger.verbose('Listening event: connection.update'); - this.connectionUpdate(events['connection.update']); - } - - if (events['creds.update']) { - this.logger.verbose('Listening event: creds.update'); - this.instance.authState.saveCreds(); - } - - if (events['messaging-history.set']) { - this.logger.verbose('Listening event: messaging-history.set'); - const payload = events['messaging-history.set']; - this.messageHandle['messaging-history.set'](payload, database); - } - - if (events['messages.upsert']) { - this.logger.verbose('Listening event: messages.upsert'); - const payload = events['messages.upsert']; - this.messageHandle['messages.upsert'](payload, database, settings); - } - - if (events['messages.update']) { - this.logger.verbose('Listening event: messages.update'); - const payload = events['messages.update']; - this.messageHandle['messages.update'](payload, database, settings); - } - - if (events['presence.update']) { - this.logger.verbose('Listening event: presence.update'); - const payload = events['presence.update']; - - if (settings.groups_ignore && payload.id.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); - } - - if (!settings?.groups_ignore) { - if (events['groups.upsert']) { - this.logger.verbose('Listening event: groups.upsert'); - const payload = events['groups.upsert']; - this.groupHandler['groups.upsert'](payload); - } - - if (events['groups.update']) { - this.logger.verbose('Listening event: groups.update'); - const payload = events['groups.update']; - this.groupHandler['groups.update'](payload); - } - - if (events['group-participants.update']) { - this.logger.verbose('Listening event: group-participants.update'); - const payload = events['group-participants.update']; - this.groupHandler['group-participants.update'](payload); - } - } - - if (events['chats.upsert']) { - this.logger.verbose('Listening event: chats.upsert'); - const payload = events['chats.upsert']; - this.chatHandle['chats.upsert'](payload, database); - } - - if (events['chats.update']) { - this.logger.verbose('Listening event: chats.update'); - const payload = events['chats.update']; - this.chatHandle['chats.update'](payload); - } - - if (events['chats.delete']) { - this.logger.verbose('Listening event: chats.delete'); - const payload = events['chats.delete']; - this.chatHandle['chats.delete'](payload); - } - - if (events['contacts.upsert']) { - this.logger.verbose('Listening event: contacts.upsert'); - const payload = events['contacts.upsert']; - this.contactHandle['contacts.upsert'](payload, database); - } - - if (events['contacts.update']) { - this.logger.verbose('Listening event: contacts.update'); - const payload = events['contacts.update']; - this.contactHandle['contacts.update'](payload, database); - } - } - }); - } - - // Check if the number is MX or AR - private formatMXOrARNumber(jid: string): string { - const countryCode = jid.substring(0, 2); - - if (Number(countryCode) === 52 || Number(countryCode) === 54) { - if (jid.length === 13) { - const number = countryCode + jid.substring(3); - return number; - } - - return jid; - } - return jid; - } - - // Check if the number is br - private formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } - return jid; - } else { - return jid; - } - } - - private createJid(number: string): string { - this.logger.verbose('Creating jid with number: ' + number); - - if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { - this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return number; - } - - if (number.includes('@broadcast')) { - this.logger.verbose('Number already contains @broadcast'); - return number; - } - - number = number - ?.replace(/\s/g, '') - .replace(/\+/g, '') - .replace(/\(/g, '') - .replace(/\)/g, '') - .split(/\:/)[0] - .split('@')[0]; - - if (number.includes('-') && number.length >= 24) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = number.replace(/\D/g, ''); - - if (number.length >= 18) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); - return `${number}@s.whatsapp.net`; - } - - public async profilePicture(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile picture with jid: ' + jid); - try { - this.logger.verbose('Getting profile picture url'); - return { - wuid: jid, - profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), - }; - } catch (error) { - this.logger.verbose('Profile picture not found'); - return { - wuid: jid, - profilePictureUrl: null, - }; - } - } - - public async getStatus(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile status with jid:' + jid); - try { - this.logger.verbose('Getting status'); - return { - wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, - }; - } catch (error) { - this.logger.verbose('Status not found'); - return { - wuid: jid, - status: null, - }; - } - } - - public async fetchProfile(instanceName: string, number?: string) { - const jid = number ? this.createJid(number) : this.client?.user?.id; - - this.logger.verbose('Getting profile with jid: ' + jid); - try { - this.logger.verbose('Getting profile info'); - const info = await waMonitor.instanceInfo(instanceName); - const business = await this.fetchBusinessProfile(jid); - - if (number) { - const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); - const picture = await this.profilePicture(jid); - const status = await this.getStatus(jid); - - return { - wuid: jid, - name: info?.name, - numberExists: info?.exists, - picture: picture?.profilePictureUrl, - status: status?.status, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } else { - const info = await waMonitor.instanceInfo(instanceName); - - return { - wuid: jid, - name: info?.instance?.profileName, - numberExists: true, - picture: info?.instance?.profilePictureUrl, - status: info?.instance?.profileStatus, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } - } catch (error) { - this.logger.verbose('Profile not found'); - return { - wuid: jid, - name: null, - picture: null, - status: null, - os: null, - isBusiness: false, - }; - } - } - - private async sendMessageWithTyping( - number: string, - message: T, - options?: Options, - ) { - this.logger.verbose('Sending message with typing'); - - const numberWA = await this.whatsappNumber({ numbers: [number] }); - const isWA = numberWA[0]; - - if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { - throw new BadRequestException(isWA); - } - - const sender = isWA.jid; - - try { - if (options?.delay) { - this.logger.verbose('Delaying message'); - - await this.client.presenceSubscribe(sender); - this.logger.verbose('Subscribing to presence'); - - await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); - this.logger.verbose( - 'Sending presence update: ' + options?.presence ?? 'composing', - ); - - await delay(options.delay); - this.logger.verbose('Set delay: ' + options.delay); - - await this.client.sendPresenceUpdate('paused', sender); - this.logger.verbose('Sending presence update: paused'); - } - - const linkPreview = options?.linkPreview != false ? undefined : false; - - let quoted: WAMessage; - - if (options?.quoted) { - const m = options?.quoted; - - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - quoted = msg; - this.logger.verbose('Quoted message'); - } - - let mentions: string[]; - if (isJidGroup(sender)) { - try { - const groupMetadata = await this.client.groupMetadata(sender); - - if (!groupMetadata) { - throw new NotFoundException('Group not found'); - } - - if (options?.mentions) { - this.logger.verbose('Mentions defined'); - - if (options.mentions?.everyOne) { - this.logger.verbose('Mentions everyone'); - - this.logger.verbose('Getting group metadata'); - mentions = groupMetadata.participants.map((participant) => participant.id); - this.logger.verbose('Getting group metadata for mentions'); - } else if (options.mentions?.mentioned?.length) { - this.logger.verbose('Mentions manually defined'); - mentions = options.mentions.mentioned.map((mention) => { - const jid = this.createJid(mention); - if (isJidGroup(jid)) { - return null; - // throw new BadRequestException('Mentions must be a number'); - } - return jid; - }); - } - } - } catch (error) { - throw new NotFoundException('Group not found'); - } - } - - const messageSent = await (async () => { - const option = { - quoted, - }; - - if ( - !message['audio'] && - !message['poll'] && - !message['sticker'] && - !message['conversation'] && - sender !== 'status@broadcast' - ) { - if (!message['audio']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - forward: { - key: { remoteJid: this.instance.wuid, fromMe: true }, - message, - }, - mentions, - }, - option as unknown as MiscMessageGenerationOptions, - ); - } - } - - if (message['conversation']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - text: message['conversation'], - mentions, - linkPreview: linkPreview, - } as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - } - - if (sender === 'status@broadcast') { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message['status'].content as unknown as AnyMessageContent, - { - backgroundColor: message['status'].option.backgroundColor, - font: message['status'].option.font, - statusJidList: message['status'].option.statusJidList, - } as unknown as MiscMessageGenerationOptions, - ); - } - - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - })(); - - const messageRaw: MessageRaw = { - key: messageSent.key, - pushName: messageSent.pushName, - message: { ...messageSent.message }, - messageType: getContentType(messageSent.message), - messageTimestamp: messageSent.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(messageSent.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); - await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - - // if (this.localChatwoot.enabled) { - // this.chatwootService.eventWhatsapp( - // Events.SEND_MESSAGE, - // { instanceName: this.instance.name }, - // messageRaw, - // ); - // } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, - ); - - return messageSent; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - // Instance Controller - public get connectionStatus() { - this.logger.verbose('Getting connection status'); - return this.stateConnection; - } - - // Send Message Controller - public async textMessage(data: SendTextDto) { - this.logger.verbose('Sending text message'); - return await this.sendMessageWithTyping( - data.number, - { - conversation: data.textMessage.text, - }, - data?.options, - ); - } - - public async pollMessage(data: SendPollDto) { - this.logger.verbose('Sending poll message'); - return await this.sendMessageWithTyping( - data.number, - { - poll: { - name: data.pollMessage.name, - selectableCount: data.pollMessage.selectableCount, - values: data.pollMessage.values, - }, - }, - data?.options, - ); - } - - private async formatStatusMessage(status: StatusMessage) { - this.logger.verbose('Formatting status message'); - - if (!status.type) { - throw new BadRequestException('Type is required'); - } - - if (!status.content) { - throw new BadRequestException('Content is required'); - } - - if (status.allContacts) { - this.logger.verbose('All contacts defined as true'); - - this.logger.verbose('Getting contacts from database'); - const contacts = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - if (!contacts.length) { - throw new BadRequestException('Contacts not found'); - } - - this.logger.verbose('Getting contacts with push name'); - status.statusJidList = contacts - .filter((contact) => contact.pushName) - .map((contact) => contact.id); - - this.logger.verbose(status.statusJidList); - } - - if (!status.statusJidList?.length && !status.allContacts) { - throw new BadRequestException('StatusJidList is required'); - } - - if (status.type === 'text') { - this.logger.verbose('Type defined as text'); - - if (!status.backgroundColor) { - throw new BadRequestException('Background color is required'); - } - - if (!status.font) { - throw new BadRequestException('Font is required'); - } - - return { - content: { - text: status.content, - }, - option: { - backgroundColor: status.backgroundColor, - font: status.font, - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'image') { - this.logger.verbose('Type defined as image'); - - return { - content: { - image: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'video') { - this.logger.verbose('Type defined as video'); - - return { - content: { - video: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'audio') { - this.logger.verbose('Type defined as audio'); - - this.logger.verbose('Processing audio'); - const convert = await this.processAudio(status.content, 'status@broadcast'); - if (typeof convert === 'string') { - this.logger.verbose('Audio processed'); - const audio = fs.readFileSync(convert).toString('base64'); - - const result = { - content: { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - option: { - statusJidList: status.statusJidList, - }, - }; - - fs.unlinkSync(convert); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - throw new BadRequestException('Type not found'); - } - - public async statusMessage(data: SendStatusDto) { - this.logger.verbose('Sending status message'); - const status = await this.formatStatusMessage(data.statusMessage); - - return await this.sendMessageWithTyping('status@broadcast', { - status, - }); - } - - private async prepareMediaMessage(mediaMessage: MediaMessage) { - try { - this.logger.verbose('Preparing media message'); - const prepareMedia = await prepareWAMessageMedia( - { - [mediaMessage.mediatype]: isURL(mediaMessage.media) - ? { url: mediaMessage.media } - : Buffer.from(mediaMessage.media, 'base64'), - } as any, - { upload: this.client.waUploadToServer }, - ); - - const mediaType = mediaMessage.mediatype + 'Message'; - this.logger.verbose('Media type: ' + mediaType); - - if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { - this.logger.verbose( - 'If media type is document and file name is not defined then', - ); - const regex = new RegExp(/.*\/(.+?)\./); - const arrayMatch = regex.exec(mediaMessage.media); - mediaMessage.fileName = arrayMatch[1]; - this.logger.verbose('File name: ' + mediaMessage.fileName); - } - - let mimetype: string; - - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); - } else { - mimetype = getMIMEType(mediaMessage.fileName); - } - - this.logger.verbose('Mimetype: ' + mimetype); - - prepareMedia[mediaType].caption = mediaMessage?.caption; - prepareMedia[mediaType].mimetype = mimetype; - prepareMedia[mediaType].fileName = mediaMessage.fileName; - - if (mediaMessage.mediatype === 'video') { - this.logger.verbose('Is media type video then set gif playback as false'); - prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( - readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), - ); - prepareMedia[mediaType].gifPlayback = false; - } - - this.logger.verbose('Generating wa message from content'); - return generateWAMessageFromContent( - '', - { [mediaType]: { ...prepareMedia[mediaType] } }, - { userJid: this.instance.wuid }, - ); - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString() || error); - } - } - - private async convertToWebP(image: string, number: string) { - try { - this.logger.verbose('Converting image to WebP to sticker'); - - let imagePath: string; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to image name: ' + hash); - - const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; - this.logger.verbose('Output path: ' + outputPath); - - if (isBase64(image)) { - this.logger.verbose('Image is base64'); - - const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); - const imageBuffer = Buffer.from(base64Data, 'base64'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } else { - this.logger.verbose('Image is url'); - - const timestamp = new Date().getTime(); - const url = `${image}?timestamp=${timestamp}`; - this.logger.verbose('including timestamp in url: ' + url); - - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting image from url'); - - const imageBuffer = Buffer.from(response.data, 'binary'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } - - await sharp(imagePath).webp().toFile(outputPath); - this.logger.verbose('Image converted to WebP'); - - fs.unlinkSync(imagePath); - this.logger.verbose('Temp image deleted'); - - return outputPath; - } catch (error) { - console.error('Erro ao converter a imagem para WebP:', error); - } - } - - public async mediaSticker(data: SendStickerDto) { - this.logger.verbose('Sending media sticker'); - const convert = await this.convertToWebP(data.stickerMessage.image, data.number); - const result = await this.sendMessageWithTyping( - data.number, - { - sticker: { url: convert }, - }, - data?.options, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted image deleted'); - - return result; - } - - public async mediaMessage(data: SendMediaDto) { - this.logger.verbose('Sending media message'); - const generate = await this.prepareMediaMessage(data.mediaMessage); - - return await this.sendMessageWithTyping( - data.number, - { ...generate.message }, - data?.options, - ); - } - - private async processAudio(audio: string, number: string) { - this.logger.verbose('Processing audio'); - let tempAudioPath: string; - let outputAudio: string; - - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to audio name: ' + hash); - - if (isURL(audio)) { - this.logger.verbose('Audio is url'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const timestamp = new Date().getTime(); - const url = `${audio}?timestamp=${timestamp}`; - - this.logger.verbose('Including timestamp in url: ' + url); - - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting audio from url'); - - fs.writeFileSync(tempAudioPath, response.data); - } else { - this.logger.verbose('Audio is base64'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const audioBuffer = Buffer.from(audio, 'base64'); - fs.writeFileSync(tempAudioPath, audioBuffer); - this.logger.verbose('Temp audio created'); - } - - this.logger.verbose('Converting audio to mp4'); - return new Promise((resolve, reject) => { - exec( - `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, - (error, _stdout, _stderr) => { - fs.unlinkSync(tempAudioPath); - this.logger.verbose('Temp audio deleted'); - - if (error) reject(error); - - this.logger.verbose('Audio converted to mp4'); - resolve(outputAudio); - }, - ); - }); - } - - public async audioWhatsapp(data: SendAudioDto) { - this.logger.verbose('Sending audio whatsapp'); - - if (!data.options?.encoding && data.options?.encoding !== false) { - data.options.encoding = true; - } - - if (data.options?.encoding) { - const convert = await this.processAudio(data.audioMessage.audio, data.number); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - const result = this.sendMessageWithTyping( - data.number, - { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - return await this.sendMessageWithTyping( - data.number, - { - audio: isURL(data.audioMessage.audio) - ? { url: data.audioMessage.audio } - : Buffer.from(data.audioMessage.audio, 'base64'), - ptt: true, - mimetype: 'audio/ogg; codecs=opus', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - } - - public async buttonMessage(data: SendButtonDto) { - this.logger.verbose('Sending button message'); - const embeddedMedia: any = {}; - let mediatype = 'TEXT'; - - if (data.buttonMessage?.mediaMessage) { - mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; - embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; - const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); - embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; - embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; - } - - const btnItems = { - text: data.buttonMessage.buttons.map((btn) => btn.buttonText), - ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), - }; - - if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { - throw new BadRequestException( - 'Button texts cannot be repeated', - 'Button IDs cannot be repeated.', - ); - } - - return await this.sendMessageWithTyping( - data.number, - { - buttonsMessage: { - text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, - contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, - footerText: data.buttonMessage?.footerText, - buttons: data.buttonMessage.buttons.map((button) => { - return { - buttonText: { - displayText: button.buttonText, - }, - buttonId: button.buttonId, - type: 1, + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: received.pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, }; - }), - headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], - [embeddedMedia?.mediaKey]: embeddedMedia?.message, + + if (contactRaw.id === 'status@broadcast') { + this.logger.verbose('Contact is status@broadcast'); + return; + } + + if (contact?.length) { + this.logger.verbose('Contact found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: contact[0].pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.CONTACTS_UPDATE, + { instanceName: this.instance.name }, + contactRaw, + ); + } + + this.logger.verbose('Updating contact in database'); + await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); + return; + } + + this.logger.verbose('Contact not found in database'); + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); + + this.logger.verbose('Inserting contact in database'); + await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); }, - }, - data?.options, - ); - } - public async locationMessage(data: SendLocationDto) { - this.logger.verbose('Sending location message'); - return await this.sendMessageWithTyping( - data.number, - { - locationMessage: { - degreesLatitude: data.locationMessage.latitude, - degreesLongitude: data.locationMessage.longitude, - name: data.locationMessage?.name, - address: data.locationMessage?.address, + 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { + this.logger.verbose('Event received: messages.update'); + const status: Record = { + 0: 'ERROR', + 1: 'PENDING', + 2: 'SERVER_ACK', + 3: 'DELIVERY_ACK', + 4: 'READ', + 5: 'PLAYED', + }; + for await (const { key, update } of args) { + if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { + this.logger.verbose('Message update is valid'); + + let pollUpdates: any; + if (update.pollUpdates) { + this.logger.verbose('Poll update found'); + + this.logger.verbose('Getting poll message'); + const pollCreation = await this.getMessage(key); + this.logger.verbose(pollCreation); + + if (pollCreation) { + this.logger.verbose('Getting aggregate votes in poll message'); + pollUpdates = getAggregateVotesInPollMessage({ + message: pollCreation as proto.IMessage, + pollUpdates: update.pollUpdates, + }); + } + } + + if (status[update.status] === 'READ' && !key.fromMe) return; + + if (update.message === null && update.status === undefined) { + this.logger.verbose('Message deleted'); + + this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); + await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + + const message: MessageUpdateRaw = { + ...key, + status: 'DELETED', + datetime: Date.now(), + owner: this.instance.name, + }; + + this.logger.verbose(message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + return; + } + + const message: MessageUpdateRaw = { + ...key, + status: status[update.status], + datetime: Date.now(), + owner: this.instance.name, + pollUpdates, + }; + + this.logger.verbose(message); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); + await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + } + } }, - }, - data?.options, - ); - } - - public async listMessage(data: SendListDto) { - this.logger.verbose('Sending list message'); - return await this.sendMessageWithTyping( - data.number, - { - listMessage: { - title: data.listMessage.title, - description: data.listMessage.description, - buttonText: data.listMessage?.buttonText, - footerText: data.listMessage?.footerText, - sections: data.listMessage.sections, - listType: 1, - }, - }, - data?.options, - ); - } - - public async contactMessage(data: SendContactDto) { - this.logger.verbose('Sending contact message'); - const message: proto.IMessage = {}; - - const vcard = (contact: ContactMessage) => { - this.logger.verbose('Creating vcard'); - let result = - 'BEGIN:VCARD\n' + - 'VERSION:3.0\n' + - `N:${contact.fullName}\n` + - `FN:${contact.fullName}\n`; - - if (contact.organization) { - this.logger.verbose('Organization defined'); - result += `ORG:${contact.organization};\n`; - } - - if (contact.email) { - this.logger.verbose('Email defined'); - result += `EMAIL:${contact.email}\n`; - } - - if (contact.url) { - this.logger.verbose('Url defined'); - result += `URL:${contact.url}\n`; - } - - if (!contact.wuid) { - this.logger.verbose('Wuid defined'); - contact.wuid = this.createJid(contact.phoneNumber); - } - - result += - `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + - 'item1.X-ABLabel:Celular\n' + - 'END:VCARD'; - - this.logger.verbose('Vcard created'); - return result; }; - if (data.contactMessage.length === 1) { - message.contactMessage = { - displayName: data.contactMessage[0].fullName, - vcard: vcard(data.contactMessage[0]), - }; - } else { - message.contactsArrayMessage = { - displayName: `${data.contactMessage.length} contacts`, - contacts: data.contactMessage.map((contact) => { - return { - displayName: contact.fullName, - vcard: vcard(contact), - }; - }), - }; - } + private readonly groupHandler = { + 'groups.upsert': (groupMetadata: GroupMetadata[]) => { + this.logger.verbose('Event received: groups.upsert'); - return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); - } - - public async reactionMessage(data: SendReactionDto) { - this.logger.verbose('Sending reaction message'); - return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { - reactionMessage: { - key: data.reactionMessage.key, - text: data.reactionMessage.reaction, - }, - }); - } - - // Chat Controller - public async whatsappNumber(data: WhatsAppNumberDto) { - this.logger.verbose('Getting whatsapp number'); - - const onWhatsapp: OnWhatsAppDto[] = []; - for await (const number of data.numbers) { - let jid = this.createJid(number); - - if (isJidGroup(jid)) { - const group = await this.findGroup({ groupJid: jid }, 'inner'); - - if (!group) throw new BadRequestException('Group not found'); - - onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); - } else { - jid = !jid.startsWith('+') ? `+${jid}` : jid; - const verify = await this.client.onWhatsApp(jid); - - const result = verify[0]; - - if (!result) { - onWhatsapp.push(new OnWhatsAppDto(jid, false)); - } else { - onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); - } - } - } - - return onWhatsapp; - } - - public async markMessageAsRead(data: ReadMessageDto) { - this.logger.verbose('Marking message as read'); - try { - const keys: proto.IMessageKey[] = []; - data.read_messages.forEach((read) => { - if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { - keys.push({ - remoteJid: read.remoteJid, - fromMe: read.fromMe, - id: read.id, - }); - } - }); - await this.client.readMessages(keys); - return { message: 'Read messages', read: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Read messages fail', error.toString()); - } - } - - public async archiveChat(data: ArchiveChatDto) { - this.logger.verbose('Archiving chat'); - try { - data.lastMessage.messageTimestamp = - data.lastMessage?.messageTimestamp ?? Date.now(); - await this.client.chatModify( - { - archive: data.archive, - lastMessages: [data.lastMessage], + this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); + this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); }, - data.lastMessage.key.remoteJid, - ); - return { - chatId: data.lastMessage.key.remoteJid, - archived: true, - }; - } catch (error) { - throw new InternalServerErrorException({ - archived: false, - message: [ - 'An error occurred while archiving the chat. Open a calling.', - error.toString(), - ], - }); - } - } + 'groups.update': (groupMetadataUpdate: Partial[]) => { + this.logger.verbose('Event received: groups.update'); - public async deleteMessage(del: DeleteMessage) { - this.logger.verbose('Deleting message'); - try { - return await this.client.sendMessage(del.remoteJid, { delete: del }); - } catch (error) { - throw new InternalServerErrorException( - 'Error while deleting message for everyone', - error?.toString(), - ); - } - } - - public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { - this.logger.verbose('Getting base64 from media message'); - try { - const m = data?.message; - const convertToMp4 = data?.convertToMp4 ?? false; - - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - for (const subtype of MessageSubtype) { - if (msg.message[subtype]) { - msg.message = msg.message[subtype].message; - } - } - - let mediaMessage: any; - let mediaType: string; - - for (const type of TypeMediaMessage) { - mediaMessage = msg.message[type]; - if (mediaMessage) { - mediaType = type; - break; - } - } - - if (!mediaMessage) { - throw 'The message is not of the media type'; - } - - if (typeof mediaMessage['mediaKey'] === 'object') { - msg.message = JSON.parse(JSON.stringify(msg.message)); - } - - this.logger.verbose('Downloading media message'); - const buffer = await downloadMediaMessage( - { key: msg?.key, message: msg?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }), - reuploadRequest: this.client.updateMediaMessage, + this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); + this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); }, - ); - const typeMessage = getContentType(msg.message); - if (convertToMp4 && typeMessage === 'audioMessage') { - this.logger.verbose('Converting audio to mp4'); - const number = msg.key.remoteJid.split('@')[0]; - const convert = await this.processAudio(buffer.toString('base64'), number); + 'group-participants.update': (participantsUpdate: { + id: string; + participants: string[]; + action: ParticipantAction; + }) => { + this.logger.verbose('Event received: group-participants.update'); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - this.logger.verbose('Audio converted to mp4'); - - const result = { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: 'audio/mp4', - base64: Buffer.from(audio, 'base64').toString('base64'), - }; - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - this.logger.verbose('Media message downloaded'); - return result; - } - } - - this.logger.verbose('Media message downloaded'); - return { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], + this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); + this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); }, - mimetype: mediaMessage['mimetype'], - base64: buffer.toString('base64'), - }; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } + }; - public async fetchContacts(query: ContactQuery) { - this.logger.verbose('Fetching contacts'); - if (query?.where) { - query.where.owner = this.instance.name; - if (query.where?.id) { - query.where.id = this.createJid(query.where.id); - } - } else { - query = { - where: { - owner: this.instance.name, - }, - }; - } - return await this.repository.contact.find(query); - } + private eventHandler() { + this.logger.verbose('Initializing event handler'); + this.client.ev.process(async (events) => { + if (!this.endSession) { + const database = this.configService.get('DATABASE'); + const settings = await this.findSettings(); - public async fetchMessages(query: MessageQuery) { - this.logger.verbose('Fetching messages'); - if (query?.where) { - if (query.where?.key?.remoteJid) { - query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.message.find(query); - } + if (events.call) { + this.logger.verbose('Listening event: call'); + const call = events.call[0]; - public async fetchStatusMessage(query: MessageUpQuery) { - this.logger.verbose('Fetching status messages'); - if (query?.where) { - if (query.where?.remoteJid) { - query.where.remoteJid = this.createJid(query.where.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.messageUpdate.find(query); - } + if (settings?.reject_call && call.status == 'offer') { + this.logger.verbose('Rejecting call'); + this.client.rejectCall(call.id, call.from); + } - public async fetchChats() { - this.logger.verbose('Fetching chats'); - return await this.repository.chat.find({ where: { owner: this.instance.name } }); - } + if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { + this.logger.verbose('Sending message in call'); + const msg = await this.client.sendMessage(call.from, { + text: settings.msg_call, + }); - public async fetchPrivacySettings() { - this.logger.verbose('Fetching privacy settings'); - return await this.client.fetchPrivacySettings(); - } + this.logger.verbose('Sending data to event messages.upsert'); + this.client.ev.emit('messages.upsert', { + messages: [msg], + type: 'notify', + }); + } - public async updatePrivacySettings(settings: PrivacySettingDto) { - this.logger.verbose('Updating privacy settings'); - try { - await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); - this.logger.verbose('Read receipts privacy updated'); + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); + } - await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); - this.logger.verbose('Profile picture privacy updated'); + if (events['connection.update']) { + this.logger.verbose('Listening event: connection.update'); + this.connectionUpdate(events['connection.update']); + } - await this.client.updateStatusPrivacy(settings.privacySettings.status); - this.logger.verbose('Status privacy updated'); + if (events['creds.update']) { + this.logger.verbose('Listening event: creds.update'); + this.instance.authState.saveCreds(); + } - await this.client.updateOnlinePrivacy(settings.privacySettings.online); - this.logger.verbose('Online privacy updated'); + if (events['messaging-history.set']) { + this.logger.verbose('Listening event: messaging-history.set'); + const payload = events['messaging-history.set']; + this.messageHandle['messaging-history.set'](payload, database); + } - await this.client.updateLastSeenPrivacy(settings.privacySettings.last); - this.logger.verbose('Last seen privacy updated'); + if (events['messages.upsert']) { + this.logger.verbose('Listening event: messages.upsert'); + const payload = events['messages.upsert']; + this.messageHandle['messages.upsert'](payload, database, settings); + } - await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); - this.logger.verbose('Groups add privacy updated'); + if (events['messages.update']) { + this.logger.verbose('Listening event: messages.update'); + const payload = events['messages.update']; + this.messageHandle['messages.update'](payload, database, settings); + } - this.client?.ws?.close(); + if (events['presence.update']) { + this.logger.verbose('Listening event: presence.update'); + const payload = events['presence.update']; - return { - update: 'success', - data: { - readreceipts: settings.privacySettings.readreceipts, - profile: settings.privacySettings.profile, - status: settings.privacySettings.status, - online: settings.privacySettings.online, - last: settings.privacySettings.last, - groupadd: settings.privacySettings.groupadd, - }, - }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating privacy settings', - error.toString(), - ); - } - } + if (settings.groups_ignore && payload.id.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); + } - public async fetchBusinessProfile(number: string): Promise { - this.logger.verbose('Fetching business profile'); - try { - const jid = number ? this.createJid(number) : this.instance.wuid; + if (!settings?.groups_ignore) { + if (events['groups.upsert']) { + this.logger.verbose('Listening event: groups.upsert'); + const payload = events['groups.upsert']; + this.groupHandler['groups.upsert'](payload); + } - const profile = await this.client.getBusinessProfile(jid); - this.logger.verbose('Trying to get business profile'); + if (events['groups.update']) { + this.logger.verbose('Listening event: groups.update'); + const payload = events['groups.update']; + this.groupHandler['groups.update'](payload); + } - if (!profile) { - const info = await this.whatsappNumber({ numbers: [jid] }); + if (events['group-participants.update']) { + this.logger.verbose('Listening event: group-participants.update'); + const payload = events['group-participants.update']; + this.groupHandler['group-participants.update'](payload); + } + } - return { - isBusiness: false, - message: 'Not is business profile', - ...info?.shift(), - }; - } + if (events['chats.upsert']) { + this.logger.verbose('Listening event: chats.upsert'); + const payload = events['chats.upsert']; + this.chatHandle['chats.upsert'](payload, database); + } - this.logger.verbose('Business profile fetched'); - return { - isBusiness: true, - ...profile, - }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); - } - } + if (events['chats.update']) { + this.logger.verbose('Listening event: chats.update'); + const payload = events['chats.update']; + this.chatHandle['chats.update'](payload); + } - public async updateProfileName(name: string) { - this.logger.verbose('Updating profile name to ' + name); - try { - await this.client.updateProfileName(name); + if (events['chats.delete']) { + this.logger.verbose('Listening event: chats.delete'); + const payload = events['chats.delete']; + this.chatHandle['chats.delete'](payload); + } - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); - } - } + if (events['contacts.upsert']) { + this.logger.verbose('Listening event: contacts.upsert'); + const payload = events['contacts.upsert']; + this.contactHandle['contacts.upsert'](payload, database); + } - public async updateProfileStatus(status: string) { - this.logger.verbose('Updating profile status to: ' + status); - try { - await this.client.updateProfileStatus(status); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile status', - error.toString(), - ); - } - } - - public async updateProfilePicture(picture: string) { - this.logger.verbose('Updating profile picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(this.instance.wuid, pic); - this.logger.verbose('Profile picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile picture', - error.toString(), - ); - } - } - - public async removeProfilePicture() { - this.logger.verbose('Removing profile picture'); - try { - await this.client.removeProfilePicture(this.instance.wuid); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error removing profile picture', - error.toString(), - ); - } - } - - // Group - public async createGroup(create: CreateGroupDto) { - this.logger.verbose('Creating group: ' + create.subject); - try { - const participants = create.participants.map((p) => this.createJid(p)); - const { id } = await this.client.groupCreate(create.subject, participants); - this.logger.verbose('Group created: ' + id); - - if (create?.description) { - this.logger.verbose('Updating group description: ' + create.description); - await this.client.groupUpdateDescription(id, create.description); - } - - if (create?.promoteParticipants) { - this.logger.verbose('Prometing group participants: ' + create.description); - await this.updateGParticipant({ - groupJid: id, - action: 'promote', - participants: participants, + if (events['contacts.update']) { + this.logger.verbose('Listening event: contacts.update'); + const payload = events['contacts.update']; + this.contactHandle['contacts.update'](payload, database); + } + } }); - } - - const group = await this.client.groupMetadata(id); - this.logger.verbose('Getting group metadata'); - - return group; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException('Error creating group', error.toString()); } - } - public async updateGroupPicture(picture: GroupPictureDto) { - this.logger.verbose('Updating group picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture.image)) { - this.logger.verbose('Picture is url'); + // Check if the number is MX or AR + private formatMXOrARNumber(jid: string): string { + const countryCode = jid.substring(0, 2); - const timestamp = new Date().getTime(); - const url = `${picture.image}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; + } - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture.image)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture.image, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(picture.groupJid, pic); - this.logger.verbose('Group picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error update group picture', - error.toString(), - ); - } - } - - public async updateGroupSubject(data: GroupSubjectDto) { - this.logger.verbose('Updating group subject to: ' + data.subject); - try { - await this.client.groupUpdateSubject(data.groupJid, data.subject); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating group subject', - error.toString(), - ); - } - } - - public async updateGroupDescription(data: GroupDescriptionDto) { - this.logger.verbose('Updating group description to: ' + data.description); - try { - await this.client.groupUpdateDescription(data.groupJid, data.description); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException( - 'Error updating group description', - error.toString(), - ); - } - } - - public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { - this.logger.verbose('Fetching group'); - try { - return await this.client.groupMetadata(id.groupJid); - } catch (error) { - if (reply === 'inner') { - return; - } - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async fetchAllGroups(getParticipants: GetParticipant) { - this.logger.verbose('Fetching all groups'); - try { - const fetch = Object.values(await this.client.groupFetchAllParticipating()); - - const groups = fetch.map((group) => { - const result = { - id: group.id, - subject: group.subject, - subjectOwner: group.subjectOwner, - subjectTime: group.subjectTime, - size: group.size, - creation: group.creation, - owner: group.owner, - desc: group.desc, - descId: group.descId, - restrict: group.restrict, - announce: group.announce, - }; - - if (getParticipants.getParticipants == 'true') { - result['participants'] = group.participants; + return jid; } + return jid; + } + + // Check if the number is br + private formatBRNumber(jid: string) { + const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); + if (regexp.test(jid)) { + const match = regexp.exec(jid); + if (match && match[1] === '55') { + const joker = Number.parseInt(match[3][0]); + const ddd = Number.parseInt(match[2]); + if (joker < 7 || ddd < 31) { + return match[0]; + } + return match[1] + match[2] + match[3]; + } + return jid; + } else { + return jid; + } + } + + private createJid(number: string): string { + this.logger.verbose('Creating jid with number: ' + number); + + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { + this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); + return number; + } + + if (number.includes('@broadcast')) { + this.logger.verbose('Number already contains @broadcast'); + return number; + } + + number = number + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(':')[0] + .split('@')[0]; + + if (number.includes('-') && number.length >= 24) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = number.replace(/\D/g, ''); + + if (number.length >= 18) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); + return `${number}@s.whatsapp.net`; + } + + public async profilePicture(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile picture with jid: ' + jid); + try { + this.logger.verbose('Getting profile picture url'); + return { + wuid: jid, + profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), + }; + } catch (error) { + this.logger.verbose('Profile picture not found'); + return { + wuid: jid, + profilePictureUrl: null, + }; + } + } + + public async getStatus(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile status with jid:' + jid); + try { + this.logger.verbose('Getting status'); + return { + wuid: jid, + status: (await this.client.fetchStatus(jid))?.status, + }; + } catch (error) { + this.logger.verbose('Status not found'); + return { + wuid: jid, + status: null, + }; + } + } + + public async fetchProfile(instanceName: string, number?: string) { + const jid = number ? this.createJid(number) : this.client?.user?.id; + + this.logger.verbose('Getting profile with jid: ' + jid); + try { + this.logger.verbose('Getting profile info'); + const business = await this.fetchBusinessProfile(jid); + + if (number) { + const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); + const picture = await this.profilePicture(jid); + const status = await this.getStatus(jid); + + return { + wuid: jid, + name: info?.name, + numberExists: info?.exists, + picture: picture?.profilePictureUrl, + status: status?.status, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } else { + const info = await waMonitor.instanceInfo(instanceName); + + return { + wuid: jid, + name: info?.instance?.profileName, + numberExists: true, + picture: info?.instance?.profilePictureUrl, + status: info?.instance?.profileStatus, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } + } catch (error) { + this.logger.verbose('Profile not found'); + return { + wuid: jid, + name: null, + picture: null, + status: null, + os: null, + isBusiness: false, + }; + } + } + + private async sendMessageWithTyping(number: string, message: T, options?: Options) { + this.logger.verbose('Sending message with typing'); + + const numberWA = await this.whatsappNumber({ numbers: [number] }); + const isWA = numberWA[0]; + + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { + throw new BadRequestException(isWA); + } + + const sender = isWA.jid; + + try { + if (options?.delay) { + this.logger.verbose('Delaying message'); + + await this.client.presenceSubscribe(sender); + this.logger.verbose('Subscribing to presence'); + + await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); + this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); + + await delay(options.delay); + this.logger.verbose('Set delay: ' + options.delay); + + await this.client.sendPresenceUpdate('paused', sender); + this.logger.verbose('Sending presence update: paused'); + } + + const linkPreview = options?.linkPreview != false ? undefined : false; + + let quoted: WAMessage; + + if (options?.quoted) { + const m = options?.quoted; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + quoted = msg; + this.logger.verbose('Quoted message'); + } + + let mentions: string[]; + if (isJidGroup(sender)) { + try { + const groupMetadata = await this.client.groupMetadata(sender); + + if (!groupMetadata) { + throw new NotFoundException('Group not found'); + } + + if (options?.mentions) { + this.logger.verbose('Mentions defined'); + + if (options.mentions?.everyOne) { + this.logger.verbose('Mentions everyone'); + + this.logger.verbose('Getting group metadata'); + mentions = groupMetadata.participants.map((participant) => participant.id); + this.logger.verbose('Getting group metadata for mentions'); + } else if (options.mentions?.mentioned?.length) { + this.logger.verbose('Mentions manually defined'); + mentions = options.mentions.mentioned.map((mention) => { + const jid = this.createJid(mention); + if (isJidGroup(jid)) { + return null; + // throw new BadRequestException('Mentions must be a number'); + } + return jid; + }); + } + } + } catch (error) { + throw new NotFoundException('Group not found'); + } + } + + const messageSent = await (async () => { + const option = { + quoted, + }; + + if ( + !message['audio'] && + !message['poll'] && + !message['sticker'] && + !message['conversation'] && + sender !== 'status@broadcast' + ) { + if (!message['audio']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + forward: { + key: { remoteJid: this.instance.wuid, fromMe: true }, + message, + }, + mentions, + }, + option as unknown as MiscMessageGenerationOptions, + ); + } + } + + if (message['conversation']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + text: message['conversation'], + mentions, + linkPreview: linkPreview, + } as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + } + + if (sender === 'status@broadcast') { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message['status'].content as unknown as AnyMessageContent, + { + backgroundColor: message['status'].option.backgroundColor, + font: message['status'].option.font, + statusJidList: message['status'].option.statusJidList, + } as unknown as MiscMessageGenerationOptions, + ); + } + + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + })(); + + const messageRaw: MessageRaw = { + key: messageSent.key, + pushName: messageSent.pushName, + message: { ...messageSent.message }, + messageType: getContentType(messageSent.message), + messageTimestamp: messageSent.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(messageSent.key.id), + }; + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); + await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); + + // if (this.localChatwoot.enabled) { + // this.chatwootService.eventWhatsapp( + // Events.SEND_MESSAGE, + // { instanceName: this.instance.name }, + // messageRaw, + // ); + // } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert( + [messageRaw], + this.instance.name, + this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, + ); + + return messageSent; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + // Instance Controller + public get connectionStatus() { + this.logger.verbose('Getting connection status'); + return this.stateConnection; + } + + // Send Message Controller + public async textMessage(data: SendTextDto) { + this.logger.verbose('Sending text message'); + return await this.sendMessageWithTyping( + data.number, + { + conversation: data.textMessage.text, + }, + data?.options, + ); + } + + public async pollMessage(data: SendPollDto) { + this.logger.verbose('Sending poll message'); + return await this.sendMessageWithTyping( + data.number, + { + poll: { + name: data.pollMessage.name, + selectableCount: data.pollMessage.selectableCount, + values: data.pollMessage.values, + }, + }, + data?.options, + ); + } + + private async formatStatusMessage(status: StatusMessage) { + this.logger.verbose('Formatting status message'); + + if (!status.type) { + throw new BadRequestException('Type is required'); + } + + if (!status.content) { + throw new BadRequestException('Content is required'); + } + + if (status.allContacts) { + this.logger.verbose('All contacts defined as true'); + + this.logger.verbose('Getting contacts from database'); + const contacts = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + if (!contacts.length) { + throw new BadRequestException('Contacts not found'); + } + + this.logger.verbose('Getting contacts with push name'); + status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); + + this.logger.verbose(status.statusJidList); + } + + if (!status.statusJidList?.length && !status.allContacts) { + throw new BadRequestException('StatusJidList is required'); + } + + if (status.type === 'text') { + this.logger.verbose('Type defined as text'); + + if (!status.backgroundColor) { + throw new BadRequestException('Background color is required'); + } + + if (!status.font) { + throw new BadRequestException('Font is required'); + } + + return { + content: { + text: status.content, + }, + option: { + backgroundColor: status.backgroundColor, + font: status.font, + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'image') { + this.logger.verbose('Type defined as image'); + + return { + content: { + image: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'video') { + this.logger.verbose('Type defined as video'); + + return { + content: { + video: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'audio') { + this.logger.verbose('Type defined as audio'); + + this.logger.verbose('Processing audio'); + const convert = await this.processAudio(status.content, 'status@broadcast'); + if (typeof convert === 'string') { + this.logger.verbose('Audio processed'); + const audio = fs.readFileSync(convert).toString('base64'); + + const result = { + content: { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + option: { + statusJidList: status.statusJidList, + }, + }; + + fs.unlinkSync(convert); + + return result; + } else { + throw new InternalServerErrorException(convert); + } + } + + throw new BadRequestException('Type not found'); + } + + public async statusMessage(data: SendStatusDto) { + this.logger.verbose('Sending status message'); + const status = await this.formatStatusMessage(data.statusMessage); + + return await this.sendMessageWithTyping('status@broadcast', { + status, + }); + } + + private async prepareMediaMessage(mediaMessage: MediaMessage) { + try { + this.logger.verbose('Preparing media message'); + const prepareMedia = await prepareWAMessageMedia( + { + [mediaMessage.mediatype]: isURL(mediaMessage.media) + ? { url: mediaMessage.media } + : Buffer.from(mediaMessage.media, 'base64'), + } as any, + { upload: this.client.waUploadToServer }, + ); + + const mediaType = mediaMessage.mediatype + 'Message'; + this.logger.verbose('Media type: ' + mediaType); + + if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { + this.logger.verbose('If media type is document and file name is not defined then'); + const regex = new RegExp(/.*\/(.+?)\./); + const arrayMatch = regex.exec(mediaMessage.media); + mediaMessage.fileName = arrayMatch[1]; + this.logger.verbose('File name: ' + mediaMessage.fileName); + } + + let mimetype: string; + + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + } else { + mimetype = getMIMEType(mediaMessage.fileName); + } + + this.logger.verbose('Mimetype: ' + mimetype); + + prepareMedia[mediaType].caption = mediaMessage?.caption; + prepareMedia[mediaType].mimetype = mimetype; + prepareMedia[mediaType].fileName = mediaMessage.fileName; + + if (mediaMessage.mediatype === 'video') { + this.logger.verbose('Is media type video then set gif playback as false'); + prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( + readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), + ); + prepareMedia[mediaType].gifPlayback = false; + } + + this.logger.verbose('Generating wa message from content'); + return generateWAMessageFromContent( + '', + { [mediaType]: { ...prepareMedia[mediaType] } }, + { userJid: this.instance.wuid }, + ); + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString() || error); + } + } + + private async convertToWebP(image: string, number: string) { + try { + this.logger.verbose('Converting image to WebP to sticker'); + + let imagePath: string; + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to image name: ' + hash); + + const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; + this.logger.verbose('Output path: ' + outputPath); + + if (isBase64(image)) { + this.logger.verbose('Image is base64'); + + const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); + const imageBuffer = Buffer.from(base64Data, 'base64'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } else { + this.logger.verbose('Image is url'); + + const timestamp = new Date().getTime(); + const url = `${image}?timestamp=${timestamp}`; + this.logger.verbose('including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting image from url'); + + const imageBuffer = Buffer.from(response.data, 'binary'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } + + await sharp(imagePath).webp().toFile(outputPath); + this.logger.verbose('Image converted to WebP'); + + fs.unlinkSync(imagePath); + this.logger.verbose('Temp image deleted'); + + return outputPath; + } catch (error) { + console.error('Erro ao converter a imagem para WebP:', error); + } + } + + public async mediaSticker(data: SendStickerDto) { + this.logger.verbose('Sending media sticker'); + const convert = await this.convertToWebP(data.stickerMessage.image, data.number); + const result = await this.sendMessageWithTyping( + data.number, + { + sticker: { url: convert }, + }, + data?.options, + ); + + fs.unlinkSync(convert); + this.logger.verbose('Converted image deleted'); return result; - }); - - return groups; - } catch (error) { - throw new NotFoundException('Error fetching group', error.toString()); } - } - public async inviteCode(id: GroupJid) { - this.logger.verbose('Fetching invite code for group: ' + id.groupJid); - try { - const code = await this.client.groupInviteCode(id.groupJid); - return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; - } catch (error) { - throw new NotFoundException('No invite code', error.toString()); + public async mediaMessage(data: SendMediaDto) { + this.logger.verbose('Sending media message'); + const generate = await this.prepareMediaMessage(data.mediaMessage); + + return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); } - } - public async inviteInfo(id: GroupInvite) { - this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); - try { - return await this.client.groupGetInviteInfo(id.inviteCode); - } catch (error) { - throw new NotFoundException('No invite info', id.inviteCode); + private async processAudio(audio: string, number: string) { + this.logger.verbose('Processing audio'); + let tempAudioPath: string; + let outputAudio: string; + + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to audio name: ' + hash); + + if (isURL(audio)) { + this.logger.verbose('Audio is url'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const timestamp = new Date().getTime(); + const url = `${audio}?timestamp=${timestamp}`; + + this.logger.verbose('Including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting audio from url'); + + fs.writeFileSync(tempAudioPath, response.data); + } else { + this.logger.verbose('Audio is base64'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const audioBuffer = Buffer.from(audio, 'base64'); + fs.writeFileSync(tempAudioPath, audioBuffer); + this.logger.verbose('Temp audio created'); + } + + this.logger.verbose('Converting audio to mp4'); + return new Promise((resolve, reject) => { + exec(`${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, (error) => { + fs.unlinkSync(tempAudioPath); + this.logger.verbose('Temp audio deleted'); + + if (error) reject(error); + + this.logger.verbose('Audio converted to mp4'); + resolve(outputAudio); + }); + }); } - } - public async sendInvite(id: GroupSendInvite) { - this.logger.verbose('Sending invite for group: ' + id.groupJid); - try { - const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); - this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); + public async audioWhatsapp(data: SendAudioDto) { + this.logger.verbose('Sending audio whatsapp'); - const inviteUrl = inviteCode.inviteUrl; - this.logger.verbose('Invite url: ' + inviteUrl); + if (!data.options?.encoding && data.options?.encoding !== false) { + data.options.encoding = true; + } - const numbers = id.numbers.map((number) => this.createJid(number)); - const description = id.description ?? ''; + if (data.options?.encoding) { + const convert = await this.processAudio(data.audioMessage.audio, data.number); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + const result = this.sendMessageWithTyping( + data.number, + { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); - const msg = `${description}\n\n${inviteUrl}`; + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); - const message = { - conversation: msg, - }; + return result; + } else { + throw new InternalServerErrorException(convert); + } + } - for await (const number of numbers) { - await this.sendMessageWithTyping(number, message); - } - - this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - - return { send: true, inviteUrl }; - } catch (error) { - throw new NotFoundException('No send invite'); + return await this.sendMessageWithTyping( + data.number, + { + audio: isURL(data.audioMessage.audio) + ? { url: data.audioMessage.audio } + : Buffer.from(data.audioMessage.audio, 'base64'), + ptt: true, + mimetype: 'audio/ogg; codecs=opus', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); } - } - public async revokeInviteCode(id: GroupJid) { - this.logger.verbose('Revoking invite code for group: ' + id.groupJid); - try { - const inviteCode = await this.client.groupRevokeInvite(id.groupJid); - return { revoked: true, inviteCode }; - } catch (error) { - throw new NotFoundException('Revoke error', error.toString()); - } - } + public async buttonMessage(data: SendButtonDto) { + this.logger.verbose('Sending button message'); + const embeddedMedia: any = {}; + let mediatype = 'TEXT'; - public async findParticipants(id: GroupJid) { - this.logger.verbose('Fetching participants for group: ' + id.groupJid); - try { - const participants = (await this.client.groupMetadata(id.groupJid)).participants; - return { participants }; - } catch (error) { - throw new NotFoundException('No participants', error.toString()); - } - } + if (data.buttonMessage?.mediaMessage) { + mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; + embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; + const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); + embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; + embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; + } - public async updateGParticipant(update: GroupUpdateParticipantDto) { - this.logger.verbose('Updating participants'); - try { - const participants = update.participants.map((p) => this.createJid(p)); - const updateParticipants = await this.client.groupParticipantsUpdate( - update.groupJid, - participants, - update.action, - ); - return { updateParticipants: updateParticipants }; - } catch (error) { - throw new BadRequestException('Error updating participants', error.toString()); - } - } + const btnItems = { + text: data.buttonMessage.buttons.map((btn) => btn.buttonText), + ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + }; - public async updateGSetting(update: GroupUpdateSettingDto) { - this.logger.verbose('Updating setting for group: ' + update.groupJid); - try { - const updateSetting = await this.client.groupSettingUpdate( - update.groupJid, - update.action, - ); - return { updateSetting: updateSetting }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } + if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { + throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); + } - public async toggleEphemeral(update: GroupToggleEphemeralDto) { - this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); - try { - const toggleEphemeral = await this.client.groupToggleEphemeral( - update.groupJid, - update.expiration, - ); - return { success: true }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); + return await this.sendMessageWithTyping( + data.number, + { + buttonsMessage: { + text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, + contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, + footerText: data.buttonMessage?.footerText, + buttons: data.buttonMessage.buttons.map((button) => { + return { + buttonText: { + displayText: button.buttonText, + }, + buttonId: button.buttonId, + type: 1, + }; + }), + headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], + [embeddedMedia?.mediaKey]: embeddedMedia?.message, + }, + }, + data?.options, + ); } - } - public async leaveGroup(id: GroupJid) { - this.logger.verbose('Leaving group: ' + id.groupJid); - try { - await this.client.groupLeave(id.groupJid); - return { groupJid: id.groupJid, leave: true }; - } catch (error) { - throw new BadRequestException('Unable to leave the group', error.toString()); + public async locationMessage(data: SendLocationDto) { + this.logger.verbose('Sending location message'); + return await this.sendMessageWithTyping( + data.number, + { + locationMessage: { + degreesLatitude: data.locationMessage.latitude, + degreesLongitude: data.locationMessage.longitude, + name: data.locationMessage?.name, + address: data.locationMessage?.address, + }, + }, + data?.options, + ); + } + + public async listMessage(data: SendListDto) { + this.logger.verbose('Sending list message'); + return await this.sendMessageWithTyping( + data.number, + { + listMessage: { + title: data.listMessage.title, + description: data.listMessage.description, + buttonText: data.listMessage?.buttonText, + footerText: data.listMessage?.footerText, + sections: data.listMessage.sections, + listType: 1, + }, + }, + data?.options, + ); + } + + public async contactMessage(data: SendContactDto) { + this.logger.verbose('Sending contact message'); + const message: proto.IMessage = {}; + + const vcard = (contact: ContactMessage) => { + this.logger.verbose('Creating vcard'); + let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; + + if (contact.organization) { + this.logger.verbose('Organization defined'); + result += `ORG:${contact.organization};\n`; + } + + if (contact.email) { + this.logger.verbose('Email defined'); + result += `EMAIL:${contact.email}\n`; + } + + if (contact.url) { + this.logger.verbose('Url defined'); + result += `URL:${contact.url}\n`; + } + + if (!contact.wuid) { + this.logger.verbose('Wuid defined'); + contact.wuid = this.createJid(contact.phoneNumber); + } + + result += + `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; + + this.logger.verbose('Vcard created'); + return result; + }; + + if (data.contactMessage.length === 1) { + message.contactMessage = { + displayName: data.contactMessage[0].fullName, + vcard: vcard(data.contactMessage[0]), + }; + } else { + message.contactsArrayMessage = { + displayName: `${data.contactMessage.length} contacts`, + contacts: data.contactMessage.map((contact) => { + return { + displayName: contact.fullName, + vcard: vcard(contact), + }; + }), + }; + } + + return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + } + + public async reactionMessage(data: SendReactionDto) { + this.logger.verbose('Sending reaction message'); + return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { + reactionMessage: { + key: data.reactionMessage.key, + text: data.reactionMessage.reaction, + }, + }); + } + + // Chat Controller + public async whatsappNumber(data: WhatsAppNumberDto) { + this.logger.verbose('Getting whatsapp number'); + + const onWhatsapp: OnWhatsAppDto[] = []; + for await (const number of data.numbers) { + let jid = this.createJid(number); + + if (isJidGroup(jid)) { + const group = await this.findGroup({ groupJid: jid }, 'inner'); + + if (!group) throw new BadRequestException('Group not found'); + + onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); + } else { + jid = !jid.startsWith('+') ? `+${jid}` : jid; + const verify = await this.client.onWhatsApp(jid); + + const result = verify[0]; + + if (!result) { + onWhatsapp.push(new OnWhatsAppDto(jid, false)); + } else { + onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); + } + } + } + + return onWhatsapp; + } + + public async markMessageAsRead(data: ReadMessageDto) { + this.logger.verbose('Marking message as read'); + try { + const keys: proto.IMessageKey[] = []; + data.read_messages.forEach((read) => { + if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { + keys.push({ + remoteJid: read.remoteJid, + fromMe: read.fromMe, + id: read.id, + }); + } + }); + await this.client.readMessages(keys); + return { message: 'Read messages', read: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Read messages fail', error.toString()); + } + } + + public async archiveChat(data: ArchiveChatDto) { + this.logger.verbose('Archiving chat'); + try { + data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); + await this.client.chatModify( + { + archive: data.archive, + lastMessages: [data.lastMessage], + }, + data.lastMessage.key.remoteJid, + ); + + return { + chatId: data.lastMessage.key.remoteJid, + archived: true, + }; + } catch (error) { + throw new InternalServerErrorException({ + archived: false, + message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], + }); + } + } + + public async deleteMessage(del: DeleteMessage) { + this.logger.verbose('Deleting message'); + try { + return await this.client.sendMessage(del.remoteJid, { delete: del }); + } catch (error) { + throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); + } + } + + public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { + this.logger.verbose('Getting base64 from media message'); + try { + const m = data?.message; + const convertToMp4 = data?.convertToMp4 ?? false; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + for (const subtype of MessageSubtype) { + if (msg.message[subtype]) { + msg.message = msg.message[subtype].message; + } + } + + let mediaMessage: any; + let mediaType: string; + + for (const type of TypeMediaMessage) { + mediaMessage = msg.message[type]; + if (mediaMessage) { + mediaType = type; + break; + } + } + + if (!mediaMessage) { + throw 'The message is not of the media type'; + } + + if (typeof mediaMessage['mediaKey'] === 'object') { + msg.message = JSON.parse(JSON.stringify(msg.message)); + } + + this.logger.verbose('Downloading media message'); + const buffer = await downloadMediaMessage( + { key: msg?.key, message: msg?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }), + reuploadRequest: this.client.updateMediaMessage, + }, + ); + const typeMessage = getContentType(msg.message); + + if (convertToMp4 && typeMessage === 'audioMessage') { + this.logger.verbose('Converting audio to mp4'); + const number = msg.key.remoteJid.split('@')[0]; + const convert = await this.processAudio(buffer.toString('base64'), number); + + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + this.logger.verbose('Audio converted to mp4'); + + const result = { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: 'audio/mp4', + base64: Buffer.from(audio, 'base64').toString('base64'), + }; + + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); + + this.logger.verbose('Media message downloaded'); + return result; + } + } + + this.logger.verbose('Media message downloaded'); + return { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: mediaMessage['mimetype'], + base64: buffer.toString('base64'), + }; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + public async fetchContacts(query: ContactQuery) { + this.logger.verbose('Fetching contacts'); + if (query?.where) { + query.where.owner = this.instance.name; + if (query.where?.id) { + query.where.id = this.createJid(query.where.id); + } + } else { + query = { + where: { + owner: this.instance.name, + }, + }; + } + return await this.repository.contact.find(query); + } + + public async fetchMessages(query: MessageQuery) { + this.logger.verbose('Fetching messages'); + if (query?.where) { + if (query.where?.key?.remoteJid) { + query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.message.find(query); + } + + public async fetchStatusMessage(query: MessageUpQuery) { + this.logger.verbose('Fetching status messages'); + if (query?.where) { + if (query.where?.remoteJid) { + query.where.remoteJid = this.createJid(query.where.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.messageUpdate.find(query); + } + + public async fetchChats() { + this.logger.verbose('Fetching chats'); + return await this.repository.chat.find({ where: { owner: this.instance.name } }); + } + + public async fetchPrivacySettings() { + this.logger.verbose('Fetching privacy settings'); + return await this.client.fetchPrivacySettings(); + } + + public async updatePrivacySettings(settings: PrivacySettingDto) { + this.logger.verbose('Updating privacy settings'); + try { + await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); + this.logger.verbose('Read receipts privacy updated'); + + await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); + this.logger.verbose('Profile picture privacy updated'); + + await this.client.updateStatusPrivacy(settings.privacySettings.status); + this.logger.verbose('Status privacy updated'); + + await this.client.updateOnlinePrivacy(settings.privacySettings.online); + this.logger.verbose('Online privacy updated'); + + await this.client.updateLastSeenPrivacy(settings.privacySettings.last); + this.logger.verbose('Last seen privacy updated'); + + await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); + this.logger.verbose('Groups add privacy updated'); + + this.client?.ws?.close(); + + return { + update: 'success', + data: { + readreceipts: settings.privacySettings.readreceipts, + profile: settings.privacySettings.profile, + status: settings.privacySettings.status, + online: settings.privacySettings.online, + last: settings.privacySettings.last, + groupadd: settings.privacySettings.groupadd, + }, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating privacy settings', error.toString()); + } + } + + public async fetchBusinessProfile(number: string): Promise { + this.logger.verbose('Fetching business profile'); + try { + const jid = number ? this.createJid(number) : this.instance.wuid; + + const profile = await this.client.getBusinessProfile(jid); + this.logger.verbose('Trying to get business profile'); + + if (!profile) { + const info = await this.whatsappNumber({ numbers: [jid] }); + + return { + isBusiness: false, + message: 'Not is business profile', + ...info?.shift(), + }; + } + + this.logger.verbose('Business profile fetched'); + return { + isBusiness: true, + ...profile, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileName(name: string) { + this.logger.verbose('Updating profile name to ' + name); + try { + await this.client.updateProfileName(name); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileStatus(status: string) { + this.logger.verbose('Updating profile status to: ' + status); + try { + await this.client.updateProfileStatus(status); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile status', error.toString()); + } + } + + public async updateProfilePicture(picture: string) { + this.logger.verbose('Updating profile picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(this.instance.wuid, pic); + this.logger.verbose('Profile picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile picture', error.toString()); + } + } + + public async removeProfilePicture() { + this.logger.verbose('Removing profile picture'); + try { + await this.client.removeProfilePicture(this.instance.wuid); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error removing profile picture', error.toString()); + } + } + + // Group + public async createGroup(create: CreateGroupDto) { + this.logger.verbose('Creating group: ' + create.subject); + try { + const participants = create.participants.map((p) => this.createJid(p)); + const { id } = await this.client.groupCreate(create.subject, participants); + this.logger.verbose('Group created: ' + id); + + if (create?.description) { + this.logger.verbose('Updating group description: ' + create.description); + await this.client.groupUpdateDescription(id, create.description); + } + + if (create?.promoteParticipants) { + this.logger.verbose('Prometing group participants: ' + create.description); + await this.updateGParticipant({ + groupJid: id, + action: 'promote', + participants: participants, + }); + } + + const group = await this.client.groupMetadata(id); + this.logger.verbose('Getting group metadata'); + + return group; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException('Error creating group', error.toString()); + } + } + + public async updateGroupPicture(picture: GroupPictureDto) { + this.logger.verbose('Updating group picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture.image)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture.image}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture.image)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture.image, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(picture.groupJid, pic); + this.logger.verbose('Group picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error update group picture', error.toString()); + } + } + + public async updateGroupSubject(data: GroupSubjectDto) { + this.logger.verbose('Updating group subject to: ' + data.subject); + try { + await this.client.groupUpdateSubject(data.groupJid, data.subject); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group subject', error.toString()); + } + } + + public async updateGroupDescription(data: GroupDescriptionDto) { + this.logger.verbose('Updating group description to: ' + data.description); + try { + await this.client.groupUpdateDescription(data.groupJid, data.description); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group description', error.toString()); + } + } + + public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { + this.logger.verbose('Fetching group'); + try { + return await this.client.groupMetadata(id.groupJid); + } catch (error) { + if (reply === 'inner') { + return; + } + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async fetchAllGroups(getParticipants: GetParticipant) { + this.logger.verbose('Fetching all groups'); + try { + const fetch = Object.values(await this.client.groupFetchAllParticipating()); + + const groups = fetch.map((group) => { + const result = { + id: group.id, + subject: group.subject, + subjectOwner: group.subjectOwner, + subjectTime: group.subjectTime, + size: group.size, + creation: group.creation, + owner: group.owner, + desc: group.desc, + descId: group.descId, + restrict: group.restrict, + announce: group.announce, + }; + + if (getParticipants.getParticipants == 'true') { + result['participants'] = group.participants; + } + + return result; + }); + + return groups; + } catch (error) { + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async inviteCode(id: GroupJid) { + this.logger.verbose('Fetching invite code for group: ' + id.groupJid); + try { + const code = await this.client.groupInviteCode(id.groupJid); + return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; + } catch (error) { + throw new NotFoundException('No invite code', error.toString()); + } + } + + public async inviteInfo(id: GroupInvite) { + this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); + try { + return await this.client.groupGetInviteInfo(id.inviteCode); + } catch (error) { + throw new NotFoundException('No invite info', id.inviteCode); + } + } + + public async sendInvite(id: GroupSendInvite) { + this.logger.verbose('Sending invite for group: ' + id.groupJid); + try { + const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); + this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); + + const inviteUrl = inviteCode.inviteUrl; + this.logger.verbose('Invite url: ' + inviteUrl); + + const numbers = id.numbers.map((number) => this.createJid(number)); + const description = id.description ?? ''; + + const msg = `${description}\n\n${inviteUrl}`; + + const message = { + conversation: msg, + }; + + for await (const number of numbers) { + await this.sendMessageWithTyping(number, message); + } + + this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); + + return { send: true, inviteUrl }; + } catch (error) { + throw new NotFoundException('No send invite'); + } + } + + public async revokeInviteCode(id: GroupJid) { + this.logger.verbose('Revoking invite code for group: ' + id.groupJid); + try { + const inviteCode = await this.client.groupRevokeInvite(id.groupJid); + return { revoked: true, inviteCode }; + } catch (error) { + throw new NotFoundException('Revoke error', error.toString()); + } + } + + public async findParticipants(id: GroupJid) { + this.logger.verbose('Fetching participants for group: ' + id.groupJid); + try { + const participants = (await this.client.groupMetadata(id.groupJid)).participants; + return { participants }; + } catch (error) { + throw new NotFoundException('No participants', error.toString()); + } + } + + public async updateGParticipant(update: GroupUpdateParticipantDto) { + this.logger.verbose('Updating participants'); + try { + const participants = update.participants.map((p) => this.createJid(p)); + const updateParticipants = await this.client.groupParticipantsUpdate( + update.groupJid, + participants, + update.action, + ); + return { updateParticipants: updateParticipants }; + } catch (error) { + throw new BadRequestException('Error updating participants', error.toString()); + } + } + + public async updateGSetting(update: GroupUpdateSettingDto) { + this.logger.verbose('Updating setting for group: ' + update.groupJid); + try { + const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); + return { updateSetting: updateSetting }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); + } + } + + public async toggleEphemeral(update: GroupToggleEphemeralDto) { + this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); + try { + await this.client.groupToggleEphemeral(update.groupJid, update.expiration); + return { success: true }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); + } + } + + public async leaveGroup(id: GroupJid) { + this.logger.verbose('Leaving group: ' + id.groupJid); + try { + await this.client.groupLeave(id.groupJid); + return { groupJid: id.groupJid, leave: true }; + } catch (error) { + throw new BadRequestException('Unable to leave the group', error.toString()); + } } - } } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index a0d514d8..59e9d012 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -2,101 +2,88 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys'; export enum Events { - APPLICATION_STARTUP = 'application.startup', - QRCODE_UPDATED = 'qrcode.updated', - CONNECTION_UPDATE = 'connection.update', - STATUS_INSTANCE = 'status.instance', - MESSAGES_SET = 'messages.set', - MESSAGES_UPSERT = 'messages.upsert', - MESSAGES_UPDATE = 'messages.update', - MESSAGES_DELETE = 'messages.delete', - SEND_MESSAGE = 'send.message', - CONTACTS_SET = 'contacts.set', - CONTACTS_UPSERT = 'contacts.upsert', - CONTACTS_UPDATE = 'contacts.update', - PRESENCE_UPDATE = 'presence.update', - CHATS_SET = 'chats.set', - CHATS_UPDATE = 'chats.update', - CHATS_UPSERT = 'chats.upsert', - CHATS_DELETE = 'chats.delete', - GROUPS_UPSERT = 'groups.upsert', - GROUPS_UPDATE = 'groups.update', - GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', - CALL = 'call', + APPLICATION_STARTUP = 'application.startup', + QRCODE_UPDATED = 'qrcode.updated', + CONNECTION_UPDATE = 'connection.update', + STATUS_INSTANCE = 'status.instance', + MESSAGES_SET = 'messages.set', + MESSAGES_UPSERT = 'messages.upsert', + MESSAGES_UPDATE = 'messages.update', + MESSAGES_DELETE = 'messages.delete', + SEND_MESSAGE = 'send.message', + CONTACTS_SET = 'contacts.set', + CONTACTS_UPSERT = 'contacts.upsert', + CONTACTS_UPDATE = 'contacts.update', + PRESENCE_UPDATE = 'presence.update', + CHATS_SET = 'chats.set', + CHATS_UPDATE = 'chats.update', + CHATS_UPSERT = 'chats.upsert', + CHATS_DELETE = 'chats.delete', + GROUPS_UPSERT = 'groups.upsert', + GROUPS_UPDATE = 'groups.update', + GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { - export type QrCode = { - count?: number; - pairingCode?: string; - base64?: string; - code?: string; - }; - export type Instance = { - qrcode?: QrCode; - pairingCode?: string; - authState?: { state: AuthenticationState; saveCreds: () => void }; - name?: string; - wuid?: string; - profileName?: string; - profilePictureUrl?: string; - }; + export type QrCode = { + count?: number; + pairingCode?: string; + base64?: string; + code?: string; + }; + export type Instance = { + qrcode?: QrCode; + pairingCode?: string; + authState?: { state: AuthenticationState; saveCreds: () => void }; + name?: string; + wuid?: string; + profileName?: string; + profilePictureUrl?: string; + }; - export type LocalWebHook = { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; - }; + export type LocalWebHook = { + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; + }; - export type LocalChatwoot = { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; - }; + export type LocalChatwoot = { + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; + }; - export type LocalSettings = { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; - }; + export type LocalSettings = { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + }; - export type StateConnection = { - instance?: string; - state?: WAConnectionState | 'refused'; - statusReason?: number; - }; + export type StateConnection = { + instance?: string; + state?: WAConnectionState | 'refused'; + statusReason?: number; + }; - export type StatusMessage = - | 'ERROR' - | 'PENDING' - | 'SERVER_ACK' - | 'DELIVERY_ACK' - | 'READ' - | 'DELETED' - | 'PLAYED'; + export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; } -export const TypeMediaMessage = [ - 'imageMessage', - 'documentMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', -]; +export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage']; export const MessageSubtype = [ - 'ephemeralMessage', - 'documentWithCaptionMessage', - 'viewOnceMessage', - 'viewOnceMessageV2', + 'ephemeralMessage', + 'documentWithCaptionMessage', + 'viewOnceMessage', + 'viewOnceMessageV2', ]; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index b8f3b1ad..f9a9456e 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -1,43 +1,40 @@ -import { Auth, configService } from '../config/env.config'; -import { Logger } from '../config/logger.config'; +import { configService } from '../config/env.config'; import { eventEmitter } from '../config/event.config'; -import { MessageRepository } from './repository/message.repository'; -import { WAMonitoringService } from './services/monitor.service'; -import { ChatRepository } from './repository/chat.repository'; -import { ContactRepository } from './repository/contact.repository'; -import { MessageUpRepository } from './repository/messageUp.repository'; +import { Logger } from '../config/logger.config'; +import { dbserver } from '../db/db.connect'; +import { RedisCache } from '../db/redis.client'; import { ChatController } from './controllers/chat.controller'; +import { ChatwootController } from './controllers/chatwoot.controller'; +import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; -import { AuthService } from './services/auth.service'; -import { GroupController } from './controllers/group.controller'; -import { ViewsController } from './controllers/views.controller'; -import { WebhookService } from './services/webhook.service'; -import { WebhookController } from './controllers/webhook.controller'; -import { ChatwootService } from './services/chatwoot.service'; -import { ChatwootController } from './controllers/chatwoot.controller'; -import { RepositoryBroker } from './repository/repository.manager'; -import { - AuthModel, - ChatModel, - ContactModel, - MessageModel, - MessageUpModel, - ChatwootModel, - WebhookModel, - SettingsModel, -} from './models'; -import { dbserver } from '../db/db.connect'; -import { WebhookRepository } from './repository/webhook.repository'; -import { ChatwootRepository } from './repository/chatwoot.repository'; -import { AuthRepository } from './repository/auth.repository'; -import { WAStartupService } from './services/whatsapp.service'; -import { delay } from '@whiskeysockets/baileys'; -import { Events } from './types/wa.types'; -import { RedisCache } from '../db/redis.client'; -import { SettingsRepository } from './repository/settings.repository'; -import { SettingsService } from './services/settings.service'; import { SettingsController } from './controllers/settings.controller'; +import { ViewsController } from './controllers/views.controller'; +import { WebhookController } from './controllers/webhook.controller'; +import { + AuthModel, + ChatModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + SettingsModel, + WebhookModel, +} from './models'; +import { AuthRepository } from './repository/auth.repository'; +import { ChatRepository } from './repository/chat.repository'; +import { ChatwootRepository } from './repository/chatwoot.repository'; +import { ContactRepository } from './repository/contact.repository'; +import { MessageRepository } from './repository/message.repository'; +import { MessageUpRepository } from './repository/messageUp.repository'; +import { RepositoryBroker } from './repository/repository.manager'; +import { SettingsRepository } from './repository/settings.repository'; +import { WebhookRepository } from './repository/webhook.repository'; +import { AuthService } from './services/auth.service'; +import { ChatwootService } from './services/chatwoot.service'; +import { WAMonitoringService } from './services/monitor.service'; +import { SettingsService } from './services/settings.service'; +import { WebhookService } from './services/webhook.service'; const logger = new Logger('WA MODULE'); @@ -51,26 +48,21 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); export const repository = new RepositoryBroker( - messageRepository, - chatRepository, - contactRepository, - messageUpdateRepository, - webhookRepository, - chatwootRepository, - settingsRepository, - authRepository, - configService, - dbserver?.getClient(), + messageRepository, + chatRepository, + contactRepository, + messageUpdateRepository, + webhookRepository, + chatwootRepository, + settingsRepository, + authRepository, + configService, + dbserver?.getClient(), ); export const cache = new RedisCache(); -export const waMonitor = new WAMonitoringService( - eventEmitter, - configService, - repository, - cache, -); +export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache); const authService = new AuthService(configService, waMonitor, repository); @@ -87,15 +79,15 @@ const settingsService = new SettingsService(waMonitor); export const settingsController = new SettingsController(settingsService); export const instanceController = new InstanceController( - waMonitor, - configService, - repository, - eventEmitter, - authService, - webhookService, - chatwootService, - settingsService, - cache, + waMonitor, + configService, + repository, + eventEmitter, + authService, + webhookService, + chatwootService, + settingsService, + cache, ); export const viewsController = new ViewsController(waMonitor, configService); export const sendMessageController = new SendMessageController(waMonitor); From 0a851b935e6746c99aca79f7b0cab0d856e2c256 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 11:10:23 -0300 Subject: [PATCH 070/177] Update .gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 69d60b7a..2364b077 100644 --- a/.gitignore +++ b/.gitignore @@ -22,12 +22,13 @@ docker-compose.yaml /yarn.lock /package-lock.json -# IDE - VSCode +# IDEs .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +.nova/* # Prisma /prisma/migrations @@ -40,3 +41,6 @@ docker-compose.yaml /store /temp/* + +.DS_Store +*.DS_Store \ No newline at end of file From dc3d59bae1dfbab1354586f964688611083905d3 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 11:12:00 -0300 Subject: [PATCH 071/177] wip --- .prettierrc.js | 2 +- src/config/env.config.ts | 394 +- src/config/error.config.ts | 28 +- src/config/event.config.ts | 6 +- src/config/logger.config.ts | 210 +- src/db/db.connect.ts | 26 +- src/db/redis.client.ts | 168 +- src/exceptions/400.exception.ts | 14 +- src/exceptions/401.exception.ts | 14 +- src/exceptions/403.exception.ts | 14 +- src/exceptions/404.exception.ts | 14 +- src/exceptions/500.exception.ts | 14 +- src/main.ts | 136 +- src/utils/server-up.ts | 34 +- src/utils/use-multi-file-auth-state-db.ts | 152 +- .../use-multi-file-auth-state-redis-db.ts | 132 +- src/validate/validate.schema.ts | 1422 ++--- src/whatsapp/abstract/abstract.repository.ts | 80 +- src/whatsapp/abstract/abstract.router.ts | 359 +- src/whatsapp/controllers/chat.controller.ts | 166 +- .../controllers/chatwoot.controller.ts | 144 +- src/whatsapp/controllers/group.controller.ts | 144 +- .../controllers/instance.controller.ts | 608 +- .../controllers/sendMessage.controller.ts | 162 +- .../controllers/settings.controller.ts | 18 +- src/whatsapp/controllers/views.controller.ts | 26 +- .../controllers/webhook.controller.ts | 34 +- src/whatsapp/dto/chat.dto.ts | 78 +- src/whatsapp/dto/chatwoot.dto.ts | 18 +- src/whatsapp/dto/group.dto.ts | 40 +- src/whatsapp/dto/instance.dto.ts | 38 +- src/whatsapp/dto/sendMessage.dto.ts | 144 +- src/whatsapp/dto/settings.dto.ts | 12 +- src/whatsapp/dto/webhook.dto.ts | 8 +- src/whatsapp/guards/auth.guard.ts | 110 +- src/whatsapp/guards/instance.guard.ts | 72 +- src/whatsapp/models/auth.model.ts | 12 +- src/whatsapp/models/chat.model.ts | 14 +- src/whatsapp/models/chatwoot.model.ts | 36 +- src/whatsapp/models/contact.model.ts | 20 +- src/whatsapp/models/message.model.ts | 88 +- src/whatsapp/models/settings.model.ts | 28 +- src/whatsapp/models/webhook.model.ts | 20 +- src/whatsapp/repository/auth.repository.ts | 98 +- src/whatsapp/repository/chat.repository.ts | 172 +- .../repository/chatwoot.repository.ts | 98 +- src/whatsapp/repository/contact.repository.ts | 266 +- src/whatsapp/repository/message.repository.ts | 244 +- .../repository/messageUp.repository.ts | 183 +- src/whatsapp/repository/repository.manager.ts | 188 +- .../repository/settings.repository.ts | 98 +- src/whatsapp/repository/webhook.repository.ts | 96 +- src/whatsapp/routers/chat.router.ts | 560 +- src/whatsapp/routers/chatwoot.router.ts | 94 +- src/whatsapp/routers/group.router.ts | 474 +- src/whatsapp/routers/index.router.ts | 42 +- src/whatsapp/routers/instance.router.ts | 310 +- src/whatsapp/routers/sendMessage.router.ts | 362 +- src/whatsapp/routers/settings.router.ts | 66 +- src/whatsapp/routers/view.router.ts | 14 +- src/whatsapp/routers/webhook.router.ts | 66 +- src/whatsapp/services/auth.service.ts | 298 +- src/whatsapp/services/chatwoot.service.ts | 2777 +++++---- src/whatsapp/services/monitor.service.ts | 610 +- src/whatsapp/services/settings.service.ts | 42 +- src/whatsapp/services/webhook.service.ts | 42 +- src/whatsapp/services/whatsapp.service.ts | 5477 ++++++++--------- src/whatsapp/types/wa.types.ts | 142 +- src/whatsapp/whatsapp.module.ts | 54 +- 69 files changed, 9028 insertions(+), 9104 deletions(-) diff --git a/.prettierrc.js b/.prettierrc.js index 362adbcb..f55f3f06 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -4,7 +4,7 @@ module.exports = { singleQuote: true, printWidth: 120, arrowParens: 'always', - tabWidth: 4, + tabWidth: 2, useTabs: false, bracketSameLine: false, bracketSpacing: true, diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 4e5871e1..b90141ff 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -7,9 +7,9 @@ export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { - ORIGIN: string[]; - METHODS: HttpMethods[]; - CREDENTIALS: boolean; + ORIGIN: string[]; + METHODS: HttpMethods[]; + CREDENTIALS: boolean; }; export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; @@ -17,90 +17,90 @@ export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' export type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS'; export type Log = { - LEVEL: LogLevel[]; - COLOR: boolean; - BAILEYS: LogBaileys; + LEVEL: LogLevel[]; + COLOR: boolean; + BAILEYS: LogBaileys; }; export type SaveData = { - INSTANCE: boolean; - NEW_MESSAGE: boolean; - MESSAGE_UPDATE: boolean; - CONTACTS: boolean; - CHATS: boolean; + INSTANCE: boolean; + NEW_MESSAGE: boolean; + MESSAGE_UPDATE: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type StoreConf = { - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type CleanStoreConf = { - CLEANING_INTERVAL: number; - MESSAGES: boolean; - MESSAGE_UP: boolean; - CONTACTS: boolean; - CHATS: boolean; + CLEANING_INTERVAL: number; + MESSAGES: boolean; + MESSAGE_UP: boolean; + CONTACTS: boolean; + CHATS: boolean; }; export type DBConnection = { - URI: string; - DB_PREFIX_NAME: string; + URI: string; + DB_PREFIX_NAME: string; }; export type Database = { - CONNECTION: DBConnection; - ENABLED: boolean; - SAVE_DATA: SaveData; + CONNECTION: DBConnection; + ENABLED: boolean; + SAVE_DATA: SaveData; }; export type Redis = { - ENABLED: boolean; - URI: string; - PREFIX_KEY: string; + ENABLED: boolean; + URI: string; + PREFIX_KEY: string; }; export type EventsWebhook = { - APPLICATION_STARTUP: boolean; - QRCODE_UPDATED: boolean; - MESSAGES_SET: boolean; - MESSAGES_UPSERT: boolean; - MESSAGES_UPDATE: boolean; - MESSAGES_DELETE: boolean; - SEND_MESSAGE: boolean; - CONTACTS_SET: boolean; - CONTACTS_UPDATE: boolean; - CONTACTS_UPSERT: boolean; - PRESENCE_UPDATE: boolean; - CHATS_SET: boolean; - CHATS_UPDATE: boolean; - CHATS_DELETE: boolean; - CHATS_UPSERT: boolean; - CONNECTION_UPDATE: boolean; - GROUPS_UPSERT: boolean; - GROUP_UPDATE: boolean; - GROUP_PARTICIPANTS_UPDATE: boolean; - CALL: boolean; - NEW_JWT_TOKEN: boolean; + APPLICATION_STARTUP: boolean; + QRCODE_UPDATED: boolean; + MESSAGES_SET: boolean; + MESSAGES_UPSERT: boolean; + MESSAGES_UPDATE: boolean; + MESSAGES_DELETE: boolean; + SEND_MESSAGE: boolean; + CONTACTS_SET: boolean; + CONTACTS_UPDATE: boolean; + CONTACTS_UPSERT: boolean; + PRESENCE_UPDATE: boolean; + CHATS_SET: boolean; + CHATS_UPDATE: boolean; + CHATS_DELETE: boolean; + CHATS_UPSERT: boolean; + CONNECTION_UPDATE: boolean; + GROUPS_UPSERT: boolean; + GROUP_UPDATE: boolean; + GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; + NEW_JWT_TOKEN: boolean; }; export type ApiKey = { KEY: string }; export type Jwt = { EXPIRIN_IN: number; SECRET: string }; export type Auth = { - API_KEY: ApiKey; - EXPOSE_IN_FETCH_INSTANCES: boolean; - JWT: Jwt; - TYPE: 'jwt' | 'apikey'; + API_KEY: ApiKey; + EXPOSE_IN_FETCH_INSTANCES: boolean; + JWT: Jwt; + TYPE: 'jwt' | 'apikey'; }; export type DelInstance = number | boolean; export type GlobalWebhook = { - URL: string; - ENABLED: boolean; - WEBHOOK_BY_EVENTS: boolean; + URL: string; + ENABLED: boolean; + WEBHOOK_BY_EVENTS: boolean; }; export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; @@ -109,158 +109,158 @@ export type QrCode = { LIMIT: number }; export type Production = boolean; export interface Env { - SERVER: HttpServer; - CORS: Cors; - SSL_CONF: SslConf; - STORE: StoreConf; - CLEAN_STORE: CleanStoreConf; - DATABASE: Database; - REDIS: Redis; - LOG: Log; - DEL_INSTANCE: DelInstance; - WEBHOOK: Webhook; - CONFIG_SESSION_PHONE: ConfigSessionPhone; - QRCODE: QrCode; - AUTHENTICATION: Auth; - PRODUCTION?: Production; + SERVER: HttpServer; + CORS: Cors; + SSL_CONF: SslConf; + STORE: StoreConf; + CLEAN_STORE: CleanStoreConf; + DATABASE: Database; + REDIS: Redis; + LOG: Log; + DEL_INSTANCE: DelInstance; + WEBHOOK: Webhook; + CONFIG_SESSION_PHONE: ConfigSessionPhone; + QRCODE: QrCode; + AUTHENTICATION: Auth; + PRODUCTION?: Production; } export type Key = keyof Env; export class ConfigService { - constructor() { - this.loadEnv(); - } + constructor() { + this.loadEnv(); + } - private env: Env; + private env: Env; - public get(key: Key) { - return this.env[key] as T; - } + public get(key: Key) { + return this.env[key] as T; + } - private loadEnv() { - this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); - this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; - if (process.env?.DOCKER_ENV === 'true') { - this.env.SERVER.TYPE = 'http'; - this.env.SERVER.PORT = 8080; - } + private loadEnv() { + this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); + this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; + if (process.env?.DOCKER_ENV === 'true') { + this.env.SERVER.TYPE = 'http'; + this.env.SERVER.PORT = 8080; } + } - private envYaml(): Env { - return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; - } + private envYaml(): Env { + return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; + } - private envProcess(): Env { - return { - SERVER: { - TYPE: process.env.SERVER_TYPE as 'http' | 'https', - PORT: Number.parseInt(process.env.SERVER_PORT), - URL: process.env.SERVER_URL, - }, - CORS: { - ORIGIN: process.env.CORS_ORIGIN.split(','), - METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], - CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', - }, - SSL_CONF: { - PRIVKEY: process.env?.SSL_CONF_PRIVKEY, - FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, - }, - STORE: { - MESSAGES: process.env?.STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.STORE_CONTACTS === 'true', - CHATS: process.env?.STORE_CHATS === 'true', - }, - CLEAN_STORE: { - CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) - ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) - : 7200, - MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', - MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', - CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', - CHATS: process.env?.CLEAN_STORE_CHATS === 'true', - }, - DATABASE: { - CONNECTION: { - URI: process.env.DATABASE_CONNECTION_URI, - DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, - }, - ENABLED: process.env?.DATABASE_ENABLED === 'true', - SAVE_DATA: { - INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', - NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', - MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', - CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', - CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', - }, - }, - REDIS: { - ENABLED: process.env?.REDIS_ENABLED === 'true', - URI: process.env.REDIS_URI, - PREFIX_KEY: process.env.REDIS_PREFIX_KEY, - }, - LOG: { - LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], - COLOR: process.env?.LOG_COLOR === 'true', - BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', - }, - DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 'true' - : Number.parseInt(process.env.DEL_INSTANCE) || false, - WEBHOOK: { - GLOBAL: { - URL: process.env?.WEBHOOK_GLOBAL_URL, - ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', - WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', - }, - EVENTS: { - APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', - QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', - MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', - MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', - MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', - MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', - SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', - CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', - CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', - CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', - PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', - CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', - CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', - CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', - CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', - CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', - GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', - GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', - GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', - CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', - NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', - }, - }, - CONFIG_SESSION_PHONE: { - CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', - NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', - }, - QRCODE: { - LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, - }, - AUTHENTICATION: { - TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', - API_KEY: { - KEY: process.env.AUTHENTICATION_API_KEY, - }, - EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', - JWT: { - EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) - ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) - : 3600, - SECRET: process.env.AUTHENTICATION_JWT_SECRET, - }, - }, - }; - } + private envProcess(): Env { + return { + SERVER: { + TYPE: process.env.SERVER_TYPE as 'http' | 'https', + PORT: Number.parseInt(process.env.SERVER_PORT), + URL: process.env.SERVER_URL, + }, + CORS: { + ORIGIN: process.env.CORS_ORIGIN.split(','), + METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], + CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', + }, + SSL_CONF: { + PRIVKEY: process.env?.SSL_CONF_PRIVKEY, + FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, + }, + STORE: { + MESSAGES: process.env?.STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.STORE_CONTACTS === 'true', + CHATS: process.env?.STORE_CHATS === 'true', + }, + CLEAN_STORE: { + CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) + ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) + : 7200, + MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', + MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', + CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', + CHATS: process.env?.CLEAN_STORE_CHATS === 'true', + }, + DATABASE: { + CONNECTION: { + URI: process.env.DATABASE_CONNECTION_URI, + DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, + }, + ENABLED: process.env?.DATABASE_ENABLED === 'true', + SAVE_DATA: { + INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true', + NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true', + MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true', + CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true', + CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', + }, + }, + REDIS: { + ENABLED: process.env?.REDIS_ENABLED === 'true', + URI: process.env.REDIS_URI, + PREFIX_KEY: process.env.REDIS_PREFIX_KEY, + }, + LOG: { + LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], + COLOR: process.env?.LOG_COLOR === 'true', + BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', + }, + DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) + ? process.env.DEL_INSTANCE === 'true' + : Number.parseInt(process.env.DEL_INSTANCE) || false, + WEBHOOK: { + GLOBAL: { + URL: process.env?.WEBHOOK_GLOBAL_URL, + ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', + WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', + }, + EVENTS: { + APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', + QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', + MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', + MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', + MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', + MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', + SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', + CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', + CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', + CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', + PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true', + CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true', + CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true', + CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true', + CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true', + CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', + GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', + GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', + GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', + NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', + }, + }, + CONFIG_SESSION_PHONE: { + CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', + }, + QRCODE: { + LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, + }, + AUTHENTICATION: { + TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', + API_KEY: { + KEY: process.env.AUTHENTICATION_API_KEY, + }, + EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', + JWT: { + EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) + ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) + : 3600, + SECRET: process.env.AUTHENTICATION_JWT_SECRET, + }, + }, + }; + } } export const configService = new ConfigService(); diff --git a/src/config/error.config.ts b/src/config/error.config.ts index 999205c4..6449d52e 100644 --- a/src/config/error.config.ts +++ b/src/config/error.config.ts @@ -1,21 +1,21 @@ import { Logger } from './logger.config'; export function onUnexpectedError() { - process.on('uncaughtException', (error, origin) => { - const logger = new Logger('uncaughtException'); - logger.error({ - origin, - stderr: process.stderr.fd, - error, - }); + process.on('uncaughtException', (error, origin) => { + const logger = new Logger('uncaughtException'); + logger.error({ + origin, + stderr: process.stderr.fd, + error, }); + }); - process.on('unhandledRejection', (error, origin) => { - const logger = new Logger('unhandledRejection'); - logger.error({ - origin, - stderr: process.stderr.fd, - error, - }); + process.on('unhandledRejection', (error, origin) => { + const logger = new Logger('unhandledRejection'); + logger.error({ + origin, + stderr: process.stderr.fd, + error, }); + }); } diff --git a/src/config/event.config.ts b/src/config/event.config.ts index ec917110..8451ffdf 100644 --- a/src/config/event.config.ts +++ b/src/config/event.config.ts @@ -1,7 +1,7 @@ import EventEmitter2 from 'eventemitter2'; export const eventEmitter = new EventEmitter2({ - delimiter: '.', - newListener: false, - ignoreErrors: false, + delimiter: '.', + newListener: false, + ignoreErrors: false, }); diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index 9fe6bac2..a5ca6a23 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -3,135 +3,135 @@ import dayjs from 'dayjs'; import { configService, Log } from './env.config'; const formatDateLog = (timestamp: number) => - dayjs(timestamp) - .toDate() - .toString() - .replace(/\sGMT.+/, ''); + dayjs(timestamp) + .toDate() + .toString() + .replace(/\sGMT.+/, ''); enum Color { - LOG = '\x1b[32m', - INFO = '\x1b[34m', - WARN = '\x1b[33m', - ERROR = '\x1b[31m', - DEBUG = '\x1b[36m', - VERBOSE = '\x1b[37m', - DARK = '\x1b[30m', + LOG = '\x1b[32m', + INFO = '\x1b[34m', + WARN = '\x1b[33m', + ERROR = '\x1b[31m', + DEBUG = '\x1b[36m', + VERBOSE = '\x1b[37m', + DARK = '\x1b[30m', } enum Command { - RESET = '\x1b[0m', - BRIGHT = '\x1b[1m', - UNDERSCORE = '\x1b[4m', + RESET = '\x1b[0m', + BRIGHT = '\x1b[1m', + UNDERSCORE = '\x1b[4m', } enum Level { - LOG = Color.LOG + '%s' + Command.RESET, - DARK = Color.DARK + '%s' + Command.RESET, - INFO = Color.INFO + '%s' + Command.RESET, - WARN = Color.WARN + '%s' + Command.RESET, - ERROR = Color.ERROR + '%s' + Command.RESET, - DEBUG = Color.DEBUG + '%s' + Command.RESET, - VERBOSE = Color.VERBOSE + '%s' + Command.RESET, + LOG = Color.LOG + '%s' + Command.RESET, + DARK = Color.DARK + '%s' + Command.RESET, + INFO = Color.INFO + '%s' + Command.RESET, + WARN = Color.WARN + '%s' + Command.RESET, + ERROR = Color.ERROR + '%s' + Command.RESET, + DEBUG = Color.DEBUG + '%s' + Command.RESET, + VERBOSE = Color.VERBOSE + '%s' + Command.RESET, } enum Type { - LOG = 'LOG', - WARN = 'WARN', - INFO = 'INFO', - DARK = 'DARK', - ERROR = 'ERROR', - DEBUG = 'DEBUG', - VERBOSE = 'VERBOSE', + LOG = 'LOG', + WARN = 'WARN', + INFO = 'INFO', + DARK = 'DARK', + ERROR = 'ERROR', + DEBUG = 'DEBUG', + VERBOSE = 'VERBOSE', } enum Background { - LOG = '\x1b[42m', - INFO = '\x1b[44m', - WARN = '\x1b[43m', - DARK = '\x1b[40m', - ERROR = '\x1b[41m', - DEBUG = '\x1b[46m', - VERBOSE = '\x1b[47m', + LOG = '\x1b[42m', + INFO = '\x1b[44m', + WARN = '\x1b[43m', + DARK = '\x1b[40m', + ERROR = '\x1b[41m', + DEBUG = '\x1b[46m', + VERBOSE = '\x1b[47m', } export class Logger { - private readonly configService = configService; - constructor(private context = 'Logger') {} + private readonly configService = configService; + constructor(private context = 'Logger') {} - public setContext(value: string) { - this.context = value; + public setContext(value: string) { + this.context = value; + } + + private console(value: any, type: Type) { + const types: Type[] = []; + + this.configService.get('LOG').LEVEL.forEach((level) => types.push(Type[level])); + + const typeValue = typeof value; + if (types.includes(type)) { + if (configService.get('LOG').COLOR) { + console.log( + /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], + '[Evolution API]', + Command.BRIGHT + Color[type], + process.pid.toString(), + Command.RESET, + Command.BRIGHT + Color[type], + '-', + Command.BRIGHT + Color.VERBOSE, + `${formatDateLog(Date.now())} `, + Command.RESET, + Color[type] + Background[type] + Command.BRIGHT, + `${type} ` + Command.RESET, + Color.WARN + Command.BRIGHT, + `[${this.context}]` + Command.RESET, + Color[type] + Command.BRIGHT, + `[${typeValue}]` + Command.RESET, + Color[type], + typeValue !== 'object' ? value : '', + Command.RESET, + ); + typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : ''; + } else { + console.log( + '[Evolution API]', + process.pid.toString(), + '-', + `${formatDateLog(Date.now())} `, + `${type} `, + `[${this.context}]`, + `[${typeValue}]`, + value, + ); + } } + } - private console(value: any, type: Type) { - const types: Type[] = []; + public log(value: any) { + this.console(value, Type.LOG); + } - this.configService.get('LOG').LEVEL.forEach((level) => types.push(Type[level])); + public info(value: any) { + this.console(value, Type.INFO); + } - const typeValue = typeof value; - if (types.includes(type)) { - if (configService.get('LOG').COLOR) { - console.log( - /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], - '[Evolution API]', - Command.BRIGHT + Color[type], - process.pid.toString(), - Command.RESET, - Command.BRIGHT + Color[type], - '-', - Command.BRIGHT + Color.VERBOSE, - `${formatDateLog(Date.now())} `, - Command.RESET, - Color[type] + Background[type] + Command.BRIGHT, - `${type} ` + Command.RESET, - Color.WARN + Command.BRIGHT, - `[${this.context}]` + Command.RESET, - Color[type] + Command.BRIGHT, - `[${typeValue}]` + Command.RESET, - Color[type], - typeValue !== 'object' ? value : '', - Command.RESET, - ); - typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : ''; - } else { - console.log( - '[Evolution API]', - process.pid.toString(), - '-', - `${formatDateLog(Date.now())} `, - `${type} `, - `[${this.context}]`, - `[${typeValue}]`, - value, - ); - } - } - } + public warn(value: any) { + this.console(value, Type.WARN); + } - public log(value: any) { - this.console(value, Type.LOG); - } + public error(value: any) { + this.console(value, Type.ERROR); + } - public info(value: any) { - this.console(value, Type.INFO); - } + public verbose(value: any) { + this.console(value, Type.VERBOSE); + } - public warn(value: any) { - this.console(value, Type.WARN); - } + public debug(value: any) { + this.console(value, Type.DEBUG); + } - public error(value: any) { - this.console(value, Type.ERROR); - } - - public verbose(value: any) { - this.console(value, Type.VERBOSE); - } - - public debug(value: any) { - this.console(value, Type.DEBUG); - } - - public dark(value: any) { - this.console(value, Type.DARK); - } + public dark(value: any) { + this.console(value, Type.DARK); + } } diff --git a/src/db/db.connect.ts b/src/db/db.connect.ts index e7e965ac..b11610c7 100644 --- a/src/db/db.connect.ts +++ b/src/db/db.connect.ts @@ -7,19 +7,19 @@ const logger = new Logger('MongoDB'); const db = configService.get('DATABASE'); export const dbserver = (() => { - if (db.ENABLED) { - logger.verbose('connecting'); - const dbs = mongoose.createConnection(db.CONNECTION.URI, { - dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api', - }); - logger.verbose('connected in ' + db.CONNECTION.URI); - logger.info('ON - dbName: ' + dbs['$dbName']); + if (db.ENABLED) { + logger.verbose('connecting'); + const dbs = mongoose.createConnection(db.CONNECTION.URI, { + dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api', + }); + logger.verbose('connected in ' + db.CONNECTION.URI); + logger.info('ON - dbName: ' + dbs['$dbName']); - process.on('beforeExit', () => { - logger.verbose('instance destroyed'); - dbserver.destroy(true, (error) => logger.error(error)); - }); + process.on('beforeExit', () => { + logger.verbose('instance destroyed'); + dbserver.destroy(true, (error) => logger.error(error)); + }); - return dbs; - } + return dbs; + } })(); diff --git a/src/db/redis.client.ts b/src/db/redis.client.ts index 5f0604bc..dffeb949 100644 --- a/src/db/redis.client.ts +++ b/src/db/redis.client.ts @@ -5,101 +5,101 @@ import { Redis } from '../config/env.config'; import { Logger } from '../config/logger.config'; export class RedisCache { - constructor() { - this.logger.verbose('instance created'); - process.on('beforeExit', async () => { - this.logger.verbose('instance destroyed'); - if (this.statusConnection) { - this.logger.verbose('instance disconnect'); - await this.client.disconnect(); - } - }); + constructor() { + this.logger.verbose('instance created'); + process.on('beforeExit', async () => { + this.logger.verbose('instance destroyed'); + if (this.statusConnection) { + this.logger.verbose('instance disconnect'); + await this.client.disconnect(); + } + }); + } + + private statusConnection = false; + private instanceName: string; + private redisEnv: Redis; + + public set reference(reference: string) { + this.logger.verbose('set reference: ' + reference); + this.instanceName = reference; + } + + public async connect(redisEnv: Redis) { + this.logger.verbose('connecting'); + this.client = createClient({ url: redisEnv.URI }); + this.logger.verbose('connected in ' + redisEnv.URI); + await this.client.connect(); + this.statusConnection = true; + this.redisEnv = redisEnv; + } + + private readonly logger = new Logger(RedisCache.name); + private client: RedisClientType; + + public async instanceKeys(): Promise { + try { + this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*'); + return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']); + } catch (error) { + this.logger.error(error); } + } - private statusConnection = false; - private instanceName: string; - private redisEnv: Redis; - - public set reference(reference: string) { - this.logger.verbose('set reference: ' + reference); - this.instanceName = reference; + public async keyExists(key?: string) { + if (key) { + this.logger.verbose('keyExists: ' + key); + return !!(await this.instanceKeys()).find((i) => i === key); } + this.logger.verbose('keyExists: ' + this.instanceName); + return !!(await this.instanceKeys()).find((i) => i === this.instanceName); + } - public async connect(redisEnv: Redis) { - this.logger.verbose('connecting'); - this.client = createClient({ url: redisEnv.URI }); - this.logger.verbose('connected in ' + redisEnv.URI); - await this.client.connect(); - this.statusConnection = true; - this.redisEnv = redisEnv; + public async writeData(field: string, data: any) { + try { + this.logger.verbose('writeData: ' + field); + const json = JSON.stringify(data, BufferJSON.replacer); + + return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json); + } catch (error) { + this.logger.error(error); } + } - private readonly logger = new Logger(RedisCache.name); - private client: RedisClientType; + public async readData(field: string) { + try { + this.logger.verbose('readData: ' + field); + const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); - public async instanceKeys(): Promise { - try { - this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*'); - return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']); - } catch (error) { - this.logger.error(error); - } + if (data) { + this.logger.verbose('readData: ' + field + ' success'); + return JSON.parse(data, BufferJSON.reviver); + } + + this.logger.verbose('readData: ' + field + ' not found'); + return null; + } catch (error) { + this.logger.error(error); } + } - public async keyExists(key?: string) { - if (key) { - this.logger.verbose('keyExists: ' + key); - return !!(await this.instanceKeys()).find((i) => i === key); - } - this.logger.verbose('keyExists: ' + this.instanceName); - return !!(await this.instanceKeys()).find((i) => i === this.instanceName); + public async removeData(field: string) { + try { + this.logger.verbose('removeData: ' + field); + return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); + } catch (error) { + this.logger.error(error); } + } - public async writeData(field: string, data: any) { - try { - this.logger.verbose('writeData: ' + field); - const json = JSON.stringify(data, BufferJSON.replacer); + public async delAll(hash?: string) { + try { + this.logger.verbose('instance delAll: ' + hash); + const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName); - return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json); - } catch (error) { - this.logger.error(error); - } - } - - public async readData(field: string) { - try { - this.logger.verbose('readData: ' + field); - const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); - - if (data) { - this.logger.verbose('readData: ' + field + ' success'); - return JSON.parse(data, BufferJSON.reviver); - } - - this.logger.verbose('readData: ' + field + ' not found'); - return null; - } catch (error) { - this.logger.error(error); - } - } - - public async removeData(field: string) { - try { - this.logger.verbose('removeData: ' + field); - return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); - } catch (error) { - this.logger.error(error); - } - } - - public async delAll(hash?: string) { - try { - this.logger.verbose('instance delAll: ' + hash); - const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName); - - return result; - } catch (error) { - this.logger.error(error); - } + return result; + } catch (error) { + this.logger.error(error); } + } } diff --git a/src/exceptions/400.exception.ts b/src/exceptions/400.exception.ts index 8b5c9c16..833295c1 100644 --- a/src/exceptions/400.exception.ts +++ b/src/exceptions/400.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class BadRequestException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.BAD_REQUEST, - error: 'Bad Request', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.BAD_REQUEST, + error: 'Bad Request', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/401.exception.ts b/src/exceptions/401.exception.ts index 97724396..72734d4e 100644 --- a/src/exceptions/401.exception.ts +++ b/src/exceptions/401.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class UnauthorizedException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.UNAUTHORIZED, - error: 'Unauthorized', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.UNAUTHORIZED, + error: 'Unauthorized', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/403.exception.ts b/src/exceptions/403.exception.ts index 9670fe25..f53ca9a5 100644 --- a/src/exceptions/403.exception.ts +++ b/src/exceptions/403.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class ForbiddenException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.FORBIDDEN, - error: 'Forbidden', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.FORBIDDEN, + error: 'Forbidden', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/404.exception.ts b/src/exceptions/404.exception.ts index 44181fe5..1119d1a1 100644 --- a/src/exceptions/404.exception.ts +++ b/src/exceptions/404.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class NotFoundException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.NOT_FOUND, - error: 'Not Found', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.NOT_FOUND, + error: 'Not Found', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/exceptions/500.exception.ts b/src/exceptions/500.exception.ts index 88d70573..2a41dfa5 100644 --- a/src/exceptions/500.exception.ts +++ b/src/exceptions/500.exception.ts @@ -1,11 +1,11 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class InternalServerErrorException { - constructor(...objectError: any[]) { - throw { - status: HttpStatus.INTERNAL_SERVER_ERROR, - error: 'Internal Server Error', - message: objectError.length > 0 ? objectError : undefined, - }; - } + constructor(...objectError: any[]) { + throw { + status: HttpStatus.INTERNAL_SERVER_ERROR, + error: 'Internal Server Error', + message: objectError.length > 0 ? objectError : undefined, + }; + } } diff --git a/src/main.ts b/src/main.ts index 5d70661e..b0d2e03e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,94 +15,94 @@ import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { - waMonitor.loadInstance(); + waMonitor.loadInstance(); } function bootstrap() { - const logger = new Logger('SERVER'); - const app = express(); + const logger = new Logger('SERVER'); + const app = express(); - // Sentry.init({ - // dsn: '', - // integrations: [ - // // enable HTTP calls tracing - // new Sentry.Integrations.Http({ tracing: true }), - // // enable Express.js middleware tracing - // new Sentry.Integrations.Express({ app }), - // // Automatically instrument Node.js libraries and frameworks - // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), - // ], + // Sentry.init({ + // dsn: '', + // integrations: [ + // // enable HTTP calls tracing + // new Sentry.Integrations.Http({ tracing: true }), + // // enable Express.js middleware tracing + // new Sentry.Integrations.Express({ app }), + // // Automatically instrument Node.js libraries and frameworks + // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), + // ], - // // Set tracesSampleRate to 1.0 to capture 100% - // // of transactions for performance monitoring. - // // We recommend adjusting this value in production - // tracesSampleRate: 1.0, - // }); + // // Set tracesSampleRate to 1.0 to capture 100% + // // of transactions for performance monitoring. + // // We recommend adjusting this value in production + // tracesSampleRate: 1.0, + // }); - // app.use(Sentry.Handlers.requestHandler()); + // app.use(Sentry.Handlers.requestHandler()); - // app.use(Sentry.Handlers.tracingHandler()); + // app.use(Sentry.Handlers.tracingHandler()); - app.use( - cors({ - origin(requestOrigin, callback) { - const { ORIGIN } = configService.get('CORS'); - !requestOrigin ? (requestOrigin = '*') : undefined; - if (ORIGIN.indexOf(requestOrigin) !== -1) { - return callback(null, true); - } - return callback(new Error('Not allowed by CORS')); - }, - methods: [...configService.get('CORS').METHODS], - credentials: configService.get('CORS').CREDENTIALS, - }), - urlencoded({ extended: true, limit: '136mb' }), - json({ limit: '136mb' }), - compression(), - ); + app.use( + cors({ + origin(requestOrigin, callback) { + const { ORIGIN } = configService.get('CORS'); + !requestOrigin ? (requestOrigin = '*') : undefined; + if (ORIGIN.indexOf(requestOrigin) !== -1) { + return callback(null, true); + } + return callback(new Error('Not allowed by CORS')); + }, + methods: [...configService.get('CORS').METHODS], + credentials: configService.get('CORS').CREDENTIALS, + }), + urlencoded({ extended: true, limit: '136mb' }), + json({ limit: '136mb' }), + compression(), + ); - app.set('view engine', 'hbs'); - app.set('views', join(ROOT_DIR, 'views')); - app.use(express.static(join(ROOT_DIR, 'public'))); + app.set('view engine', 'hbs'); + app.set('views', join(ROOT_DIR, 'views')); + app.use(express.static(join(ROOT_DIR, 'public'))); - app.use('/', router); + app.use('/', router); - // app.use(Sentry.Handlers.errorHandler()); + // app.use(Sentry.Handlers.errorHandler()); - // app.use(function onError(err, req, res, next) { - // res.statusCode = 500; - // res.end(res.sentry + '\n'); - // }); + // app.use(function onError(err, req, res, next) { + // res.statusCode = 500; + // res.end(res.sentry + '\n'); + // }); - app.use( - (err: Error, req: Request, res: Response) => { - if (err) { - return res.status(err['status'] || 500).json(err); - } - }, - (req: Request, res: Response, next: NextFunction) => { - const { method, url } = req; + app.use( + (err: Error, req: Request, res: Response) => { + if (err) { + return res.status(err['status'] || 500).json(err); + } + }, + (req: Request, res: Response, next: NextFunction) => { + const { method, url } = req; - res.status(HttpStatus.NOT_FOUND).json({ - status: HttpStatus.NOT_FOUND, - message: `Cannot ${method.toUpperCase()} ${url}`, - error: 'Not Found', - }); + res.status(HttpStatus.NOT_FOUND).json({ + status: HttpStatus.NOT_FOUND, + message: `Cannot ${method.toUpperCase()} ${url}`, + error: 'Not Found', + }); - next(); - }, - ); + next(); + }, + ); - const httpServer = configService.get('SERVER'); + const httpServer = configService.get('SERVER'); - ServerUP.app = app; - const server = ServerUP[httpServer.TYPE]; + ServerUP.app = app; + const server = ServerUP[httpServer.TYPE]; - server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); + server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); - initWA(); + initWA(); - onUnexpectedError(); + onUnexpectedError(); } bootstrap(); diff --git a/src/utils/server-up.ts b/src/utils/server-up.ts index a6205249..e06caea7 100644 --- a/src/utils/server-up.ts +++ b/src/utils/server-up.ts @@ -6,24 +6,24 @@ import * as https from 'https'; import { configService, SslConf } from '../config/env.config'; export class ServerUP { - static #app: Express; + static #app: Express; - static set app(e: Express) { - this.#app = e; - } + static set app(e: Express) { + this.#app = e; + } - static get https() { - const { FULLCHAIN, PRIVKEY } = configService.get('SSL_CONF'); - return https.createServer( - { - cert: readFileSync(FULLCHAIN), - key: readFileSync(PRIVKEY), - }, - ServerUP.#app, - ); - } + static get https() { + const { FULLCHAIN, PRIVKEY } = configService.get('SSL_CONF'); + return https.createServer( + { + cert: readFileSync(FULLCHAIN), + key: readFileSync(PRIVKEY), + }, + ServerUP.#app, + ); + } - static get http() { - return http.createServer(ServerUP.#app); - } + static get http() { + return http.createServer(ServerUP.#app); + } } diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index a372fbcf..8b0d76e4 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -1,10 +1,10 @@ import { - AuthenticationCreds, - AuthenticationState, - BufferJSON, - initAuthCreds, - proto, - SignalDataTypeMap, + AuthenticationCreds, + AuthenticationState, + BufferJSON, + initAuthCreds, + proto, + SignalDataTypeMap, } from '@whiskeysockets/baileys'; import { configService, Database } from '../config/env.config'; @@ -12,86 +12,86 @@ import { Logger } from '../config/logger.config'; import { dbserver } from '../db/db.connect'; export async function useMultiFileAuthStateDb( - coll: string, + coll: string, ): Promise<{ state: AuthenticationState; saveCreds: () => Promise }> { - const logger = new Logger(useMultiFileAuthStateDb.name); + const logger = new Logger(useMultiFileAuthStateDb.name); - const client = dbserver.getClient(); + const client = dbserver.getClient(); - const collection = client - .db(configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(coll); + const collection = client + .db(configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(coll); - const writeData = async (data: any, key: string): Promise => { - try { - await client.connect(); - return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), { - upsert: true, - }); - } catch (error) { - logger.error(error); - } - }; + const writeData = async (data: any, key: string): Promise => { + try { + await client.connect(); + return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), { + upsert: true, + }); + } catch (error) { + logger.error(error); + } + }; - const readData = async (key: string): Promise => { - try { - await client.connect(); - const data = await collection.findOne({ _id: key }); - const creds = JSON.stringify(data); - return JSON.parse(creds, BufferJSON.reviver); - } catch (error) { - logger.error(error); - } - }; + const readData = async (key: string): Promise => { + try { + await client.connect(); + const data = await collection.findOne({ _id: key }); + const creds = JSON.stringify(data); + return JSON.parse(creds, BufferJSON.reviver); + } catch (error) { + logger.error(error); + } + }; - const removeData = async (key: string) => { - try { - await client.connect(); - return await collection.deleteOne({ _id: key }); - } catch (error) { - logger.error(error); - } - }; + const removeData = async (key: string) => { + try { + await client.connect(); + return await collection.deleteOne({ _id: key }); + } catch (error) { + logger.error(error); + } + }; - const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); + const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); - return { - state: { - creds, - keys: { - get: async (type, ids: string[]) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const data: { [_: string]: SignalDataTypeMap[type] } = {}; - await Promise.all( - ids.map(async (id) => { - let value = await readData(`${type}-${id}`); - if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.fromObject(value); - } + return { + state: { + creds, + keys: { + get: async (type, ids: string[]) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const data: { [_: string]: SignalDataTypeMap[type] } = {}; + await Promise.all( + ids.map(async (id) => { + let value = await readData(`${type}-${id}`); + if (type === 'app-state-sync-key' && value) { + value = proto.Message.AppStateSyncKeyData.fromObject(value); + } - data[id] = value; - }), - ); + data[id] = value; + }), + ); - return data; - }, - set: async (data: any) => { - const tasks: Promise[] = []; - for (const category in data) { - for (const id in data[category]) { - const value = data[category][id]; - const key = `${category}-${id}`; - tasks.push(value ? writeData(value, key) : removeData(key)); - } - } - - await Promise.all(tasks); - }, - }, + return data; }, - saveCreds: async () => { - return writeData(creds, 'creds'); + set: async (data: any) => { + const tasks: Promise[] = []; + for (const category in data) { + for (const id in data[category]) { + const value = data[category][id]; + const key = `${category}-${id}`; + tasks.push(value ? writeData(value, key) : removeData(key)); + } + } + + await Promise.all(tasks); }, - }; + }, + }, + saveCreds: async () => { + return writeData(creds, 'creds'); + }, + }; } diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index f26d7d02..57439ced 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -1,84 +1,84 @@ import { - AuthenticationCreds, - AuthenticationState, - initAuthCreds, - proto, - SignalDataTypeMap, + AuthenticationCreds, + AuthenticationState, + initAuthCreds, + proto, + SignalDataTypeMap, } from '@whiskeysockets/baileys'; import { Logger } from '../config/logger.config'; import { RedisCache } from '../db/redis.client'; export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{ - state: AuthenticationState; - saveCreds: () => Promise; + state: AuthenticationState; + saveCreds: () => Promise; }> { - const logger = new Logger(useMultiFileAuthStateRedisDb.name); + const logger = new Logger(useMultiFileAuthStateRedisDb.name); - const writeData = async (data: any, key: string): Promise => { - try { - return await cache.writeData(key, data); - } catch (error) { - return logger.error({ localError: 'writeData', error }); - } - }; + const writeData = async (data: any, key: string): Promise => { + try { + return await cache.writeData(key, data); + } catch (error) { + return logger.error({ localError: 'writeData', error }); + } + }; - const readData = async (key: string): Promise => { - try { - return await cache.readData(key); - } catch (error) { - logger.error({ readData: 'writeData', error }); - return; - } - }; + const readData = async (key: string): Promise => { + try { + return await cache.readData(key); + } catch (error) { + logger.error({ readData: 'writeData', error }); + return; + } + }; - const removeData = async (key: string) => { - try { - return await cache.removeData(key); - } catch (error) { - logger.error({ readData: 'removeData', error }); - } - }; + const removeData = async (key: string) => { + try { + return await cache.removeData(key); + } catch (error) { + logger.error({ readData: 'removeData', error }); + } + }; - const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); + const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); - return { - state: { - creds, - keys: { - get: async (type, ids: string[]) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const data: { [_: string]: SignalDataTypeMap[type] } = {}; - await Promise.all( - ids.map(async (id) => { - let value = await readData(`${type}-${id}`); - if (type === 'app-state-sync-key' && value) { - value = proto.Message.AppStateSyncKeyData.fromObject(value); - } + return { + state: { + creds, + keys: { + get: async (type, ids: string[]) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const data: { [_: string]: SignalDataTypeMap[type] } = {}; + await Promise.all( + ids.map(async (id) => { + let value = await readData(`${type}-${id}`); + if (type === 'app-state-sync-key' && value) { + value = proto.Message.AppStateSyncKeyData.fromObject(value); + } - data[id] = value; - }), - ); + data[id] = value; + }), + ); - return data; - }, - set: async (data: any) => { - const tasks: Promise[] = []; - for (const category in data) { - for (const id in data[category]) { - const value = data[category][id]; - const key = `${category}-${id}`; - tasks.push(value ? await writeData(value, key) : await removeData(key)); - } - } - - await Promise.all(tasks); - }, - }, + return data; }, - saveCreds: async () => { - return await writeData(creds, 'creds'); + set: async (data: any) => { + const tasks: Promise[] = []; + for (const category in data) { + for (const id in data[category]) { + const value = data[category][id]; + const key = `${category}-${id}`; + tasks.push(value ? await writeData(value, key) : await removeData(key)); + } + } + + await Promise.all(tasks); }, - }; + }, + }, + saveCreds: async () => { + return await writeData(creds, 'creds'); + }, + }; } diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 8e021116..8c1a4667 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -2,896 +2,896 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; import { v4 } from 'uuid'; const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => { - const properties = {}; - propertyNames.forEach( - (property) => - (properties[property] = { - minLength: 1, - description: `The "${property}" cannot be empty`, - }), - ); - return { - if: { - propertyNames: { - enum: [...propertyNames], - }, - }, - then: { properties }, - }; + const properties = {}; + propertyNames.forEach( + (property) => + (properties[property] = { + minLength: 1, + description: `The "${property}" cannot be empty`, + }), + ); + return { + if: { + propertyNames: { + enum: [...propertyNames], + }, + }, + then: { properties }, + }; }; // Instance Schema export const instanceNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - instanceName: { type: 'string' }, - webhook: { type: 'string' }, - webhook_by_events: { type: 'boolean' }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'CALL', - 'NEW_JWT_TOKEN', - ], - }, - }, - qrcode: { type: 'boolean', enum: [true, false] }, - number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, - token: { type: 'string' }, + $id: v4(), + type: 'object', + properties: { + instanceName: { type: 'string' }, + webhook: { type: 'string' }, + webhook_by_events: { type: 'boolean' }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, }, - ...isNotEmpty('instanceName'), + qrcode: { type: 'boolean', enum: [true, false] }, + number: { type: 'string', pattern: '^\\d+[\\.@\\w-]+' }, + token: { type: 'string' }, + }, + ...isNotEmpty('instanceName'), }; export const oldTokenSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - oldToken: { type: 'string' }, - }, - required: ['oldToken'], - ...isNotEmpty('oldToken'), + $id: v4(), + type: 'object', + properties: { + oldToken: { type: 'string' }, + }, + required: ['oldToken'], + ...isNotEmpty('oldToken'), }; const quotedOptionsSchema: JSONSchema7 = { - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id'], - ...isNotEmpty('id'), - }, - message: { type: 'object' }, + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id'], + ...isNotEmpty('id'), }, + message: { type: 'object' }, + }, }; const mentionsOptionsSchema: JSONSchema7 = { - properties: { - everyOne: { type: 'boolean', enum: [true, false] }, - mentioned: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"mentioned" must be an array of numeric strings', - }, - }, + properties: { + everyOne: { type: 'boolean', enum: [true, false] }, + mentioned: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"mentioned" must be an array of numeric strings', + }, }, + }, }; // Send Message Schema const optionsSchema: JSONSchema7 = { - properties: { - delay: { - type: 'integer', - description: 'Enter a value in milliseconds', - }, - presence: { - type: 'string', - enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], - }, - quoted: { ...quotedOptionsSchema }, - mentions: { ...mentionsOptionsSchema }, + properties: { + delay: { + type: 'integer', + description: 'Enter a value in milliseconds', }, + presence: { + type: 'string', + enum: ['unavailable', 'available', 'composing', 'recording', 'paused'], + }, + quoted: { ...quotedOptionsSchema }, + mentions: { ...mentionsOptionsSchema }, + }, }; const numberDefinition: JSONSchema7Definition = { - type: 'string', - description: 'Invalid format', + type: 'string', + description: 'Invalid format', }; export const textMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - textMessage: { - type: 'object', - properties: { - text: { type: 'string' }, - }, - required: ['text'], - ...isNotEmpty('text'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + textMessage: { + type: 'object', + properties: { + text: { type: 'string' }, + }, + required: ['text'], + ...isNotEmpty('text'), }, - required: ['textMessage', 'number'], + }, + required: ['textMessage', 'number'], }; export const pollMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - pollMessage: { - type: 'object', - properties: { - name: { type: 'string' }, - selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, - values: { - type: 'array', - minItems: 2, - maxItems: 10, - uniqueItems: true, - items: { - type: 'string', - }, - }, - }, - required: ['name', 'selectableCount', 'values'], - ...isNotEmpty('name', 'selectableCount', 'values'), + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + pollMessage: { + type: 'object', + properties: { + name: { type: 'string' }, + selectableCount: { type: 'integer', minimum: 0, maximum: 10 }, + values: { + type: 'array', + minItems: 2, + maxItems: 10, + uniqueItems: true, + items: { + type: 'string', + }, }, + }, + required: ['name', 'selectableCount', 'values'], + ...isNotEmpty('name', 'selectableCount', 'values'), }, - required: ['pollMessage', 'number'], + }, + required: ['pollMessage', 'number'], }; export const statusMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - statusMessage: { - type: 'object', - properties: { - type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, - content: { type: 'string' }, - caption: { type: 'string' }, - backgroundColor: { type: 'string' }, - font: { type: 'integer', minimum: 0, maximum: 5 }, - statusJidList: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - pattern: '^\\d+', - description: '"statusJidList" must be an array of numeric strings', - }, - }, - allContacts: { type: 'boolean', enum: [true, false] }, - }, - required: ['type', 'content'], - ...isNotEmpty('type', 'content'), + $id: v4(), + type: 'object', + properties: { + statusMessage: { + type: 'object', + properties: { + type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] }, + content: { type: 'string' }, + caption: { type: 'string' }, + backgroundColor: { type: 'string' }, + font: { type: 'integer', minimum: 0, maximum: 5 }, + statusJidList: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"statusJidList" must be an array of numeric strings', + }, }, + allContacts: { type: 'boolean', enum: [true, false] }, + }, + required: ['type', 'content'], + ...isNotEmpty('type', 'content'), }, - required: ['statusMessage'], + }, + required: ['statusMessage'], }; export const mediaMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - mediaMessage: { - type: 'object', - properties: { - mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, - media: { type: 'string' }, - fileName: { type: 'string' }, - caption: { type: 'string' }, - }, - required: ['mediatype', 'media'], - ...isNotEmpty('fileName', 'caption', 'media'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + mediaMessage: { + type: 'object', + properties: { + mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] }, + media: { type: 'string' }, + fileName: { type: 'string' }, + caption: { type: 'string' }, + }, + required: ['mediatype', 'media'], + ...isNotEmpty('fileName', 'caption', 'media'), }, - required: ['mediaMessage', 'number'], + }, + required: ['mediaMessage', 'number'], }; export const stickerMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - stickerMessage: { - type: 'object', - properties: { - image: { type: 'string' }, - }, - required: ['image'], - ...isNotEmpty('image'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + stickerMessage: { + type: 'object', + properties: { + image: { type: 'string' }, + }, + required: ['image'], + ...isNotEmpty('image'), }, - required: ['stickerMessage', 'number'], + }, + required: ['stickerMessage', 'number'], }; export const audioMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - audioMessage: { - type: 'object', - properties: { - audio: { type: 'string' }, - }, - required: ['audio'], - ...isNotEmpty('audio'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + audioMessage: { + type: 'object', + properties: { + audio: { type: 'string' }, + }, + required: ['audio'], + ...isNotEmpty('audio'), }, - required: ['audioMessage', 'number'], + }, + required: ['audioMessage', 'number'], }; export const buttonMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - buttonMessage: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + buttonMessage: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttons: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { type: 'object', properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttons: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - buttonText: { type: 'string' }, - buttonId: { type: 'string' }, - }, - required: ['buttonText', 'buttonId'], - ...isNotEmpty('buttonText', 'buttonId'), - }, - }, - mediaMessage: { - type: 'object', - properties: { - media: { type: 'string' }, - fileName: { type: 'string' }, - mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, - }, - required: ['media', 'mediatype'], - ...isNotEmpty('media', 'fileName'), - }, + buttonText: { type: 'string' }, + buttonId: { type: 'string' }, }, - required: ['title', 'buttons'], - ...isNotEmpty('title', 'description'), + required: ['buttonText', 'buttonId'], + ...isNotEmpty('buttonText', 'buttonId'), + }, }, + mediaMessage: { + type: 'object', + properties: { + media: { type: 'string' }, + fileName: { type: 'string' }, + mediatype: { type: 'string', enum: ['image', 'document', 'video'] }, + }, + required: ['media', 'mediatype'], + ...isNotEmpty('media', 'fileName'), + }, + }, + required: ['title', 'buttons'], + ...isNotEmpty('title', 'description'), }, - required: ['number', 'buttonMessage'], + }, + required: ['number', 'buttonMessage'], }; export const locationMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - locationMessage: { - type: 'object', - properties: { - latitude: { type: 'number' }, - longitude: { type: 'number' }, - name: { type: 'string' }, - address: { type: 'string' }, - }, - required: ['latitude', 'longitude'], - ...isNotEmpty('name', 'addresss'), - }, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + locationMessage: { + type: 'object', + properties: { + latitude: { type: 'number' }, + longitude: { type: 'number' }, + name: { type: 'string' }, + address: { type: 'string' }, + }, + required: ['latitude', 'longitude'], + ...isNotEmpty('name', 'addresss'), }, - required: ['number', 'locationMessage'], + }, + required: ['number', 'locationMessage'], }; export const listMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - listMessage: { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + listMessage: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + footerText: { type: 'string' }, + buttonText: { type: 'string' }, + sections: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { type: 'object', properties: { - title: { type: 'string' }, - description: { type: 'string' }, - footerText: { type: 'string' }, - buttonText: { type: 'string' }, - sections: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - rows: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'object', - properties: { - title: { type: 'string' }, - description: { type: 'string' }, - rowId: { type: 'string' }, - }, - required: ['title', 'description', 'rowId'], - ...isNotEmpty('title', 'description', 'rowId'), - }, - }, - }, - required: ['title', 'rows'], - ...isNotEmpty('title'), - }, + title: { type: 'string' }, + rows: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'object', + properties: { + title: { type: 'string' }, + description: { type: 'string' }, + rowId: { type: 'string' }, + }, + required: ['title', 'description', 'rowId'], + ...isNotEmpty('title', 'description', 'rowId'), }, + }, }, - required: ['title', 'description', 'buttonText', 'sections'], - ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), + required: ['title', 'rows'], + ...isNotEmpty('title'), + }, }, + }, + required: ['title', 'description', 'buttonText', 'sections'], + ...isNotEmpty('title', 'description', 'buttonText', 'footerText'), }, - required: ['number', 'listMessage'], + }, + required: ['number', 'listMessage'], }; export const contactMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - contactMessage: { - type: 'array', - items: { - type: 'object', - properties: { - fullName: { type: 'string' }, - wuid: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"wuid" must be a numeric string', - }, - phoneNumber: { type: 'string', minLength: 10 }, - organization: { type: 'string' }, - email: { type: 'string' }, - url: { type: 'string' }, - }, - required: ['fullName', 'phoneNumber'], - ...isNotEmpty('fullName'), - }, - minItems: 1, - uniqueItems: true, + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema }, + contactMessage: { + type: 'array', + items: { + type: 'object', + properties: { + fullName: { type: 'string' }, + wuid: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"wuid" must be a numeric string', + }, + phoneNumber: { type: 'string', minLength: 10 }, + organization: { type: 'string' }, + email: { type: 'string' }, + url: { type: 'string' }, }, + required: ['fullName', 'phoneNumber'], + ...isNotEmpty('fullName'), + }, + minItems: 1, + uniqueItems: true, }, - required: ['number', 'contactMessage'], + }, + required: ['number', 'contactMessage'], }; export const reactionMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reactionMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'remoteJid', 'fromMe'], - ...isNotEmpty('id', 'remoteJid'), - }, - reaction: { type: 'string' }, - }, - required: ['key', 'reaction'], - ...isNotEmpty('reaction'), + $id: v4(), + type: 'object', + properties: { + reactionMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'remoteJid', 'fromMe'], + ...isNotEmpty('id', 'remoteJid'), }, + reaction: { type: 'string' }, + }, + required: ['key', 'reaction'], + ...isNotEmpty('reaction'), }, - required: ['reactionMessage'], + }, + required: ['reactionMessage'], }; // Chat Schema export const whatsappNumberSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - description: '"numbers" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + description: '"numbers" must be an array of numeric strings', + }, }, + }, }; export const readMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - read_messages: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, + $id: v4(), + type: 'object', + properties: { + read_messages: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, }, - required: ['read_messages'], + }, + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - privacySettings: { - type: 'object', - properties: { - readreceipts: { type: 'string', enum: ['all', 'none'] }, - profile: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - status: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - online: { type: 'string', enum: ['all', 'match_last_seen'] }, - last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, - groupadd: { - type: 'string', - enum: ['all', 'contacts', 'contact_blacklist', 'none'], - }, - }, - required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], - ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), + $id: v4(), + type: 'object', + properties: { + privacySettings: { + type: 'object', + properties: { + readreceipts: { type: 'string', enum: ['all', 'none'] }, + profile: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], }, + status: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + online: { type: 'string', enum: ['all', 'match_last_seen'] }, + last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] }, + groupadd: { + type: 'string', + enum: ['all', 'contacts', 'contact_blacklist', 'none'], + }, + }, + required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'], + ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'), }, - required: ['privacySettings'], + }, + required: ['privacySettings'], }; export const archiveChatSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - lastMessage: { - type: 'object', - properties: { - key: { - type: 'object', - properties: { - id: { type: 'string' }, - remoteJid: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid'), - }, - messageTimestamp: { type: 'integer', minLength: 1 }, - }, - required: ['key'], - ...isNotEmpty('messageTimestamp'), + $id: v4(), + type: 'object', + properties: { + lastMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), }, - archive: { type: 'boolean', enum: [true, false] }, + messageTimestamp: { type: 'integer', minLength: 1 }, + }, + required: ['key'], + ...isNotEmpty('messageTimestamp'), }, - required: ['lastMessage', 'archive'], + archive: { type: 'boolean', enum: [true, false] }, + }, + required: ['lastMessage', 'archive'], }; export const deleteMessageSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - remoteJid: { type: 'string' }, - participant: { type: 'string' }, - }, - required: ['id', 'fromMe', 'remoteJid'], - ...isNotEmpty('id', 'remoteJid', 'participant'), + $id: v4(), + type: 'object', + properties: { + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + remoteJid: { type: 'string' }, + participant: { type: 'string' }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid', 'participant'), }; export const contactValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - pushName: { type: 'string', minLength: 1 }, - id: { type: 'string', minLength: 1 }, - }, - ...isNotEmpty('_id', 'id', 'pushName'), - }, + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + pushName: { type: 'string', minLength: 1 }, + id: { type: 'string', minLength: 1 }, + }, + ...isNotEmpty('_id', 'id', 'pushName'), }, + }, }; export const profileNameSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - name: { type: 'string' }, - }, - ...isNotEmpty('name'), + $id: v4(), + type: 'object', + properties: { + name: { type: 'string' }, + }, + ...isNotEmpty('name'), }; export const profileStatusSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - status: { type: 'string' }, - }, - ...isNotEmpty('status'), + $id: v4(), + type: 'object', + properties: { + status: { type: 'string' }, + }, + ...isNotEmpty('status'), }; export const profilePictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { type: 'string' }, - picture: { type: 'string' }, - }, + $id: v4(), + type: 'object', + properties: { + number: { type: 'string' }, + picture: { type: 'string' }, + }, }; export const profileSchema: JSONSchema7 = { - type: 'object', - properties: { - wuid: { type: 'string' }, - name: { type: 'string' }, - picture: { type: 'string' }, - status: { type: 'string' }, - isBusiness: { type: 'boolean' }, - }, + type: 'object', + properties: { + wuid: { type: 'string' }, + name: { type: 'string' }, + picture: { type: 'string' }, + status: { type: 'string' }, + isBusiness: { type: 'boolean' }, + }, }; export const messageValidateSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string', minLength: 1 }, - key: { - type: 'object', - if: { - propertyNames: { - enum: ['fromMe', 'remoteJid', 'id'], - }, - }, - then: { - properties: { - remoteJid: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - id: { - type: 'string', - minLength: 1, - description: 'The property cannot be empty', - }, - fromMe: { type: 'boolean', enum: [true, false] }, - }, - }, - }, - message: { type: 'object' }, + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string', minLength: 1 }, + key: { + type: 'object', + if: { + propertyNames: { + enum: ['fromMe', 'remoteJid', 'id'], }, - ...isNotEmpty('_id'), + }, + then: { + properties: { + remoteJid: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + id: { + type: 'string', + minLength: 1, + description: 'The property cannot be empty', + }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + }, }, - limit: { type: 'integer' }, + message: { type: 'object' }, + }, + ...isNotEmpty('_id'), }, + limit: { type: 'integer' }, + }, }; export const messageUpSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - where: { - type: 'object', - properties: { - _id: { type: 'string' }, - remoteJid: { type: 'string' }, - id: { type: 'string' }, - fromMe: { type: 'boolean', enum: [true, false] }, - participant: { type: 'string' }, - status: { - type: 'string', - enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], - }, - }, - ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), + $id: v4(), + type: 'object', + properties: { + where: { + type: 'object', + properties: { + _id: { type: 'string' }, + remoteJid: { type: 'string' }, + id: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + participant: { type: 'string' }, + status: { + type: 'string', + enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'], }, - limit: { type: 'integer' }, + }, + ...isNotEmpty('_id', 'remoteJid', 'id', 'status'), }, + limit: { type: 'integer' }, + }, }; // Group Schema export const createGroupSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - subject: { type: 'string' }, - description: { type: 'string' }, - profilePicture: { type: 'string' }, - promoteParticipants: { type: 'boolean', enum: [true, false] }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + subject: { type: 'string' }, + description: { type: 'string' }, + profilePicture: { type: 'string' }, + promoteParticipants: { type: 'boolean', enum: [true, false] }, + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, }, - required: ['subject', 'participants'], - ...isNotEmpty('subject', 'description', 'profilePicture'), + }, + required: ['subject', 'participants'], + ...isNotEmpty('subject', 'description', 'profilePicture'), }; export const groupJidSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, - }, - required: ['groupJid'], - ...isNotEmpty('groupJid'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string', pattern: '^[\\d-]+@g.us$' }, + }, + required: ['groupJid'], + ...isNotEmpty('groupJid'), }; export const getParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - getParticipants: { type: 'string', enum: ['true', 'false'] }, - }, - required: ['getParticipants'], - ...isNotEmpty('getParticipants'), + $id: v4(), + type: 'object', + properties: { + getParticipants: { type: 'string', enum: ['true', 'false'] }, + }, + required: ['getParticipants'], + ...isNotEmpty('getParticipants'), }; export const groupSendInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - numbers: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"numbers" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + numbers: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"numbers" must be an array of numeric strings', + }, }, - required: ['groupJid', 'description', 'numbers'], - ...isNotEmpty('groupJid', 'description', 'numbers'), + }, + required: ['groupJid', 'description', 'numbers'], + ...isNotEmpty('groupJid', 'description', 'numbers'), }; export const groupInviteSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, - }, - required: ['inviteCode'], - ...isNotEmpty('inviteCode'), + $id: v4(), + type: 'object', + properties: { + inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' }, + }, + required: ['inviteCode'], + ...isNotEmpty('inviteCode'), }; export const updateParticipantsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['add', 'remove', 'promote', 'demote'], - }, - participants: { - type: 'array', - minItems: 1, - uniqueItems: true, - items: { - type: 'string', - minLength: 10, - pattern: '\\d+', - description: '"participants" must be an array of numeric strings', - }, - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['add', 'remove', 'promote', 'demote'], }, - required: ['groupJid', 'action', 'participants'], - ...isNotEmpty('groupJid', 'action'), + participants: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + minLength: 10, + pattern: '\\d+', + description: '"participants" must be an array of numeric strings', + }, + }, + }, + required: ['groupJid', 'action', 'participants'], + ...isNotEmpty('groupJid', 'action'), }; export const updateSettingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - action: { - type: 'string', - enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + action: { + type: 'string', + enum: ['announcement', 'not_announcement', 'locked', 'unlocked'], }, - required: ['groupJid', 'action'], - ...isNotEmpty('groupJid', 'action'), + }, + required: ['groupJid', 'action'], + ...isNotEmpty('groupJid', 'action'), }; export const toggleEphemeralSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - expiration: { - type: 'number', - enum: [0, 86400, 604800, 7776000], - }, + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + expiration: { + type: 'number', + enum: [0, 86400, 604800, 7776000], }, - required: ['groupJid', 'expiration'], - ...isNotEmpty('groupJid', 'expiration'), + }, + required: ['groupJid', 'expiration'], + ...isNotEmpty('groupJid', 'expiration'), }; export const updateGroupPictureSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - image: { type: 'string' }, - }, - required: ['groupJid', 'image'], - ...isNotEmpty('groupJid', 'image'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + image: { type: 'string' }, + }, + required: ['groupJid', 'image'], + ...isNotEmpty('groupJid', 'image'), }; export const updateGroupSubjectSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - subject: { type: 'string' }, - }, - required: ['groupJid', 'subject'], - ...isNotEmpty('groupJid', 'subject'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + subject: { type: 'string' }, + }, + required: ['groupJid', 'subject'], + ...isNotEmpty('groupJid', 'subject'), }; export const updateGroupDescriptionSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - groupJid: { type: 'string' }, - description: { type: 'string' }, - }, - required: ['groupJid', 'description'], - ...isNotEmpty('groupJid', 'description'), + $id: v4(), + type: 'object', + properties: { + groupJid: { type: 'string' }, + description: { type: 'string' }, + }, + required: ['groupJid', 'description'], + ...isNotEmpty('groupJid', 'description'), }; // Webhook Schema export const webhookSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - url: { type: 'string' }, - enabled: { type: 'boolean', enum: [true, false] }, - events: { - type: 'array', - minItems: 0, - items: { - type: 'string', - enum: [ - 'APPLICATION_STARTUP', - 'QRCODE_UPDATED', - 'MESSAGES_SET', - 'MESSAGES_UPSERT', - 'MESSAGES_UPDATE', - 'MESSAGES_DELETE', - 'SEND_MESSAGE', - 'CONTACTS_SET', - 'CONTACTS_UPSERT', - 'CONTACTS_UPDATE', - 'PRESENCE_UPDATE', - 'CHATS_SET', - 'CHATS_UPSERT', - 'CHATS_UPDATE', - 'CHATS_DELETE', - 'GROUPS_UPSERT', - 'GROUP_UPDATE', - 'GROUP_PARTICIPANTS_UPDATE', - 'CONNECTION_UPDATE', - 'CALL', - 'NEW_JWT_TOKEN', - ], - }, - }, + $id: v4(), + type: 'object', + properties: { + url: { type: 'string' }, + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, }, - required: ['url', 'enabled'], - ...isNotEmpty('url'), + }, + required: ['url', 'enabled'], + ...isNotEmpty('url'), }; export const chatwootSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - enabled: { type: 'boolean', enum: [true, false] }, - account_id: { type: 'string' }, - token: { type: 'string' }, - url: { type: 'string' }, - sign_msg: { type: 'boolean', enum: [true, false] }, - reopen_conversation: { type: 'boolean', enum: [true, false] }, - conversation_pending: { type: 'boolean', enum: [true, false] }, - }, - required: ['enabled', 'account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'], - ...isNotEmpty('account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'), + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + account_id: { type: 'string' }, + token: { type: 'string' }, + url: { type: 'string' }, + sign_msg: { type: 'boolean', enum: [true, false] }, + reopen_conversation: { type: 'boolean', enum: [true, false] }, + conversation_pending: { type: 'boolean', enum: [true, false] }, + }, + required: ['enabled', 'account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'], + ...isNotEmpty('account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'), }; export const settingsSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - reject_call: { type: 'boolean', enum: [true, false] }, - msg_call: { type: 'string' }, - groups_ignore: { type: 'boolean', enum: [true, false] }, - always_online: { type: 'boolean', enum: [true, false] }, - read_messages: { type: 'boolean', enum: [true, false] }, - read_status: { type: 'boolean', enum: [true, false] }, - }, - required: ['reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'], - ...isNotEmpty('reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'), + $id: v4(), + type: 'object', + properties: { + reject_call: { type: 'boolean', enum: [true, false] }, + msg_call: { type: 'string' }, + groups_ignore: { type: 'boolean', enum: [true, false] }, + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, + }, + required: ['reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'], + ...isNotEmpty('reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'), }; diff --git a/src/whatsapp/abstract/abstract.repository.ts b/src/whatsapp/abstract/abstract.repository.ts index 739489eb..a5b7a841 100644 --- a/src/whatsapp/abstract/abstract.repository.ts +++ b/src/whatsapp/abstract/abstract.repository.ts @@ -7,61 +7,61 @@ import { ROOT_DIR } from '../../config/path.config'; export type IInsert = { insertCount: number }; export interface IRepository { - insert(data: any, instanceName: string, saveDb?: boolean): Promise; - update(data: any, instanceName: string, saveDb?: boolean): Promise; - find(query: any): Promise; - delete(query: any, force?: boolean): Promise; + insert(data: any, instanceName: string, saveDb?: boolean): Promise; + update(data: any, instanceName: string, saveDb?: boolean): Promise; + find(query: any): Promise; + delete(query: any, force?: boolean): Promise; - dbSettings: Database; - readonly storePath: string; + dbSettings: Database; + readonly storePath: string; } type WriteStore = { - path: string; - fileName: string; - data: U; + path: string; + fileName: string; + data: U; }; export abstract class Repository implements IRepository { - constructor(configService: ConfigService) { - this.dbSettings = configService.get('DATABASE'); + constructor(configService: ConfigService) { + this.dbSettings = configService.get('DATABASE'); + } + + dbSettings: Database; + readonly storePath = join(ROOT_DIR, 'store'); + + public writeStore = (create: WriteStore) => { + if (!existsSync(create.path)) { + mkdirSync(create.path, { recursive: true }); } + try { + writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), { + encoding: 'utf-8', + }); - dbSettings: Database; - readonly storePath = join(ROOT_DIR, 'store'); + return { message: 'create - success' }; + } finally { + create.data = undefined; + } + }; - public writeStore = (create: WriteStore) => { - if (!existsSync(create.path)) { - mkdirSync(create.path, { recursive: true }); - } - try { - writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), { - encoding: 'utf-8', - }); - - return { message: 'create - success' }; - } finally { - create.data = undefined; - } - }; - - // eslint-disable-next-line + // eslint-disable-next-line public insert(data: any, instanceName: string, saveDb = false): Promise { - throw new Error('Method not implemented.'); - } + throw new Error('Method not implemented.'); + } - // eslint-disable-next-line + // eslint-disable-next-line public update(data: any, instanceName: string, saveDb = false): Promise { - throw new Error('Method not implemented.'); - } + throw new Error('Method not implemented.'); + } - // eslint-disable-next-line + // eslint-disable-next-line public find(query: any): Promise { - throw new Error('Method not implemented.'); - } + throw new Error('Method not implemented.'); + } - // eslint-disable-next-line + // eslint-disable-next-line delete(query: any, force?: boolean): Promise { - throw new Error('Method not implemented.'); - } + throw new Error('Method not implemented.'); + } } diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index 86f05d6a..3c19e6bb 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -10,214 +10,211 @@ import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; type DataValidate = { - request: Request; - schema: JSONSchema7; - ClassRef: any; - execute: (instance: InstanceDto, data: T) => Promise; + request: Request; + schema: JSONSchema7; + ClassRef: any; + execute: (instance: InstanceDto, data: T) => Promise; }; const logger = new Logger('Validate'); export abstract class RouterBroker { - constructor() {} - public routerPath(path: string, param = true) { - // const route = param ? '/:instanceName/' + path : '/' + path; - let route = '/' + path; - param ? (route += '/:instanceName') : null; + constructor() {} + public routerPath(path: string, param = true) { + // const route = param ? '/:instanceName/' + path : '/' + path; + let route = '/' + path; + param ? (route += '/:instanceName') : null; - return route; + return route; + } + + public async dataValidate(args: DataValidate) { + const { request, schema, ClassRef, execute } = args; + + const ref = new ClassRef(); + const body = request.body; + const instance = request.params as unknown as InstanceDto; + + if (request?.query && Object.keys(request.query).length > 0) { + Object.assign(instance, request.query); } - public async dataValidate(args: DataValidate) { - const { request, schema, ClassRef, execute } = args; - - const ref = new ClassRef(); - const body = request.body; - const instance = request.params as unknown as InstanceDto; - - if (request?.query && Object.keys(request.query).length > 0) { - Object.assign(instance, request.query); - } - - if (request.originalUrl.includes('/instance/create')) { - Object.assign(instance, body); - } - - Object.assign(ref, body); - - const v = schema ? validate(ref, schema) : { valid: true, errors: [] }; - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); - } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - - return await execute(instance, ref); + if (request.originalUrl.includes('/instance/create')) { + Object.assign(instance, body); } - public async groupNoValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + Object.assign(ref, body); - const instance = request.params as unknown as InstanceDto; + const v = schema ? validate(ref, schema) : { valid: true, errors: [] }; - const ref = new ClassRef(); - - Object.assign(ref, request.body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); - } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); } - - return await execute(instance, ref); + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); } - public async groupValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + return await execute(instance, ref); + } - const groupJid = request.query as unknown as GroupJid; + public async groupNoValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; - if (!groupJid?.groupJid) { - throw new BadRequestException( - 'The group id needs to be informed in the query', - 'ex: "groupJid=120362@g.us"', - ); + const instance = request.params as unknown as InstanceDto; + + const ref = new ClassRef(); + + Object.assign(ref, request.body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); } - - const instance = request.params as unknown as InstanceDto; - const body = request.body; - - const ref = new ClassRef(); - - Object.assign(body, groupJid); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); - } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - - return await execute(instance, ref); + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); } - public async inviteCodeValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + return await execute(instance, ref); + } - const inviteCode = request.query as unknown as GroupInvite; + public async groupValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; - if (!inviteCode?.inviteCode) { - throw new BadRequestException( - 'The group invite code id needs to be informed in the query', - 'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)', - ); - } + const groupJid = request.query as unknown as GroupJid; - const instance = request.params as unknown as InstanceDto; - const body = request.body; - - const ref = new ClassRef(); - - Object.assign(body, inviteCode); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); - } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - - return await execute(instance, ref); + if (!groupJid?.groupJid) { + throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"'); } - public async getParticipantsValidate(args: DataValidate) { - const { request, ClassRef, schema, execute } = args; + const instance = request.params as unknown as InstanceDto; + const body = request.body; - const getParticipants = request.query as unknown as GetParticipant; + const ref = new ClassRef(); - if (!getParticipants?.getParticipants) { - throw new BadRequestException('The getParticipants needs to be informed in the query'); + Object.assign(body, groupJid); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); } - - const instance = request.params as unknown as InstanceDto; - const body = request.body; - - const ref = new ClassRef(); - - Object.assign(body, getParticipants); - Object.assign(ref, body); - - const v = validate(ref, schema); - - if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { - let message: string; - if (schema['description']) { - message = schema['description']; - } else { - message = stack.replace('instance.', ''); - } - return { - property: property.replace('instance.', ''), - message, - }; - }); - logger.error([...message]); - throw new BadRequestException(...message); - } - - return await execute(instance, ref); + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); } + + return await execute(instance, ref); + } + + public async inviteCodeValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; + + const inviteCode = request.query as unknown as GroupInvite; + + if (!inviteCode?.inviteCode) { + throw new BadRequestException( + 'The group invite code id needs to be informed in the query', + 'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)', + ); + } + + const instance = request.params as unknown as InstanceDto; + const body = request.body; + + const ref = new ClassRef(); + + Object.assign(body, inviteCode); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); + } + + return await execute(instance, ref); + } + + public async getParticipantsValidate(args: DataValidate) { + const { request, ClassRef, schema, execute } = args; + + const getParticipants = request.query as unknown as GetParticipant; + + if (!getParticipants?.getParticipants) { + throw new BadRequestException('The getParticipants needs to be informed in the query'); + } + + const instance = request.params as unknown as InstanceDto; + const body = request.body; + + const ref = new ClassRef(); + + Object.assign(body, getParticipants); + Object.assign(ref, body); + + const v = validate(ref, schema); + + if (!v.valid) { + const message: any[] = v.errors.map(({ property, stack, schema }) => { + let message: string; + if (schema['description']) { + message = schema['description']; + } else { + message = stack.replace('instance.', ''); + } + return { + property: property.replace('instance.', ''), + message, + }; + }); + logger.error([...message]); + throw new BadRequestException(...message); + } + + return await execute(instance, ref); + } } diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index c1eff50b..0299841c 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -1,15 +1,15 @@ import { Logger } from '../../config/logger.config'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberDto, - PrivacySettingDto, - ProfileNameDto, - ProfilePictureDto, - ProfileStatusDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberDto, + PrivacySettingDto, + ProfileNameDto, + ProfilePictureDto, + ProfileStatusDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; @@ -20,95 +20,95 @@ import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('ChatController'); export class ChatController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) { - logger.verbose('requested whatsappNumber from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].whatsappNumber(data); - } + public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) { + logger.verbose('requested whatsappNumber from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].whatsappNumber(data); + } - public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) { - logger.verbose('requested readMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data); - } + public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) { + logger.verbose('requested readMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data); + } - public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) { - logger.verbose('requested archiveChat from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].archiveChat(data); - } + public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) { + logger.verbose('requested archiveChat from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].archiveChat(data); + } - public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) { - logger.verbose('requested deleteMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].deleteMessage(data); - } + public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) { + logger.verbose('requested deleteMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].deleteMessage(data); + } - public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) { - logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); - } + public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) { + logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].profilePicture(data.number); + } - public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { - logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number); - } + public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { + logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number); + } - public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { - logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchContacts(query); - } + public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { + logger.verbose('requested fetchContacts from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchContacts(query); + } - public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) { - logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data); - } + public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) { + logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data); + } - public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) { - logger.verbose('requested fetchMessages from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchMessages(query); - } + public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) { + logger.verbose('requested fetchMessages from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchMessages(query); + } - public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) { - logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query); - } + public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) { + logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query); + } - public async fetchChats({ instanceName }: InstanceDto) { - logger.verbose('requested fetchChats from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchChats(); - } + public async fetchChats({ instanceName }: InstanceDto) { + logger.verbose('requested fetchChats from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchChats(); + } - public async fetchPrivacySettings({ instanceName }: InstanceDto) { - logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings(); - } + public async fetchPrivacySettings({ instanceName }: InstanceDto) { + logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings(); + } - public async updatePrivacySettings({ instanceName }: InstanceDto, data: PrivacySettingDto) { - logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data); - } + public async updatePrivacySettings({ instanceName }: InstanceDto, data: PrivacySettingDto) { + logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data); + } - public async fetchBusinessProfile({ instanceName }: InstanceDto, data: ProfilePictureDto) { - logger.verbose('requested fetchBusinessProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile(data.number); - } + public async fetchBusinessProfile({ instanceName }: InstanceDto, data: ProfilePictureDto) { + logger.verbose('requested fetchBusinessProfile from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile(data.number); + } - public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) { - logger.verbose('requested updateProfileName from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name); - } + public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) { + logger.verbose('requested updateProfileName from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name); + } - public async updateProfileStatus({ instanceName }: InstanceDto, data: ProfileStatusDto) { - logger.verbose('requested updateProfileStatus from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfileStatus(data.status); - } + public async updateProfileStatus({ instanceName }: InstanceDto, data: ProfileStatusDto) { + logger.verbose('requested updateProfileStatus from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfileStatus(data.status); + } - public async updateProfilePicture({ instanceName }: InstanceDto, data: ProfilePictureDto) { - logger.verbose('requested updateProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfilePicture(data.picture); - } + public async updateProfilePicture({ instanceName }: InstanceDto, data: ProfilePictureDto) { + logger.verbose('requested updateProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].updateProfilePicture(data.picture); + } - public async removeProfilePicture({ instanceName }: InstanceDto) { - logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].removeProfilePicture(); - } + public async removeProfilePicture({ instanceName }: InstanceDto) { + logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].removeProfilePicture(); + } } diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index 67591cb3..ab291c43 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -11,89 +11,89 @@ import { waMonitor } from '../whatsapp.module'; const logger = new Logger('ChatwootController'); export class ChatwootController { - constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} + constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} - public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { - logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); + public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { + logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); - if (data.enabled) { - if (!isURL(data.url, { require_tld: false })) { - throw new BadRequestException('url is not valid'); - } + if (data.enabled) { + if (!isURL(data.url, { require_tld: false })) { + throw new BadRequestException('url is not valid'); + } - if (!data.account_id) { - throw new BadRequestException('account_id is required'); - } + if (!data.account_id) { + throw new BadRequestException('account_id is required'); + } - if (!data.token) { - throw new BadRequestException('token is required'); - } + if (!data.token) { + throw new BadRequestException('token is required'); + } - if (data.sign_msg !== true && data.sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } - } - - if (!data.enabled) { - logger.verbose('chatwoot disabled'); - data.account_id = ''; - data.token = ''; - data.url = ''; - data.sign_msg = false; - data.reopen_conversation = false; - data.conversation_pending = false; - } - - data.name_inbox = instance.instanceName; - - const result = this.chatwootService.create(instance, data); - - const urlServer = this.configService.get('SERVER').URL; - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; + if (data.sign_msg !== true && data.sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } } - public async findChatwoot(instance: InstanceDto) { - logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); - const result = await this.chatwootService.find(instance); - - const urlServer = this.configService.get('SERVER').URL; - - if (Object.keys(result).length === 0) { - return { - enabled: false, - url: '', - account_id: '', - token: '', - sign_msg: false, - name_inbox: '', - webhook_url: '', - }; - } - - const response = { - ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }; - - return response; + if (!data.enabled) { + logger.verbose('chatwoot disabled'); + data.account_id = ''; + data.token = ''; + data.url = ''; + data.sign_msg = false; + data.reopen_conversation = false; + data.conversation_pending = false; } - public async receiveWebhook(instance: InstanceDto, data: any) { - logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); - const chatwootService = new ChatwootService(waMonitor, this.configService); + data.name_inbox = instance.instanceName; - return chatwootService.receiveWebhook(instance, data); + const result = this.chatwootService.create(instance, data); + + const urlServer = this.configService.get('SERVER').URL; + + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; + + return response; + } + + public async findChatwoot(instance: InstanceDto) { + logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance'); + const result = await this.chatwootService.find(instance); + + const urlServer = this.configService.get('SERVER').URL; + + if (Object.keys(result).length === 0) { + return { + enabled: false, + url: '', + account_id: '', + token: '', + sign_msg: false, + name_inbox: '', + webhook_url: '', + }; } - public async newInstance(data: any) { - const chatwootService = new ChatwootService(waMonitor, this.configService); + const response = { + ...result, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }; - return chatwootService.newInstance(data); - } + return response; + } + + public async receiveWebhook(instance: InstanceDto, data: any) { + logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); + const chatwootService = new ChatwootService(waMonitor, this.configService); + + return chatwootService.receiveWebhook(instance, data); + } + + public async newInstance(data: any) { + const chatwootService = new ChatwootService(waMonitor, this.configService); + + return chatwootService.newInstance(data); + } } diff --git a/src/whatsapp/controllers/group.controller.ts b/src/whatsapp/controllers/group.controller.ts index 86e78737..0cf093ca 100644 --- a/src/whatsapp/controllers/group.controller.ts +++ b/src/whatsapp/controllers/group.controller.ts @@ -1,16 +1,16 @@ import { Logger } from '../../config/logger.config'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; import { WAMonitoringService } from '../services/monitor.service'; @@ -18,80 +18,80 @@ import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('ChatController'); export class GroupController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async createGroup(instance: InstanceDto, create: CreateGroupDto) { - logger.verbose('requested createGroup from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].createGroup(create); - } + public async createGroup(instance: InstanceDto, create: CreateGroupDto) { + logger.verbose('requested createGroup from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].createGroup(create); + } - public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) { - logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update); - } + public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) { + logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update); + } - public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) { - logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update); - } + public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) { + logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update); + } - public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) { - logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update); - } + public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) { + logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update); + } - public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid); - } + public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid); + } - public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) { - logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants); - } + public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) { + logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants); + } - public async inviteCode(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid); - } + public async inviteCode(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid); + } - public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) { - logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode); - } + public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) { + logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode); + } - public async sendInvite(instance: InstanceDto, data: GroupSendInvite) { - logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data); - } + public async sendInvite(instance: InstanceDto, data: GroupSendInvite) { + logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data); + } - public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid); - } + public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid); + } - public async findParticipants(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid); - } + public async findParticipants(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid); + } - public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) { - logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update); - } + public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) { + logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update); + } - public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) { - logger.verbose('requested updateGSetting from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update); - } + public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) { + logger.verbose('requested updateGSetting from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update); + } - public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) { - logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update); - } + public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) { + logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update); + } - public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance'); - return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid); - } + public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) { + logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid); + } } diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index f0a89ee8..e45644fe 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -17,340 +17,340 @@ import { WAStartupService } from '../services/whatsapp.service'; import { wa } from '../types/wa.types'; export class InstanceController { - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly eventEmitter: EventEmitter2, - private readonly authService: AuthService, - private readonly webhookService: WebhookService, - private readonly chatwootService: ChatwootService, - private readonly settingsService: SettingsService, - private readonly cache: RedisCache, - ) {} + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly eventEmitter: EventEmitter2, + private readonly authService: AuthService, + private readonly webhookService: WebhookService, + private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, + private readonly cache: RedisCache, + ) {} - private readonly logger = new Logger(InstanceController.name); + private readonly logger = new Logger(InstanceController.name); - public async createInstance({ - instanceName, + public async createInstance({ + instanceName, + webhook, + webhook_by_events, + events, + qrcode, + number, + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + chatwoot_reopen_conversation, + chatwoot_conversation_pending, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, + }: InstanceDto) { + try { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException('The instance name must be lowercase and without special characters'); + } + + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); + + this.logger.verbose('creating instance'); + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); + + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + let getEvents: string[]; + + if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } + + this.logger.verbose('creating webhook'); + try { + this.webhookService.create(instance, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); + + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; + + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, + webhook_by_events, + events: getEvents, + settings, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + + if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) { + throw new BadRequestException('reopen_conversation is required'); + } + + if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) { + throw new BadRequestException('conversation_pending is required'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + }); + + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); + } catch (error) { + this.logger.log(error); + } + + return { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, webhook, webhook_by_events, - events, - qrcode, - number, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - chatwoot_reopen_conversation, - chatwoot_conversation_pending, - reject_call, - msg_call, - groups_ignore, - always_online, - read_messages, - read_status, - }: InstanceDto) { - try { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + events: getEvents, + settings, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, + }; + } catch (error) { + console.log(error); + return { error: true, message: error.toString() }; + } + } - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException('The instance name must be lowercase and without special characters'); - } + public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { + try { + this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); + const instance = this.waMonitor.waInstances[instanceName]; + const state = instance?.connectionStatus?.state; - this.logger.verbose('creating instance'); - const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); + this.logger.verbose('state: ' + state); - this.logger.verbose('instance: ' + instance.instanceName + ' created'); + if (state == 'open') { + return await this.connectionState({ instanceName }); + } - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); + if (state == 'connecting') { + return instance.qrCode; + } - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); + if (state == 'close') { + this.logger.verbose('connecting'); + await instance.connectToWhatsapp(number); - this.logger.verbose('hash: ' + hash + ' generated'); + await delay(5000); + return instance.qrCode; + } - let getEvents: string[]; + return { + instance: { + instanceName: instanceName, + status: state, + }, + qrcode: instance?.qrCode, + }; + } catch (error) { + this.logger.error(error); + } + } - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); - } + public async restartInstance({ instanceName }: InstanceDto) { + try { + this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, - webhook_by_events, - }); + this.logger.verbose('logging out instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - getEvents = (await this.webhookService.find(instance)).events; - } catch (error) { - this.logger.log(error); - } - } + return { error: false, message: 'Instance restarted' }; + } catch (error) { + this.logger.error(error); + } + } - this.logger.verbose('creating settings'); - const settings: wa.LocalSettings = { - reject_call: reject_call || false, - msg_call: msg_call || '', - groups_ignore: groups_ignore || false, - always_online: always_online || false, - read_messages: read_messages || false, - read_status: read_status || false, - }; + public async connectionState({ instanceName }: InstanceDto) { + this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); + return { + instance: { + instanceName: instanceName, + state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, + }, + }; + } - this.logger.verbose('settings: ' + JSON.stringify(settings)); - - this.settingsService.create(instance, settings); - - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - settings, - qrcode: getQrcode, - }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { - throw new BadRequestException('sign_msg is required'); - } - - if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) { - throw new BadRequestException('reopen_conversation is required'); - } - - if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) { - throw new BadRequestException('conversation_pending is required'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - reopen_conversation: chatwoot_reopen_conversation || false, - conversation_pending: chatwoot_conversation_pending || false, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - number, - ); - } catch (error) { - this.logger.log(error); - } - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - settings, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - reopen_conversation: chatwoot_reopen_conversation || false, - conversation_pending: chatwoot_conversation_pending || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; - } catch (error) { - console.log(error); - return { error: true, message: error.toString() }; - } + public async fetchInstances({ instanceName }: InstanceDto) { + this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); + if (instanceName) { + this.logger.verbose('instanceName: ' + instanceName); + return this.waMonitor.instanceInfo(instanceName); } - public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { - try { - this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); + return this.waMonitor.instanceInfo(); + } - const instance = this.waMonitor.waInstances[instanceName]; - const state = instance?.connectionStatus?.state; + public async logout({ instanceName }: InstanceDto) { + this.logger.verbose('requested logout from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); - this.logger.verbose('state: ' + state); - - if (state == 'open') { - return await this.connectionState({ instanceName }); - } - - if (state == 'connecting') { - return instance.qrCode; - } - - if (state == 'close') { - this.logger.verbose('connecting'); - await instance.connectToWhatsapp(number); - - await delay(5000); - return instance.qrCode; - } - - return { - instance: { - instanceName: instanceName, - status: state, - }, - qrcode: instance?.qrCode, - }; - } catch (error) { - this.logger.error(error); - } + if (instance.state === 'close') { + throw new BadRequestException('The "' + instanceName + '" instance is not connected'); } - public async restartInstance({ instanceName }: InstanceDto) { - try { - this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); + try { + this.logger.verbose('logging out instance: ' + instanceName); + await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); - this.logger.verbose('logging out instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); + this.logger.verbose('close connection instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - return { error: false, message: 'Instance restarted' }; - } catch (error) { - this.logger.error(error); - } + return { error: false, message: 'Instance logged out' }; + } catch (error) { + throw new InternalServerErrorException(error.toString()); } + } - public async connectionState({ instanceName }: InstanceDto) { - this.logger.verbose('requested connectionState from ' + instanceName + ' instance'); - return { - instance: { - instanceName: instanceName, - state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state, - }, - }; + public async deleteInstance({ instanceName }: InstanceDto) { + this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); + const { instance } = await this.connectionState({ instanceName }); + + if (instance.state === 'open') { + throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); } + try { + if (instance.state === 'connecting') { + this.logger.verbose('logging out instance: ' + instanceName); - public async fetchInstances({ instanceName }: InstanceDto) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); - if (instanceName) { - this.logger.verbose('instanceName: ' + instanceName); - return this.waMonitor.instanceInfo(instanceName); - } + await this.logout({ instanceName }); + delete this.waMonitor.waInstances[instanceName]; + return { error: false, message: 'Instance deleted' }; + } else { + this.logger.verbose('deleting instance: ' + instanceName); - return this.waMonitor.instanceInfo(); + delete this.waMonitor.waInstances[instanceName]; + this.eventEmitter.emit('remove.instance', instanceName, 'inner'); + return { error: false, message: 'Instance deleted' }; + } + } catch (error) { + throw new BadRequestException(error.toString()); } + } - public async logout({ instanceName }: InstanceDto) { - this.logger.verbose('requested logout from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); - - if (instance.state === 'close') { - throw new BadRequestException('The "' + instanceName + '" instance is not connected'); - } - - try { - this.logger.verbose('logging out instance: ' + instanceName); - await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); - - this.logger.verbose('close connection instance: ' + instanceName); - this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - - return { error: false, message: 'Instance logged out' }; - } catch (error) { - throw new InternalServerErrorException(error.toString()); - } - } - - public async deleteInstance({ instanceName }: InstanceDto) { - this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance'); - const { instance } = await this.connectionState({ instanceName }); - - if (instance.state === 'open') { - throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); - } - try { - if (instance.state === 'connecting') { - this.logger.verbose('logging out instance: ' + instanceName); - - await this.logout({ instanceName }); - delete this.waMonitor.waInstances[instanceName]; - return { error: false, message: 'Instance deleted' }; - } else { - this.logger.verbose('deleting instance: ' + instanceName); - - delete this.waMonitor.waInstances[instanceName]; - this.eventEmitter.emit('remove.instance', instanceName, 'inner'); - return { error: false, message: 'Instance deleted' }; - } - } catch (error) { - throw new BadRequestException(error.toString()); - } - } - - public async refreshToken(_: InstanceDto, oldToken: OldToken) { - this.logger.verbose('requested refreshToken'); - return await this.authService.refreshToken(oldToken); - } + public async refreshToken(_: InstanceDto, oldToken: OldToken) { + this.logger.verbose('requested refreshToken'); + return await this.authService.refreshToken(oldToken); + } } diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index 593b858e..20e38ae5 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -4,112 +4,108 @@ import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, } from '../dto/sendMessage.dto'; import { WAMonitoringService } from '../services/monitor.service'; const logger = new Logger('MessageRouter'); export class SendMessageController { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - public async sendText({ instanceName }: InstanceDto, data: SendTextDto) { - logger.verbose('requested sendText from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].textMessage(data); + public async sendText({ instanceName }: InstanceDto, data: SendTextDto) { + logger.verbose('requested sendText from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].textMessage(data); + } + + public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) { + logger.verbose('requested sendMedia from ' + instanceName + ' instance'); + + if ( + isBase64(data?.mediaMessage?.media) && + !data?.mediaMessage?.fileName && + data?.mediaMessage?.mediatype === 'document' + ) { + throw new BadRequestException('For base64 the file name must be informed.'); } - public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) { - logger.verbose('requested sendMedia from ' + instanceName + ' instance'); - - if ( - isBase64(data?.mediaMessage?.media) && - !data?.mediaMessage?.fileName && - data?.mediaMessage?.mediatype === 'document' - ) { - throw new BadRequestException('For base64 the file name must be informed.'); - } - - logger.verbose( - 'isURL: ' + isURL(data?.mediaMessage?.media) + ', isBase64: ' + isBase64(data?.mediaMessage?.media), - ); - if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) { - return await this.waMonitor.waInstances[instanceName].mediaMessage(data); - } - throw new BadRequestException('Owned media must be a url or base64'); + logger.verbose('isURL: ' + isURL(data?.mediaMessage?.media) + ', isBase64: ' + isBase64(data?.mediaMessage?.media)); + if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) { + return await this.waMonitor.waInstances[instanceName].mediaMessage(data); } + throw new BadRequestException('Owned media must be a url or base64'); + } - public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) { - logger.verbose('requested sendSticker from ' + instanceName + ' instance'); + public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) { + logger.verbose('requested sendSticker from ' + instanceName + ' instance'); - logger.verbose( - 'isURL: ' + isURL(data?.stickerMessage?.image) + ', isBase64: ' + isBase64(data?.stickerMessage?.image), - ); - if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) { - return await this.waMonitor.waInstances[instanceName].mediaSticker(data); - } - throw new BadRequestException('Owned media must be a url or base64'); + logger.verbose( + 'isURL: ' + isURL(data?.stickerMessage?.image) + ', isBase64: ' + isBase64(data?.stickerMessage?.image), + ); + if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) { + return await this.waMonitor.waInstances[instanceName].mediaSticker(data); } + throw new BadRequestException('Owned media must be a url or base64'); + } - public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) { - logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance'); + public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) { + logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance'); - logger.verbose( - 'isURL: ' + isURL(data?.audioMessage?.audio) + ', isBase64: ' + isBase64(data?.audioMessage?.audio), - ); - if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) { - return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data); - } - throw new BadRequestException('Owned media must be a url or base64'); + logger.verbose('isURL: ' + isURL(data?.audioMessage?.audio) + ', isBase64: ' + isBase64(data?.audioMessage?.audio)); + if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) { + return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data); } + throw new BadRequestException('Owned media must be a url or base64'); + } - public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { - logger.verbose('requested sendButtons from ' + instanceName + ' instance'); - if (isBase64(data.buttonMessage.mediaMessage?.media) && !data.buttonMessage.mediaMessage?.fileName) { - throw new BadRequestException('For bse64 the file name must be informed.'); - } - return await this.waMonitor.waInstances[instanceName].buttonMessage(data); + public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { + logger.verbose('requested sendButtons from ' + instanceName + ' instance'); + if (isBase64(data.buttonMessage.mediaMessage?.media) && !data.buttonMessage.mediaMessage?.fileName) { + throw new BadRequestException('For bse64 the file name must be informed.'); } + return await this.waMonitor.waInstances[instanceName].buttonMessage(data); + } - public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) { - logger.verbose('requested sendLocation from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].locationMessage(data); - } + public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) { + logger.verbose('requested sendLocation from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].locationMessage(data); + } - public async sendList({ instanceName }: InstanceDto, data: SendListDto) { - logger.verbose('requested sendList from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].listMessage(data); - } + public async sendList({ instanceName }: InstanceDto, data: SendListDto) { + logger.verbose('requested sendList from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].listMessage(data); + } - public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) { - logger.verbose('requested sendContact from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].contactMessage(data); - } + public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) { + logger.verbose('requested sendContact from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].contactMessage(data); + } - public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { - logger.verbose('requested sendReaction from ' + instanceName + ' instance'); - if (!data.reactionMessage.reaction.match(/[^()\w\sà-ú"-+]+/)) { - throw new BadRequestException('"reaction" must be an emoji'); - } - return await this.waMonitor.waInstances[instanceName].reactionMessage(data); + public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { + logger.verbose('requested sendReaction from ' + instanceName + ' instance'); + if (!data.reactionMessage.reaction.match(/[^()\w\sà-ú"-+]+/)) { + throw new BadRequestException('"reaction" must be an emoji'); } + return await this.waMonitor.waInstances[instanceName].reactionMessage(data); + } - public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) { - logger.verbose('requested sendPoll from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].pollMessage(data); - } + public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) { + logger.verbose('requested sendPoll from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].pollMessage(data); + } - public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) { - logger.verbose('requested sendStatus from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].statusMessage(data); - } + public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) { + logger.verbose('requested sendStatus from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].statusMessage(data); + } } diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 1a82a0b2..1a8baafc 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -9,16 +9,16 @@ import { SettingsService } from '../services/settings.service'; const logger = new Logger('SettingsController'); export class SettingsController { - constructor(private readonly settingsService: SettingsService) {} + constructor(private readonly settingsService: SettingsService) {} - public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); + public async createSettings(instance: InstanceDto, data: SettingsDto) { + logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.create(instance, data); - } + return this.settingsService.create(instance, data); + } - public async findSettings(instance: InstanceDto) { - logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); - return this.settingsService.find(instance); - } + public async findSettings(instance: InstanceDto) { + logger.verbose('requested findSettings from ' + instance.instanceName + ' instance'); + return this.settingsService.find(instance); + } } diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index 269ea7de..5f4060ac 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -7,20 +7,20 @@ import { HttpStatus } from '../routers/index.router'; import { WAMonitoringService } from '../services/monitor.service'; export class ViewsController { - constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} + constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} - public async qrcode(request: Request, response: Response) { - try { - const param = request.params as unknown as InstanceDto; - const instance = this.waMonit.waInstances[param.instanceName]; - if (instance.connectionStatus.state === 'open') { - throw new BadRequestException('The instance is already connected'); - } - const type = this.configService.get('AUTHENTICATION').TYPE; + public async qrcode(request: Request, response: Response) { + try { + const param = request.params as unknown as InstanceDto; + const instance = this.waMonit.waInstances[param.instanceName]; + if (instance.connectionStatus.state === 'open') { + throw new BadRequestException('The instance is already connected'); + } + const type = this.configService.get('AUTHENTICATION').TYPE; - return response.status(HttpStatus.OK).render('qrcode', { type, ...param }); - } catch (error) { - console.log('ERROR: ', error); - } + return response.status(HttpStatus.OK).render('qrcode', { type, ...param }); + } catch (error) { + console.log('ERROR: ', error); } + } } diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index 073a22fc..281147db 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -9,26 +9,26 @@ import { WebhookService } from '../services/webhook.service'; const logger = new Logger('WebhookController'); export class WebhookController { - constructor(private readonly webhookService: WebhookService) {} + constructor(private readonly webhookService: WebhookService) {} - public async createWebhook(instance: InstanceDto, data: WebhookDto) { - logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance'); + public async createWebhook(instance: InstanceDto, data: WebhookDto) { + logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance'); - if (data.enabled && !isURL(data.url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property'); - } - - if (!data.enabled) { - logger.verbose('webhook disabled'); - data.url = ''; - data.events = []; - } - - return this.webhookService.create(instance, data); + if (data.enabled && !isURL(data.url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property'); } - public async findWebhook(instance: InstanceDto) { - logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance'); - return this.webhookService.find(instance); + if (!data.enabled) { + logger.verbose('webhook disabled'); + data.url = ''; + data.events = []; } + + return this.webhookService.create(instance, data); + } + + public async findWebhook(instance: InstanceDto) { + logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance'); + return this.webhookService.find(instance); + } } diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 487a30d4..f2f9b1cc 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,84 +1,84 @@ import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; export class OnWhatsAppDto { - constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} + constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} } export class getBase64FromMediaMessageDto { - message: proto.WebMessageInfo; - convertToMp4?: boolean; + message: proto.WebMessageInfo; + convertToMp4?: boolean; } export class WhatsAppNumberDto { - numbers: string[]; + numbers: string[]; } export class NumberDto { - number: string; + number: string; } export class NumberBusiness { - wid?: string; - jid?: string; - exists?: boolean; - isBusiness: boolean; - name?: string; - message?: string; - description?: string; - email?: string; - website?: string[]; - address?: string; + wid?: string; + jid?: string; + exists?: boolean; + isBusiness: boolean; + name?: string; + message?: string; + description?: string; + email?: string; + website?: string[]; + address?: string; } export class ProfileNameDto { - name: string; + name: string; } export class ProfileStatusDto { - status: string; + status: string; } export class ProfilePictureDto { - number?: string; - // url or base64 - picture?: string; + number?: string; + // url or base64 + picture?: string; } class Key { - id: string; - fromMe: boolean; - remoteJid: string; + id: string; + fromMe: boolean; + remoteJid: string; } export class ReadMessageDto { - read_messages: Key[]; + read_messages: Key[]; } class LastMessage { - key: Key; - messageTimestamp?: number; + key: Key; + messageTimestamp?: number; } export class ArchiveChatDto { - lastMessage: LastMessage; - archive: boolean; + lastMessage: LastMessage; + archive: boolean; } class PrivacySetting { - readreceipts: WAReadReceiptsValue; - profile: WAPrivacyValue; - status: WAPrivacyValue; - online: WAPrivacyOnlineValue; - last: WAPrivacyValue; - groupadd: WAPrivacyValue; + readreceipts: WAReadReceiptsValue; + profile: WAPrivacyValue; + status: WAPrivacyValue; + online: WAPrivacyOnlineValue; + last: WAPrivacyValue; + groupadd: WAPrivacyValue; } export class PrivacySettingDto { - privacySettings: PrivacySetting; + privacySettings: PrivacySetting; } export class DeleteMessage { - id: string; - fromMe: boolean; - remoteJid: string; - participant?: string; + id: string; + fromMe: boolean; + remoteJid: string; + participant?: string; } diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index 212e0090..b270c869 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -1,11 +1,11 @@ export class ChatwootDto { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index 62a1b890..6dfdc45c 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,52 +1,52 @@ export class CreateGroupDto { - subject: string; - participants: string[]; - description?: string; - promoteParticipants?: boolean; + subject: string; + participants: string[]; + description?: string; + promoteParticipants?: boolean; } export class GroupPictureDto { - groupJid: string; - image: string; + groupJid: string; + image: string; } export class GroupSubjectDto { - groupJid: string; - subject: string; + groupJid: string; + subject: string; } export class GroupDescriptionDto { - groupJid: string; - description: string; + groupJid: string; + description: string; } export class GroupJid { - groupJid: string; + groupJid: string; } export class GetParticipant { - getParticipants: string; + getParticipants: string; } export class GroupInvite { - inviteCode: string; + inviteCode: string; } export class GroupSendInvite { - groupJid: string; - description: string; - numbers: string[]; + groupJid: string; + description: string; + numbers: string[]; } export class GroupUpdateParticipantDto extends GroupJid { - action: 'add' | 'remove' | 'promote' | 'demote'; - participants: string[]; + action: 'add' | 'remove' | 'promote' | 'demote'; + participants: string[]; } export class GroupUpdateSettingDto extends GroupJid { - action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; + action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked'; } export class GroupToggleEphemeralDto extends GroupJid { - expiration: 0 | 86400 | 604800 | 7776000; + expiration: 0 | 86400 | 604800 | 7776000; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 827b1243..c317060f 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,21 +1,21 @@ export class InstanceDto { - instanceName: string; - qrcode?: boolean; - number?: string; - token?: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; - chatwoot_account_id?: string; - chatwoot_token?: string; - chatwoot_url?: string; - chatwoot_sign_msg?: boolean; - chatwoot_reopen_conversation?: boolean; - chatwoot_conversation_pending?: boolean; + instanceName: string; + qrcode?: boolean; + number?: string; + token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + chatwoot_account_id?: string; + chatwoot_token?: string; + chatwoot_url?: string; + chatwoot_sign_msg?: boolean; + chatwoot_reopen_conversation?: boolean; + chatwoot_conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 754d66e2..c2ddb3a2 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -1,150 +1,150 @@ import { proto, WAPresence } from '@whiskeysockets/baileys'; export class Quoted { - key: proto.IMessageKey; - message: proto.IMessage; + key: proto.IMessageKey; + message: proto.IMessage; } export class Mentions { - everyOne: boolean; - mentioned: string[]; + everyOne: boolean; + mentioned: string[]; } export class Options { - delay?: number; - presence?: WAPresence; - quoted?: Quoted; - mentions?: Mentions; - linkPreview?: boolean; - encoding?: boolean; + delay?: number; + presence?: WAPresence; + quoted?: Quoted; + mentions?: Mentions; + linkPreview?: boolean; + encoding?: boolean; } class OptionsMessage { - options: Options; + options: Options; } export class Metadata extends OptionsMessage { - number: string; + number: string; } class TextMessage { - text: string; + text: string; } export class StatusMessage { - type: string; - content: string; - statusJidList?: string[]; - allContacts?: boolean; - caption?: string; - backgroundColor?: string; - font?: number; + type: string; + content: string; + statusJidList?: string[]; + allContacts?: boolean; + caption?: string; + backgroundColor?: string; + font?: number; } class PollMessage { - name: string; - selectableCount: number; - values: string[]; - messageSecret?: Uint8Array; + name: string; + selectableCount: number; + values: string[]; + messageSecret?: Uint8Array; } export class SendTextDto extends Metadata { - textMessage: TextMessage; + textMessage: TextMessage; } export class SendStatusDto extends Metadata { - statusMessage: StatusMessage; + statusMessage: StatusMessage; } export class SendPollDto extends Metadata { - pollMessage: PollMessage; + pollMessage: PollMessage; } export type MediaType = 'image' | 'document' | 'video' | 'audio'; export class MediaMessage { - mediatype: MediaType; - caption?: string; - // for document - fileName?: string; - // url or base64 - media: string; + mediatype: MediaType; + caption?: string; + // for document + fileName?: string; + // url or base64 + media: string; } export class SendMediaDto extends Metadata { - mediaMessage: MediaMessage; + mediaMessage: MediaMessage; } class Sticker { - image: string; + image: string; } export class SendStickerDto extends Metadata { - stickerMessage: Sticker; + stickerMessage: Sticker; } class Audio { - audio: string; + audio: string; } export class SendAudioDto extends Metadata { - audioMessage: Audio; + audioMessage: Audio; } class Button { - buttonText: string; - buttonId: string; + buttonText: string; + buttonId: string; } class ButtonMessage { - title: string; - description: string; - footerText?: string; - buttons: Button[]; - mediaMessage?: MediaMessage; + title: string; + description: string; + footerText?: string; + buttons: Button[]; + mediaMessage?: MediaMessage; } export class SendButtonDto extends Metadata { - buttonMessage: ButtonMessage; + buttonMessage: ButtonMessage; } class LocationMessage { - latitude: number; - longitude: number; - name?: string; - address?: string; + latitude: number; + longitude: number; + name?: string; + address?: string; } export class SendLocationDto extends Metadata { - locationMessage: LocationMessage; + locationMessage: LocationMessage; } class Row { - title: string; - description: string; - rowId: string; + title: string; + description: string; + rowId: string; } class Section { - title: string; - rows: Row[]; + title: string; + rows: Row[]; } class ListMessage { - title: string; - description: string; - footerText?: string; - buttonText: string; - sections: Section[]; + title: string; + description: string; + footerText?: string; + buttonText: string; + sections: Section[]; } export class SendListDto extends Metadata { - listMessage: ListMessage; + listMessage: ListMessage; } export class ContactMessage { - fullName: string; - wuid: string; - phoneNumber: string; - organization?: string; - email?: string; - url?: string; + fullName: string; + wuid: string; + phoneNumber: string; + organization?: string; + email?: string; + url?: string; } export class SendContactDto extends Metadata { - contactMessage: ContactMessage[]; + contactMessage: ContactMessage[]; } class ReactionMessage { - key: proto.IMessageKey; - reaction: string; + key: proto.IMessageKey; + reaction: string; } export class SendReactionDto { - reactionMessage: ReactionMessage; + reactionMessage: ReactionMessage; } diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 9094b888..594ab3a4 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -1,8 +1,8 @@ export class SettingsDto { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/dto/webhook.dto.ts b/src/whatsapp/dto/webhook.dto.ts index b41ec0e6..5203884d 100644 --- a/src/whatsapp/dto/webhook.dto.ts +++ b/src/whatsapp/dto/webhook.dto.ts @@ -1,6 +1,6 @@ export class WebhookDto { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; } diff --git a/src/whatsapp/guards/auth.guard.ts b/src/whatsapp/guards/auth.guard.ts index f4d30fc1..72148885 100644 --- a/src/whatsapp/guards/auth.guard.ts +++ b/src/whatsapp/guards/auth.guard.ts @@ -13,77 +13,71 @@ import { repository } from '../whatsapp.module'; const logger = new Logger('GUARD'); async function jwtGuard(req: Request, res: Response, next: NextFunction) { - const key = req.get('apikey'); + const key = req.get('apikey'); - if (key && configService.get('AUTHENTICATION').API_KEY.KEY !== key) { - throw new UnauthorizedException(); + if (key && configService.get('AUTHENTICATION').API_KEY.KEY !== key) { + throw new UnauthorizedException(); + } + + if (configService.get('AUTHENTICATION').API_KEY.KEY === key) { + return next(); + } + + if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); + } + + const jwtOpts = configService.get('AUTHENTICATION').JWT; + try { + const [bearer, token] = req.get('authorization').split(' '); + + if (bearer.toLowerCase() !== 'bearer') { + throw new UnauthorizedException(); } - if (configService.get('AUTHENTICATION').API_KEY.KEY === key) { - return next(); + if (!isJWT(token)) { + throw new UnauthorizedException(); } - if ( - (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException('Missing global api key', 'The global api key must be set'); + const param = req.params as unknown as InstanceDto; + const decode = jwt.verify(token, jwtOpts.SECRET, { + ignoreExpiration: jwtOpts.EXPIRIN_IN === 0, + }) as JwtPayload; + + if (param.instanceName !== decode.instanceName || name !== decode.apiName) { + throw new UnauthorizedException(); } - const jwtOpts = configService.get('AUTHENTICATION').JWT; - try { - const [bearer, token] = req.get('authorization').split(' '); - - if (bearer.toLowerCase() !== 'bearer') { - throw new UnauthorizedException(); - } - - if (!isJWT(token)) { - throw new UnauthorizedException(); - } - - const param = req.params as unknown as InstanceDto; - const decode = jwt.verify(token, jwtOpts.SECRET, { - ignoreExpiration: jwtOpts.EXPIRIN_IN === 0, - }) as JwtPayload; - - if (param.instanceName !== decode.instanceName || name !== decode.apiName) { - throw new UnauthorizedException(); - } - - return next(); - } catch (error) { - logger.error(error); - throw new UnauthorizedException(); - } + return next(); + } catch (error) { + logger.error(error); + throw new UnauthorizedException(); + } } async function apikey(req: Request, res: Response, next: NextFunction) { - const env = configService.get('AUTHENTICATION').API_KEY; - const key = req.get('apikey'); + const env = configService.get('AUTHENTICATION').API_KEY; + const key = req.get('apikey'); - if (env.KEY === key) { - return next(); + if (env.KEY === key) { + return next(); + } + + if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); + } + + try { + const param = req.params as unknown as InstanceDto; + const instanceKey = await repository.auth.find(param.instanceName); + if (instanceKey.apikey === key) { + return next(); } + } catch (error) { + logger.error(error); + } - if ( - (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException('Missing global api key', 'The global api key must be set'); - } - - try { - const param = req.params as unknown as InstanceDto; - const instanceKey = await repository.auth.find(param.instanceName); - if (instanceKey.apikey === key) { - return next(); - } - } catch (error) { - logger.error(error); - } - - throw new UnauthorizedException(); + throw new UnauthorizedException(); } export const authGuard = { jwt: jwtGuard, apikey }; diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 6d65c743..69d20414 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -10,55 +10,55 @@ import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; async function getInstance(instanceName: string) { - const db = configService.get('DATABASE'); - const redisConf = configService.get('REDIS'); + const db = configService.get('DATABASE'); + const redisConf = configService.get('REDIS'); - const exists = !!waMonitor.waInstances[instanceName]; + const exists = !!waMonitor.waInstances[instanceName]; - if (redisConf.ENABLED) { - const keyExists = await cache.keyExists(); - return exists || keyExists; - } + if (redisConf.ENABLED) { + const keyExists = await cache.keyExists(); + return exists || keyExists; + } - if (db.ENABLED) { - const collection = dbserver - .getClient() - .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(instanceName); - return exists || (await collection.find({}).toArray()).length > 0; - } + if (db.ENABLED) { + const collection = dbserver + .getClient() + .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(instanceName); + return exists || (await collection.find({}).toArray()).length > 0; + } - return exists || existsSync(join(INSTANCE_DIR, instanceName)); + return exists || existsSync(join(INSTANCE_DIR, instanceName)); } export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) { - if (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) { - return next(); - } + if (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) { + return next(); + } - const param = req.params as unknown as InstanceDto; - if (!param?.instanceName) { - throw new BadRequestException('"instanceName" not provided.'); - } + const param = req.params as unknown as InstanceDto; + if (!param?.instanceName) { + throw new BadRequestException('"instanceName" not provided.'); + } - if (!(await getInstance(param.instanceName))) { - throw new NotFoundException(`The "${param.instanceName}" instance does not exist`); - } + if (!(await getInstance(param.instanceName))) { + throw new NotFoundException(`The "${param.instanceName}" instance does not exist`); + } - next(); + next(); } export async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) { - if (req.originalUrl.includes('/instance/create')) { - const instance = req.body as InstanceDto; - if (await getInstance(instance.instanceName)) { - throw new ForbiddenException(`This name "${instance.instanceName}" is already in use.`); - } - - if (waMonitor.waInstances[instance.instanceName]) { - delete waMonitor.waInstances[instance.instanceName]; - } + if (req.originalUrl.includes('/instance/create')) { + const instance = req.body as InstanceDto; + if (await getInstance(instance.instanceName)) { + throw new ForbiddenException(`This name "${instance.instanceName}" is already in use.`); } - next(); + if (waMonitor.waInstances[instance.instanceName]) { + delete waMonitor.waInstances[instance.instanceName]; + } + } + + next(); } diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index c9e48da1..5c5b6a41 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -3,15 +3,15 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class AuthRaw { - _id?: string; - jwt?: string; - apikey?: string; + _id?: string; + jwt?: string; + apikey?: string; } const authSchema = new Schema({ - _id: { type: String, _id: true }, - jwt: { type: String, minlength: 1 }, - apikey: { type: String, minlength: 1 }, + _id: { type: String, _id: true }, + jwt: { type: String, minlength: 1 }, + apikey: { type: String, minlength: 1 }, }); export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication'); diff --git a/src/whatsapp/models/chat.model.ts b/src/whatsapp/models/chat.model.ts index d44a4673..20153603 100644 --- a/src/whatsapp/models/chat.model.ts +++ b/src/whatsapp/models/chat.model.ts @@ -3,16 +3,16 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ChatRaw { - _id?: string; - id?: string; - owner: string; - lastMsgTimestamp?: number; + _id?: string; + id?: string; + owner: string; + lastMsgTimestamp?: number; } const chatSchema = new Schema({ - _id: { type: String, _id: true }, - id: { type: String, required: true, minlength: 1 }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + id: { type: String, required: true, minlength: 1 }, + owner: { type: String, required: true, minlength: 1 }, }); export const ChatModel = dbserver?.model(ChatRaw.name, chatSchema, 'chats'); diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 3b1a99a2..d72f6e74 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -3,27 +3,27 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { - _id?: string; - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; + _id?: string; + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } const chatwootSchema = new Schema({ - _id: { type: String, _id: true }, - enabled: { type: Boolean, required: true }, - account_id: { type: String, required: true }, - token: { type: String, required: true }, - url: { type: String, required: true }, - name_inbox: { type: String, required: true }, - sign_msg: { type: Boolean, required: true }, - number: { type: String, required: true }, + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + account_id: { type: String, required: true }, + token: { type: String, required: true }, + url: { type: String, required: true }, + name_inbox: { type: String, required: true }, + sign_msg: { type: Boolean, required: true }, + number: { type: String, required: true }, }); export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot'); diff --git a/src/whatsapp/models/contact.model.ts b/src/whatsapp/models/contact.model.ts index 84749945..d9b51e1e 100644 --- a/src/whatsapp/models/contact.model.ts +++ b/src/whatsapp/models/contact.model.ts @@ -3,19 +3,19 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class ContactRaw { - _id?: string; - pushName?: string; - id?: string; - profilePictureUrl?: string; - owner: string; + _id?: string; + pushName?: string; + id?: string; + profilePictureUrl?: string; + owner: string; } const contactSchema = new Schema({ - _id: { type: String, _id: true }, - pushName: { type: String, minlength: 1 }, - id: { type: String, required: true, minlength: 1 }, - profilePictureUrl: { type: String, minlength: 1 }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + pushName: { type: String, minlength: 1 }, + id: { type: String, required: true, minlength: 1 }, + profilePictureUrl: { type: String, minlength: 1 }, + owner: { type: String, required: true, minlength: 1 }, }); export const ContactModel = dbserver?.model(ContactRaw.name, contactSchema, 'contacts'); diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index bfa048cf..764b04d9 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -4,65 +4,65 @@ import { dbserver } from '../../db/db.connect'; import { wa } from '../types/wa.types'; class Key { - id?: string; - remoteJid?: string; - fromMe?: boolean; - participant?: string; + id?: string; + remoteJid?: string; + fromMe?: boolean; + participant?: string; } export class MessageRaw { - _id?: string; - key?: Key; - pushName?: string; - participant?: string; - message?: object; - messageType?: string; - messageTimestamp?: number | Long.Long; - owner: string; - source?: 'android' | 'web' | 'ios'; + _id?: string; + key?: Key; + pushName?: string; + participant?: string; + message?: object; + messageType?: string; + messageTimestamp?: number | Long.Long; + owner: string; + source?: 'android' | 'web' | 'ios'; } const messageSchema = new Schema({ - _id: { type: String, _id: true }, - key: { - id: { type: String, required: true, minlength: 1 }, - remoteJid: { type: String, required: true, minlength: 1 }, - fromMe: { type: Boolean, required: true }, - participant: { type: String, minlength: 1 }, - }, - pushName: { type: String }, - participant: { type: String }, - messageType: { type: String }, - message: { type: Object }, - source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, - messageTimestamp: { type: Number, required: true }, - owner: { type: String, required: true, minlength: 1 }, + _id: { type: String, _id: true }, + key: { + id: { type: String, required: true, minlength: 1 }, + remoteJid: { type: String, required: true, minlength: 1 }, + fromMe: { type: Boolean, required: true }, + participant: { type: String, minlength: 1 }, + }, + pushName: { type: String }, + participant: { type: String }, + messageType: { type: String }, + message: { type: Object }, + source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, + messageTimestamp: { type: Number, required: true }, + owner: { type: String, required: true, minlength: 1 }, }); export const MessageModel = dbserver?.model(MessageRaw.name, messageSchema, 'messages'); export type IMessageModel = typeof MessageModel; export class MessageUpdateRaw { - _id?: string; - remoteJid?: string; - id?: string; - fromMe?: boolean; - participant?: string; - datetime?: number; - status?: wa.StatusMessage; - owner: string; - pollUpdates?: any; + _id?: string; + remoteJid?: string; + id?: string; + fromMe?: boolean; + participant?: string; + datetime?: number; + status?: wa.StatusMessage; + owner: string; + pollUpdates?: any; } const messageUpdateSchema = new Schema({ - _id: { type: String, _id: true }, - remoteJid: { type: String, required: true, min: 1 }, - id: { type: String, required: true, min: 1 }, - fromMe: { type: Boolean, required: true }, - participant: { type: String, min: 1 }, - datetime: { type: Number, required: true, min: 1 }, - status: { type: String, required: true }, - owner: { type: String, required: true, min: 1 }, + _id: { type: String, _id: true }, + remoteJid: { type: String, required: true, min: 1 }, + id: { type: String, required: true, min: 1 }, + fromMe: { type: Boolean, required: true }, + participant: { type: String, min: 1 }, + datetime: { type: Number, required: true, min: 1 }, + status: { type: String, required: true }, + owner: { type: String, required: true, min: 1 }, }); export const MessageUpModel = dbserver?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate'); diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index 935f8f3d..c928be42 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -3,23 +3,23 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class SettingsRaw { - _id?: string; - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; + _id?: string; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ - _id: { type: String, _id: true }, - reject_call: { type: Boolean, required: true }, - msg_call: { type: String, required: true }, - groups_ignore: { type: Boolean, required: true }, - always_online: { type: Boolean, required: true }, - read_messages: { type: Boolean, required: true }, - read_status: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + reject_call: { type: Boolean, required: true }, + msg_call: { type: String, required: true }, + groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings'); diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index 57d55a7b..fa91326c 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -3,19 +3,19 @@ import { Schema } from 'mongoose'; import { dbserver } from '../../db/db.connect'; export class WebhookRaw { - _id?: string; - url?: string; - enabled?: boolean; - events?: string[]; - webhook_by_events?: boolean; + _id?: string; + url?: string; + enabled?: boolean; + events?: string[]; + webhook_by_events?: boolean; } const webhookSchema = new Schema({ - _id: { type: String, _id: true }, - url: { type: String, required: true }, - enabled: { type: Boolean, required: true }, - events: { type: [String], required: true }, - webhook_by_events: { type: Boolean, required: true }, + _id: { type: String, _id: true }, + url: { type: String, required: true }, + enabled: { type: Boolean, required: true }, + events: { type: [String], required: true }, + webhook_by_events: { type: Boolean, required: true }, }); export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook'); diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index b93ea86d..4da8980b 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -8,58 +8,58 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { AuthRaw, IAuthModel } from '../models'; export class AuthRepository extends Repository { - constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) { - super(configService); - this.auth = configService.get('AUTHENTICATION'); + constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) { + super(configService); + this.auth = configService.get('AUTHENTICATION'); + } + + private readonly auth: Auth; + private readonly logger = new Logger('AuthRepository'); + + public async create(data: AuthRaw, instance: string): Promise { + try { + this.logger.verbose('creating auth'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving auth to db'); + const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving auth to store'); + + this.writeStore({ + path: join(AUTH_DIR, this.auth.TYPE), + fileName: instance, + data, + }); + this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance); + + this.logger.verbose('auth created'); + return { insertCount: 1 }; + } catch (error) { + return { error } as any; } + } - private readonly auth: Auth; - private readonly logger = new Logger('AuthRepository'); + public async find(instance: string): Promise { + try { + this.logger.verbose('finding auth'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding auth in db'); + return await this.authModel.findOne({ _id: instance }); + } - public async create(data: AuthRaw, instance: string): Promise { - try { - this.logger.verbose('creating auth'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving auth to db'); - const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + this.logger.verbose('finding auth in store'); - this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving auth to store'); - - this.writeStore({ - path: join(AUTH_DIR, this.auth.TYPE), - fileName: instance, - data, - }); - this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance); - - this.logger.verbose('auth created'); - return { insertCount: 1 }; - } catch (error) { - return { error } as any; - } - } - - public async find(instance: string): Promise { - try { - this.logger.verbose('finding auth'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding auth in db'); - return await this.authModel.findOne({ _id: instance }); - } - - this.logger.verbose('finding auth in store'); - - return JSON.parse( - readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), { - encoding: 'utf-8', - }), - ) as AuthRaw; - } catch (error) { - return {}; - } + return JSON.parse( + readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), { + encoding: 'utf-8', + }), + ) as AuthRaw; + } catch (error) { + return {}; } + } } diff --git a/src/whatsapp/repository/chat.repository.ts b/src/whatsapp/repository/chat.repository.ts index b3ff575a..68d653a4 100644 --- a/src/whatsapp/repository/chat.repository.ts +++ b/src/whatsapp/repository/chat.repository.ts @@ -7,111 +7,111 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ChatRaw, IChatModel } from '../models'; export class ChatQuery { - where: ChatRaw; + where: ChatRaw; } export class ChatRepository extends Repository { - constructor(private readonly chatModel: IChatModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly chatModel: IChatModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('ChatRepository'); + + public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting chats'); + if (data.length === 0) { + this.logger.verbose('no chats to insert'); + return; } - private readonly logger = new Logger('ChatRepository'); + try { + this.logger.verbose('saving chats to store'); + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving chats to db'); + const insert = await this.chatModel.insertMany([...data]); - public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise { - this.logger.verbose('inserting chats'); - if (data.length === 0) { - this.logger.verbose('no chats to insert'); - return; - } + this.logger.verbose('chats saved to db: ' + insert.length + ' chats'); + return { insertCount: insert.length }; + } - try { - this.logger.verbose('saving chats to store'); - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving chats to db'); - const insert = await this.chatModel.insertMany([...data]); + this.logger.verbose('saving chats to store'); - this.logger.verbose('chats saved to db: ' + insert.length + ' chats'); - return { insertCount: insert.length }; - } + const store = this.configService.get('STORE'); - this.logger.verbose('saving chats to store'); + if (store.CHATS) { + this.logger.verbose('saving chats to store'); + data.forEach((chat) => { + this.writeStore({ + path: join(this.storePath, 'chats', instanceName), + fileName: chat.id, + data: chat, + }); + this.logger.verbose( + 'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id, + ); + }); - const store = this.configService.get('STORE'); + this.logger.verbose('chats saved to store'); + return { insertCount: data.length }; + } - if (store.CHATS) { - this.logger.verbose('saving chats to store'); - data.forEach((chat) => { - this.writeStore({ - path: join(this.storePath, 'chats', instanceName), - fileName: chat.id, - data: chat, - }); - this.logger.verbose( - 'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id, - ); - }); - - this.logger.verbose('chats saved to store'); - return { insertCount: data.length }; - } - - this.logger.verbose('chats not saved to store'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } + this.logger.verbose('chats not saved to store'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; } + } - public async find(query: ChatQuery): Promise { - try { - this.logger.verbose('finding chats'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding chats in db'); - return await this.chatModel.find({ owner: query.where.owner }); - } + public async find(query: ChatQuery): Promise { + try { + this.logger.verbose('finding chats'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding chats in db'); + return await this.chatModel.find({ owner: query.where.owner }); + } - this.logger.verbose('finding chats in store'); + this.logger.verbose('finding chats in store'); - const chats: ChatRaw[] = []; - const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner)); - for await (const dirent of openDir) { - if (dirent.isFile()) { - chats.push( - JSON.parse( - readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), { - encoding: 'utf-8', - }), - ), - ); - } - } - - this.logger.verbose('chats found in store: ' + chats.length + ' chats'); - return chats; - } catch (error) { - return []; + const chats: ChatRaw[] = []; + const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner)); + for await (const dirent of openDir) { + if (dirent.isFile()) { + chats.push( + JSON.parse( + readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); } + } + + this.logger.verbose('chats found in store: ' + chats.length + ' chats'); + return chats; + } catch (error) { + return []; } + } - public async delete(query: ChatQuery) { - try { - this.logger.verbose('deleting chats'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('deleting chats in db'); - return await this.chatModel.deleteOne({ ...query.where }); - } + public async delete(query: ChatQuery) { + try { + this.logger.verbose('deleting chats'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('deleting chats in db'); + return await this.chatModel.deleteOne({ ...query.where }); + } - this.logger.verbose('deleting chats in store'); - rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), { - force: true, - recursive: true, - }); + this.logger.verbose('deleting chats in store'); + rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), { + force: true, + recursive: true, + }); - return { deleted: { chatId: query.where.id } }; - } catch (error) { - return { error: error?.toString() }; - } + return { deleted: { chatId: query.where.id } }; + } catch (error) { + return { error: error?.toString() }; } + } } diff --git a/src/whatsapp/repository/chatwoot.repository.ts b/src/whatsapp/repository/chatwoot.repository.ts index 6cc3f631..47398d68 100644 --- a/src/whatsapp/repository/chatwoot.repository.ts +++ b/src/whatsapp/repository/chatwoot.repository.ts @@ -7,58 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ChatwootRaw, IChatwootModel } from '../models'; export class ChatwootRepository extends Repository { - constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('ChatwootRepository'); + + public async create(data: ChatwootRaw, instance: string): Promise { + try { + this.logger.verbose('creating chatwoot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving chatwoot to db'); + const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving chatwoot to store'); + + this.writeStore({ + path: join(this.storePath, 'chatwoot'), + fileName: instance, + data, + }); + + this.logger.verbose('chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance); + + this.logger.verbose('chatwoot created'); + return { insertCount: 1 }; + } catch (error) { + return error; } + } - private readonly logger = new Logger('ChatwootRepository'); + public async find(instance: string): Promise { + try { + this.logger.verbose('finding chatwoot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding chatwoot in db'); + return await this.chatwootModel.findOne({ _id: instance }); + } - public async create(data: ChatwootRaw, instance: string): Promise { - try { - this.logger.verbose('creating chatwoot'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving chatwoot to db'); - const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - - this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving chatwoot to store'); - - this.writeStore({ - path: join(this.storePath, 'chatwoot'), - fileName: instance, - data, - }); - - this.logger.verbose( - 'chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance, - ); - - this.logger.verbose('chatwoot created'); - return { insertCount: 1 }; - } catch (error) { - return error; - } - } - - public async find(instance: string): Promise { - try { - this.logger.verbose('finding chatwoot'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding chatwoot in db'); - return await this.chatwootModel.findOne({ _id: instance }); - } - - this.logger.verbose('finding chatwoot in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), { - encoding: 'utf-8', - }), - ) as ChatwootRaw; - } catch (error) { - return {}; - } + this.logger.verbose('finding chatwoot in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), { + encoding: 'utf-8', + }), + ) as ChatwootRaw; + } catch (error) { + return {}; } + } } diff --git a/src/whatsapp/repository/contact.repository.ts b/src/whatsapp/repository/contact.repository.ts index ed96ff56..03851607 100644 --- a/src/whatsapp/repository/contact.repository.ts +++ b/src/whatsapp/repository/contact.repository.ts @@ -7,171 +7,165 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ContactRaw, IContactModel } from '../models'; export class ContactQuery { - where: ContactRaw; + where: ContactRaw; } export class ContactRepository extends Repository { - constructor(private readonly contactModel: IContactModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly contactModel: IContactModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('ContactRepository'); + + public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting contacts'); + + if (data.length === 0) { + this.logger.verbose('no contacts to insert'); + return; } - private readonly logger = new Logger('ContactRepository'); + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving contacts to db'); - public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise { - this.logger.verbose('inserting contacts'); + const insert = await this.contactModel.insertMany([...data]); - if (data.length === 0) { - this.logger.verbose('no contacts to insert'); - return; - } + this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts'); + return { insertCount: insert.length }; + } - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving contacts to db'); + this.logger.verbose('saving contacts to store'); - const insert = await this.contactModel.insertMany([...data]); + const store = this.configService.get('STORE'); - this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts'); - return { insertCount: insert.length }; - } + if (store.CONTACTS) { + this.logger.verbose('saving contacts to store'); + data.forEach((contact) => { + this.writeStore({ + path: join(this.storePath, 'contacts', instanceName), + fileName: contact.id, + data: contact, + }); + this.logger.verbose( + 'contacts saved to store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id, + ); + }); - this.logger.verbose('saving contacts to store'); + this.logger.verbose('contacts saved to store: ' + data.length + ' contacts'); + return { insertCount: data.length }; + } - const store = this.configService.get('STORE'); - - if (store.CONTACTS) { - this.logger.verbose('saving contacts to store'); - data.forEach((contact) => { - this.writeStore({ - path: join(this.storePath, 'contacts', instanceName), - fileName: contact.id, - data: contact, - }); - this.logger.verbose( - 'contacts saved to store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, - ); - }); - - this.logger.verbose('contacts saved to store: ' + data.length + ' contacts'); - return { insertCount: data.length }; - } - - this.logger.verbose('contacts not saved'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } + this.logger.verbose('contacts not saved'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; } + } - public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise { - try { - this.logger.verbose('updating contacts'); + public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise { + try { + this.logger.verbose('updating contacts'); - if (data.length === 0) { - this.logger.verbose('no contacts to update'); - return; - } + if (data.length === 0) { + this.logger.verbose('no contacts to update'); + return; + } - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('updating contacts in db'); + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('updating contacts in db'); - const contacts = data.map((contact) => { - return { - updateOne: { - filter: { id: contact.id }, - update: { ...contact }, - upsert: true, - }, - }; - }); + const contacts = data.map((contact) => { + return { + updateOne: { + filter: { id: contact.id }, + update: { ...contact }, + upsert: true, + }, + }; + }); - const { nModified } = await this.contactModel.bulkWrite(contacts); + const { nModified } = await this.contactModel.bulkWrite(contacts); - this.logger.verbose('contacts updated in db: ' + nModified + ' contacts'); - return { insertCount: nModified }; - } + this.logger.verbose('contacts updated in db: ' + nModified + ' contacts'); + return { insertCount: nModified }; + } - this.logger.verbose('updating contacts in store'); + this.logger.verbose('updating contacts in store'); - const store = this.configService.get('STORE'); + const store = this.configService.get('STORE'); - if (store.CONTACTS) { - this.logger.verbose('updating contacts in store'); - data.forEach((contact) => { - this.writeStore({ - path: join(this.storePath, 'contacts', instanceName), - fileName: contact.id, - data: contact, - }); - this.logger.verbose( - 'contacts updated in store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, - ); - }); + if (store.CONTACTS) { + this.logger.verbose('updating contacts in store'); + data.forEach((contact) => { + this.writeStore({ + path: join(this.storePath, 'contacts', instanceName), + fileName: contact.id, + data: contact, + }); + this.logger.verbose( + 'contacts updated in store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id, + ); + }); - this.logger.verbose('contacts updated in store: ' + data.length + ' contacts'); + this.logger.verbose('contacts updated in store: ' + data.length + ' contacts'); - return { insertCount: data.length }; - } + return { insertCount: data.length }; + } - this.logger.verbose('contacts not updated'); - return { insertCount: 0 }; - } catch (error) { - return error; - } finally { - data = undefined; - } + this.logger.verbose('contacts not updated'); + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; } + } - public async find(query: ContactQuery): Promise { - try { - this.logger.verbose('finding contacts'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding contacts in db'); - return await this.contactModel.find({ ...query.where }); - } + public async find(query: ContactQuery): Promise { + try { + this.logger.verbose('finding contacts'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding contacts in db'); + return await this.contactModel.find({ ...query.where }); + } - this.logger.verbose('finding contacts in store'); - const contacts: ContactRaw[] = []; - if (query?.where?.id) { - this.logger.verbose('finding contacts in store by id'); - contacts.push( - JSON.parse( - readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), { - encoding: 'utf-8', - }), - ), - ); - } else { - this.logger.verbose('finding contacts in store by owner'); + this.logger.verbose('finding contacts in store'); + const contacts: ContactRaw[] = []; + if (query?.where?.id) { + this.logger.verbose('finding contacts in store by id'); + contacts.push( + JSON.parse( + readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), { + encoding: 'utf-8', + }), + ), + ); + } else { + this.logger.verbose('finding contacts in store by owner'); - const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), { - encoding: 'utf-8', - }); - for await (const dirent of openDir) { - if (dirent.isFile()) { - contacts.push( - JSON.parse( - readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), { - encoding: 'utf-8', - }), - ), - ); - } - } - } - - this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts'); - return contacts; - } catch (error) { - return []; + const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), { + encoding: 'utf-8', + }); + for await (const dirent of openDir) { + if (dirent.isFile()) { + contacts.push( + JSON.parse( + readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } } + } + + this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts'); + return contacts; + } catch (error) { + return []; } + } } diff --git a/src/whatsapp/repository/message.repository.ts b/src/whatsapp/repository/message.repository.ts index efd57783..ed362815 100644 --- a/src/whatsapp/repository/message.repository.ts +++ b/src/whatsapp/repository/message.repository.ts @@ -7,145 +7,141 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IMessageModel, MessageRaw } from '../models'; export class MessageQuery { - where: MessageRaw; - limit?: number; + where: MessageRaw; + limit?: number; } export class MessageRepository extends Repository { - constructor(private readonly messageModel: IMessageModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly messageModel: IMessageModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('MessageRepository'); + + public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise { + this.logger.verbose('inserting messages'); + + if (!Array.isArray(data) || data.length === 0) { + this.logger.verbose('no messages to insert'); + return; } - private readonly logger = new Logger('MessageRepository'); + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving messages to db'); + const cleanedData = data.map((obj) => { + const cleanedObj = { ...obj }; + if ('extendedTextMessage' in obj.message) { + const extendedTextMessage = obj.message.extendedTextMessage as { + contextInfo?: { + mentionedJid?: any; + }; + }; - public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise { - this.logger.verbose('inserting messages'); - - if (!Array.isArray(data) || data.length === 0) { - this.logger.verbose('no messages to insert'); - return; - } - - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving messages to db'); - const cleanedData = data.map((obj) => { - const cleanedObj = { ...obj }; - if ('extendedTextMessage' in obj.message) { - const extendedTextMessage = obj.message.extendedTextMessage as { - contextInfo?: { - mentionedJid?: any; - }; - }; - - if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) { - if ('contextInfo' in extendedTextMessage) { - delete extendedTextMessage.contextInfo?.mentionedJid; - extendedTextMessage.contextInfo = {}; - } - } - } - return cleanedObj; - }); - - const insert = await this.messageModel.insertMany([...cleanedData]); - - this.logger.verbose('messages saved to db: ' + insert.length + ' messages'); - return { insertCount: insert.length }; + if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) { + if ('contextInfo' in extendedTextMessage) { + delete extendedTextMessage.contextInfo?.mentionedJid; + extendedTextMessage.contextInfo = {}; + } } + } + return cleanedObj; + }); - this.logger.verbose('saving messages to store'); + const insert = await this.messageModel.insertMany([...cleanedData]); - const store = this.configService.get('STORE'); + this.logger.verbose('messages saved to db: ' + insert.length + ' messages'); + return { insertCount: insert.length }; + } - if (store.MESSAGES) { - this.logger.verbose('saving messages to store'); + this.logger.verbose('saving messages to store'); - data.forEach((message) => { - this.writeStore({ - path: join(this.storePath, 'messages', instanceName), - fileName: message.key.id, - data: message, - }); - this.logger.verbose( - 'messages saved to store in path: ' + - join(this.storePath, 'messages', instanceName) + - '/' + - message.key.id, - ); - }); + const store = this.configService.get('STORE'); - this.logger.verbose('messages saved to store: ' + data.length + ' messages'); - return { insertCount: data.length }; - } + if (store.MESSAGES) { + this.logger.verbose('saving messages to store'); - this.logger.verbose('messages not saved to store'); - return { insertCount: 0 }; - } catch (error) { - console.log('ERROR: ', error); - return error; - } finally { - data = undefined; - } + data.forEach((message) => { + this.writeStore({ + path: join(this.storePath, 'messages', instanceName), + fileName: message.key.id, + data: message, + }); + this.logger.verbose( + 'messages saved to store in path: ' + join(this.storePath, 'messages', instanceName) + '/' + message.key.id, + ); + }); + + this.logger.verbose('messages saved to store: ' + data.length + ' messages'); + return { insertCount: data.length }; + } + + this.logger.verbose('messages not saved to store'); + return { insertCount: 0 }; + } catch (error) { + console.log('ERROR: ', error); + return error; + } finally { + data = undefined; } + } - public async find(query: MessageQuery) { - try { - this.logger.verbose('finding messages'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding messages in db'); - if (query?.where?.key) { - for (const [k, v] of Object.entries(query.where.key)) { - query.where['key.' + k] = v; - } - delete query?.where?.key; - } - - return await this.messageModel - .find({ ...query.where }) - .sort({ messageTimestamp: -1 }) - .limit(query?.limit ?? 0); - } - - this.logger.verbose('finding messages in store'); - const messages: MessageRaw[] = []; - if (query?.where?.key?.id) { - this.logger.verbose('finding messages in store by id'); - messages.push( - JSON.parse( - readFileSync( - join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), - { encoding: 'utf-8' }, - ), - ), - ); - } else { - this.logger.verbose('finding messages in store by owner'); - const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), { - encoding: 'utf-8', - }); - - for await (const dirent of openDir) { - if (dirent.isFile()) { - messages.push( - JSON.parse( - readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), { - encoding: 'utf-8', - }), - ), - ); - } - } - } - - this.logger.verbose('messages found in store: ' + messages.length + ' messages'); - return messages - .sort((x, y) => { - return (y.messageTimestamp as number) - (x.messageTimestamp as number); - }) - .splice(0, query?.limit ?? messages.length); - } catch (error) { - return []; + public async find(query: MessageQuery) { + try { + this.logger.verbose('finding messages'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding messages in db'); + if (query?.where?.key) { + for (const [k, v] of Object.entries(query.where.key)) { + query.where['key.' + k] = v; + } + delete query?.where?.key; } + + return await this.messageModel + .find({ ...query.where }) + .sort({ messageTimestamp: -1 }) + .limit(query?.limit ?? 0); + } + + this.logger.verbose('finding messages in store'); + const messages: MessageRaw[] = []; + if (query?.where?.key?.id) { + this.logger.verbose('finding messages in store by id'); + messages.push( + JSON.parse( + readFileSync(join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), { + encoding: 'utf-8', + }), + ), + ); + } else { + this.logger.verbose('finding messages in store by owner'); + const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), { + encoding: 'utf-8', + }); + + for await (const dirent of openDir) { + if (dirent.isFile()) { + messages.push( + JSON.parse( + readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } + } + } + + this.logger.verbose('messages found in store: ' + messages.length + ' messages'); + return messages + .sort((x, y) => { + return (y.messageTimestamp as number) - (x.messageTimestamp as number); + }) + .splice(0, query?.limit ?? messages.length); + } catch (error) { + return []; } + } } diff --git a/src/whatsapp/repository/messageUp.repository.ts b/src/whatsapp/repository/messageUp.repository.ts index 7a25467f..b97bf59b 100644 --- a/src/whatsapp/repository/messageUp.repository.ts +++ b/src/whatsapp/repository/messageUp.repository.ts @@ -7,117 +7,114 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IMessageUpModel, MessageUpdateRaw } from '../models'; export class MessageUpQuery { - where: MessageUpdateRaw; - limit?: number; + where: MessageUpdateRaw; + limit?: number; } export class MessageUpRepository extends Repository { - constructor(private readonly messageUpModel: IMessageUpModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly messageUpModel: IMessageUpModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('MessageUpRepository'); + + public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise { + this.logger.verbose('inserting message up'); + + if (data.length === 0) { + this.logger.verbose('no message up to insert'); + return; } - private readonly logger = new Logger('MessageUpRepository'); + try { + if (this.dbSettings.ENABLED && saveDb) { + this.logger.verbose('saving message up to db'); + const insert = await this.messageUpModel.insertMany([...data]); - public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise { - this.logger.verbose('inserting message up'); + this.logger.verbose('message up saved to db: ' + insert.length + ' message up'); + return { insertCount: insert.length }; + } - if (data.length === 0) { - this.logger.verbose('no message up to insert'); - return; - } + this.logger.verbose('saving message up to store'); - try { - if (this.dbSettings.ENABLED && saveDb) { - this.logger.verbose('saving message up to db'); - const insert = await this.messageUpModel.insertMany([...data]); + const store = this.configService.get('STORE'); - this.logger.verbose('message up saved to db: ' + insert.length + ' message up'); - return { insertCount: insert.length }; - } + if (store.MESSAGE_UP) { + this.logger.verbose('saving message up to store'); + data.forEach((update) => { + this.writeStore({ + path: join(this.storePath, 'message-up', instanceName), + fileName: update.id, + data: update, + }); + this.logger.verbose( + 'message up saved to store in path: ' + join(this.storePath, 'message-up', instanceName) + '/' + update.id, + ); + }); - this.logger.verbose('saving message up to store'); + this.logger.verbose('message up saved to store: ' + data.length + ' message up'); + return { insertCount: data.length }; + } - const store = this.configService.get('STORE'); - - if (store.MESSAGE_UP) { - this.logger.verbose('saving message up to store'); - data.forEach((update) => { - this.writeStore({ - path: join(this.storePath, 'message-up', instanceName), - fileName: update.id, - data: update, - }); - this.logger.verbose( - 'message up saved to store in path: ' + - join(this.storePath, 'message-up', instanceName) + - '/' + - update.id, - ); - }); - - this.logger.verbose('message up saved to store: ' + data.length + ' message up'); - return { insertCount: data.length }; - } - - this.logger.verbose('message up not saved to store'); - return { insertCount: 0 }; - } catch (error) { - return error; - } + this.logger.verbose('message up not saved to store'); + return { insertCount: 0 }; + } catch (error) { + return error; } + } - public async find(query: MessageUpQuery) { - try { - this.logger.verbose('finding message up'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding message up in db'); - return await this.messageUpModel - .find({ ...query.where }) - .sort({ datetime: -1 }) - .limit(query?.limit ?? 0); - } + public async find(query: MessageUpQuery) { + try { + this.logger.verbose('finding message up'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding message up in db'); + return await this.messageUpModel + .find({ ...query.where }) + .sort({ datetime: -1 }) + .limit(query?.limit ?? 0); + } - this.logger.verbose('finding message up in store'); + this.logger.verbose('finding message up in store'); - const messageUpdate: MessageUpdateRaw[] = []; - if (query?.where?.id) { - this.logger.verbose('finding message up in store by id'); + const messageUpdate: MessageUpdateRaw[] = []; + if (query?.where?.id) { + this.logger.verbose('finding message up in store by id'); - messageUpdate.push( - JSON.parse( - readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), { - encoding: 'utf-8', - }), - ), - ); - } else { - this.logger.verbose('finding message up in store by owner'); + messageUpdate.push( + JSON.parse( + readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), { + encoding: 'utf-8', + }), + ), + ); + } else { + this.logger.verbose('finding message up in store by owner'); - const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), { - encoding: 'utf-8', - }); + const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), { + encoding: 'utf-8', + }); - for await (const dirent of openDir) { - if (dirent.isFile()) { - messageUpdate.push( - JSON.parse( - readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), { - encoding: 'utf-8', - }), - ), - ); - } - } - } - - this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up'); - return messageUpdate - .sort((x, y) => { - return y.datetime - x.datetime; - }) - .splice(0, query?.limit ?? messageUpdate.length); - } catch (error) { - return []; + for await (const dirent of openDir) { + if (dirent.isFile()) { + messageUpdate.push( + JSON.parse( + readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), + ), + ); + } } + } + + this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up'); + return messageUpdate + .sort((x, y) => { + return y.datetime - x.datetime; + }) + .splice(0, query?.limit ?? messageUpdate.length); + } catch (error) { + return []; } + } } diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 46d92418..e1292329 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -13,105 +13,105 @@ import { MessageUpRepository } from './messageUp.repository'; import { SettingsRepository } from './settings.repository'; import { WebhookRepository } from './webhook.repository'; export class RepositoryBroker { - constructor( - public readonly message: MessageRepository, - public readonly chat: ChatRepository, - public readonly contact: ContactRepository, - public readonly messageUpdate: MessageUpRepository, - public readonly webhook: WebhookRepository, - public readonly chatwoot: ChatwootRepository, - public readonly settings: SettingsRepository, - public readonly auth: AuthRepository, - private configService: ConfigService, - dbServer?: MongoClient, - ) { - this.dbClient = dbServer; - this.__init_repo_without_db__(); - } + constructor( + public readonly message: MessageRepository, + public readonly chat: ChatRepository, + public readonly contact: ContactRepository, + public readonly messageUpdate: MessageUpRepository, + public readonly webhook: WebhookRepository, + public readonly chatwoot: ChatwootRepository, + public readonly settings: SettingsRepository, + public readonly auth: AuthRepository, + private configService: ConfigService, + dbServer?: MongoClient, + ) { + this.dbClient = dbServer; + this.__init_repo_without_db__(); + } - private dbClient?: MongoClient; - private readonly logger = new Logger('RepositoryBroker'); + private dbClient?: MongoClient; + private readonly logger = new Logger('RepositoryBroker'); - public get dbServer() { - return this.dbClient; - } + public get dbServer() { + return this.dbClient; + } - private __init_repo_without_db__() { - this.logger.verbose('initializing repository without db'); - if (!this.configService.get('DATABASE').ENABLED) { - const storePath = join(process.cwd(), 'store'); + private __init_repo_without_db__() { + this.logger.verbose('initializing repository without db'); + if (!this.configService.get('DATABASE').ENABLED) { + const storePath = join(process.cwd(), 'store'); - this.logger.verbose('creating store path: ' + storePath); - try { - const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); - const chatsDir = join(storePath, 'chats'); - const contactsDir = join(storePath, 'contacts'); - const messagesDir = join(storePath, 'messages'); - const messageUpDir = join(storePath, 'message-up'); - const webhookDir = join(storePath, 'webhook'); - const chatwootDir = join(storePath, 'chatwoot'); - const settingsDir = join(storePath, 'settings'); - const tempDir = join(storePath, 'temp'); + this.logger.verbose('creating store path: ' + storePath); + try { + const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); + const chatsDir = join(storePath, 'chats'); + const contactsDir = join(storePath, 'contacts'); + const messagesDir = join(storePath, 'messages'); + const messageUpDir = join(storePath, 'message-up'); + const webhookDir = join(storePath, 'webhook'); + const chatwootDir = join(storePath, 'chatwoot'); + const settingsDir = join(storePath, 'settings'); + const tempDir = join(storePath, 'temp'); - if (!fs.existsSync(authDir)) { - this.logger.verbose('creating auth dir: ' + authDir); - fs.mkdirSync(authDir, { recursive: true }); - } - if (!fs.existsSync(chatsDir)) { - this.logger.verbose('creating chats dir: ' + chatsDir); - fs.mkdirSync(chatsDir, { recursive: true }); - } - if (!fs.existsSync(contactsDir)) { - this.logger.verbose('creating contacts dir: ' + contactsDir); - fs.mkdirSync(contactsDir, { recursive: true }); - } - if (!fs.existsSync(messagesDir)) { - this.logger.verbose('creating messages dir: ' + messagesDir); - fs.mkdirSync(messagesDir, { recursive: true }); - } - if (!fs.existsSync(messageUpDir)) { - this.logger.verbose('creating message-up dir: ' + messageUpDir); - fs.mkdirSync(messageUpDir, { recursive: true }); - } - if (!fs.existsSync(webhookDir)) { - this.logger.verbose('creating webhook dir: ' + webhookDir); - fs.mkdirSync(webhookDir, { recursive: true }); - } - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(settingsDir)) { - this.logger.verbose('creating settings dir: ' + settingsDir); - fs.mkdirSync(settingsDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } - } else { - try { - const storePath = join(process.cwd(), 'store'); - - this.logger.verbose('creating store path: ' + storePath); - - const tempDir = join(storePath, 'temp'); - const chatwootDir = join(storePath, 'chatwoot'); - - if (!fs.existsSync(chatwootDir)) { - this.logger.verbose('creating chatwoot dir: ' + chatwootDir); - fs.mkdirSync(chatwootDir, { recursive: true }); - } - if (!fs.existsSync(tempDir)) { - this.logger.verbose('creating temp dir: ' + tempDir); - fs.mkdirSync(tempDir, { recursive: true }); - } - } catch (error) { - this.logger.error(error); - } + if (!fs.existsSync(authDir)) { + this.logger.verbose('creating auth dir: ' + authDir); + fs.mkdirSync(authDir, { recursive: true }); } + if (!fs.existsSync(chatsDir)) { + this.logger.verbose('creating chats dir: ' + chatsDir); + fs.mkdirSync(chatsDir, { recursive: true }); + } + if (!fs.existsSync(contactsDir)) { + this.logger.verbose('creating contacts dir: ' + contactsDir); + fs.mkdirSync(contactsDir, { recursive: true }); + } + if (!fs.existsSync(messagesDir)) { + this.logger.verbose('creating messages dir: ' + messagesDir); + fs.mkdirSync(messagesDir, { recursive: true }); + } + if (!fs.existsSync(messageUpDir)) { + this.logger.verbose('creating message-up dir: ' + messageUpDir); + fs.mkdirSync(messageUpDir, { recursive: true }); + } + if (!fs.existsSync(webhookDir)) { + this.logger.verbose('creating webhook dir: ' + webhookDir); + fs.mkdirSync(webhookDir, { recursive: true }); + } + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(settingsDir)) { + this.logger.verbose('creating settings dir: ' + settingsDir); + fs.mkdirSync(settingsDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } + } else { + try { + const storePath = join(process.cwd(), 'store'); + + this.logger.verbose('creating store path: ' + storePath); + + const tempDir = join(storePath, 'temp'); + const chatwootDir = join(storePath, 'chatwoot'); + + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } + if (!fs.existsSync(tempDir)) { + this.logger.verbose('creating temp dir: ' + tempDir); + fs.mkdirSync(tempDir, { recursive: true }); + } + } catch (error) { + this.logger.error(error); + } } + } } diff --git a/src/whatsapp/repository/settings.repository.ts b/src/whatsapp/repository/settings.repository.ts index 96003d69..4d09d79f 100644 --- a/src/whatsapp/repository/settings.repository.ts +++ b/src/whatsapp/repository/settings.repository.ts @@ -7,58 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { ISettingsModel, SettingsRaw } from '../models'; export class SettingsRepository extends Repository { - constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('SettingsRepository'); + + public async create(data: SettingsRaw, instance: string): Promise { + try { + this.logger.verbose('creating settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving settings to db'); + const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving settings to store'); + + this.writeStore({ + path: join(this.storePath, 'settings'), + fileName: instance, + data, + }); + + this.logger.verbose('settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance); + + this.logger.verbose('settings created'); + return { insertCount: 1 }; + } catch (error) { + return error; } + } - private readonly logger = new Logger('SettingsRepository'); + public async find(instance: string): Promise { + try { + this.logger.verbose('finding settings'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding settings in db'); + return await this.settingsModel.findOne({ _id: instance }); + } - public async create(data: SettingsRaw, instance: string): Promise { - try { - this.logger.verbose('creating settings'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving settings to db'); - const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - - this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving settings to store'); - - this.writeStore({ - path: join(this.storePath, 'settings'), - fileName: instance, - data, - }); - - this.logger.verbose( - 'settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance, - ); - - this.logger.verbose('settings created'); - return { insertCount: 1 }; - } catch (error) { - return error; - } - } - - public async find(instance: string): Promise { - try { - this.logger.verbose('finding settings'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding settings in db'); - return await this.settingsModel.findOne({ _id: instance }); - } - - this.logger.verbose('finding settings in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'settings', instance + '.json'), { - encoding: 'utf-8', - }), - ) as SettingsRaw; - } catch (error) { - return {}; - } + this.logger.verbose('finding settings in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'settings', instance + '.json'), { + encoding: 'utf-8', + }), + ) as SettingsRaw; + } catch (error) { + return {}; } + } } diff --git a/src/whatsapp/repository/webhook.repository.ts b/src/whatsapp/repository/webhook.repository.ts index f3e9d12f..10074516 100644 --- a/src/whatsapp/repository/webhook.repository.ts +++ b/src/whatsapp/repository/webhook.repository.ts @@ -7,56 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository'; import { IWebhookModel, WebhookRaw } from '../models'; export class WebhookRepository extends Repository { - constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) { - super(configService); + constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('WebhookRepository'); + + public async create(data: WebhookRaw, instance: string): Promise { + try { + this.logger.verbose('creating webhook'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving webhook to db'); + const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving webhook to store'); + + this.writeStore({ + path: join(this.storePath, 'webhook'), + fileName: instance, + data, + }); + + this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance); + + this.logger.verbose('webhook created'); + return { insertCount: 1 }; + } catch (error) { + return error; } + } - private readonly logger = new Logger('WebhookRepository'); + public async find(instance: string): Promise { + try { + this.logger.verbose('finding webhook'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding webhook in db'); + return await this.webhookModel.findOne({ _id: instance }); + } - public async create(data: WebhookRaw, instance: string): Promise { - try { - this.logger.verbose('creating webhook'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('saving webhook to db'); - const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - - this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook'); - return { insertCount: insert.modifiedCount }; - } - - this.logger.verbose('saving webhook to store'); - - this.writeStore({ - path: join(this.storePath, 'webhook'), - fileName: instance, - data, - }); - - this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance); - - this.logger.verbose('webhook created'); - return { insertCount: 1 }; - } catch (error) { - return error; - } - } - - public async find(instance: string): Promise { - try { - this.logger.verbose('finding webhook'); - if (this.dbSettings.ENABLED) { - this.logger.verbose('finding webhook in db'); - return await this.webhookModel.findOne({ _id: instance }); - } - - this.logger.verbose('finding webhook in store'); - return JSON.parse( - readFileSync(join(this.storePath, 'webhook', instance + '.json'), { - encoding: 'utf-8', - }), - ) as WebhookRaw; - } catch (error) { - return {}; - } + this.logger.verbose('finding webhook in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'webhook', instance + '.json'), { + encoding: 'utf-8', + }), + ) as WebhookRaw; + } catch (error) { + return {}; } + } } diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index ee7e972f..285c29a0 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - archiveChatSchema, - contactValidateSchema, - deleteMessageSchema, - messageUpSchema, - messageValidateSchema, - privacySettingsSchema, - profileNameSchema, - profilePictureSchema, - profileSchema, - profileStatusSchema, - readMessageSchema, - whatsappNumberSchema, + archiveChatSchema, + contactValidateSchema, + deleteMessageSchema, + messageUpSchema, + messageValidateSchema, + privacySettingsSchema, + profileNameSchema, + profilePictureSchema, + profileSchema, + profileStatusSchema, + readMessageSchema, + whatsappNumberSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberDto, - PrivacySettingDto, - ProfileNameDto, - ProfilePictureDto, - ProfileStatusDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberDto, + PrivacySettingDto, + ProfileNameDto, + ProfilePictureDto, + ProfileStatusDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; @@ -38,317 +38,317 @@ import { HttpStatus } from './index.router'; const logger = new Logger('ChatRouter'); export class ChatRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => { - logger.verbose('request received in whatsappNumbers'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => { + logger.verbose('request received in whatsappNumbers'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: whatsappNumberSchema, - ClassRef: WhatsAppNumberDto, - execute: (instance, data) => chatController.whatsappNumber(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: whatsappNumberSchema, + ClassRef: WhatsAppNumberDto, + execute: (instance, data) => chatController.whatsappNumber(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => { - logger.verbose('request received in markMessageAsRead'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => { + logger.verbose('request received in markMessageAsRead'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: readMessageSchema, - ClassRef: ReadMessageDto, - execute: (instance, data) => chatController.readMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: readMessageSchema, + ClassRef: ReadMessageDto, + execute: (instance, data) => chatController.readMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('archiveChat'), ...guards, async (req, res) => { - logger.verbose('request received in archiveChat'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('archiveChat'), ...guards, async (req, res) => { + logger.verbose('request received in archiveChat'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: archiveChatSchema, - ClassRef: ArchiveChatDto, - execute: (instance, data) => chatController.archiveChat(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: archiveChatSchema, + ClassRef: ArchiveChatDto, + execute: (instance, data) => chatController.archiveChat(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => { - logger.verbose('request received in deleteMessageForEveryone'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => { + logger.verbose('request received in deleteMessageForEveryone'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: deleteMessageSchema, - ClassRef: DeleteMessage, - execute: (instance, data) => chatController.deleteMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: deleteMessageSchema, + ClassRef: DeleteMessage, + execute: (instance, data) => chatController.deleteMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => { - logger.verbose('request received in fetchProfilePictureUrl'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => { + logger.verbose('request received in fetchProfilePictureUrl'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: NumberDto, - execute: (instance, data) => chatController.fetchProfilePicture(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: NumberDto, + execute: (instance, data) => chatController.fetchProfilePicture(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { - logger.verbose('request received in fetchProfile'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => { + logger.verbose('request received in fetchProfile'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileSchema, - ClassRef: NumberDto, - execute: (instance, data) => chatController.fetchProfile(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileSchema, + ClassRef: NumberDto, + execute: (instance, data) => chatController.fetchProfile(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('findContacts'), ...guards, async (req, res) => { - logger.verbose('request received in findContacts'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('findContacts'), ...guards, async (req, res) => { + logger.verbose('request received in findContacts'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: contactValidateSchema, - ClassRef: ContactQuery, - execute: (instance, data) => chatController.fetchContacts(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: contactValidateSchema, + ClassRef: ContactQuery, + execute: (instance, data) => chatController.fetchContacts(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => { - logger.verbose('request received in getBase64FromMediaMessage'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => { + logger.verbose('request received in getBase64FromMediaMessage'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: getBase64FromMediaMessageDto, - execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: getBase64FromMediaMessageDto, + execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('findMessages'), ...guards, async (req, res) => { - logger.verbose('request received in findMessages'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('findMessages'), ...guards, async (req, res) => { + logger.verbose('request received in findMessages'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: messageValidateSchema, - ClassRef: MessageQuery, - execute: (instance, data) => chatController.fetchMessages(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: messageValidateSchema, + ClassRef: MessageQuery, + execute: (instance, data) => chatController.fetchMessages(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => { - logger.verbose('request received in findStatusMessage'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => { + logger.verbose('request received in findStatusMessage'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: messageUpSchema, - ClassRef: MessageUpQuery, - execute: (instance, data) => chatController.fetchStatusMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: messageUpSchema, + ClassRef: MessageUpQuery, + execute: (instance, data) => chatController.fetchStatusMessage(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('findChats'), ...guards, async (req, res) => { - logger.verbose('request received in findChats'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('findChats'), ...guards, async (req, res) => { + logger.verbose('request received in findChats'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => chatController.fetchChats(instance), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => chatController.fetchChats(instance), + }); - return res.status(HttpStatus.OK).json(response); - }) - // Profile routes - .get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => { - logger.verbose('request received in fetchPrivacySettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + // Profile routes + .get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => { + logger.verbose('request received in fetchPrivacySettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => chatController.fetchPrivacySettings(instance), - }); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => chatController.fetchPrivacySettings(instance), + }); - return res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => { - logger.verbose('request received in updatePrivacySettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => { + logger.verbose('request received in updatePrivacySettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: privacySettingsSchema, - ClassRef: PrivacySettingDto, - execute: (instance, data) => chatController.updatePrivacySettings(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: privacySettingsSchema, + ClassRef: PrivacySettingDto, + execute: (instance, data) => chatController.updatePrivacySettings(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => { - logger.verbose('request received in fetchBusinessProfile'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => { + logger.verbose('request received in fetchBusinessProfile'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance, data) => chatController.fetchBusinessProfile(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance, data) => chatController.fetchBusinessProfile(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('updateProfileName'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfileName'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('updateProfileName'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfileName'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileNameSchema, - ClassRef: ProfileNameDto, - execute: (instance, data) => chatController.updateProfileName(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileNameSchema, + ClassRef: ProfileNameDto, + execute: (instance, data) => chatController.updateProfileName(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfileStatus'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfileStatus'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profileStatusSchema, - ClassRef: ProfileStatusDto, - execute: (instance, data) => chatController.updateProfileStatus(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profileStatusSchema, + ClassRef: ProfileStatusDto, + execute: (instance, data) => chatController.updateProfileStatus(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => { - logger.verbose('request received in updateProfilePicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => { + logger.verbose('request received in updateProfilePicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance, data) => chatController.updateProfilePicture(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance, data) => chatController.updateProfilePicture(instance, data), + }); - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => { - logger.verbose('request received in removeProfilePicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => { + logger.verbose('request received in removeProfilePicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: profilePictureSchema, - ClassRef: ProfilePictureDto, - execute: (instance) => chatController.removeProfilePicture(instance), - }); + const response = await this.dataValidate({ + request: req, + schema: profilePictureSchema, + ClassRef: ProfilePictureDto, + execute: (instance) => chatController.removeProfilePicture(instance), + }); - return res.status(HttpStatus.OK).json(response); - }); - } + return res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/chatwoot.router.ts b/src/whatsapp/routers/chatwoot.router.ts index 4556f4ec..eb779587 100644 --- a/src/whatsapp/routers/chatwoot.router.ts +++ b/src/whatsapp/routers/chatwoot.router.ts @@ -12,58 +12,58 @@ import { HttpStatus } from './index.router'; const logger = new Logger('ChatwootRouter'); export class ChatwootRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: chatwootSchema, - ClassRef: ChatwootDto, - execute: (instance, data) => chatwootController.createChatwoot(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: chatwootSchema, + ClassRef: ChatwootDto, + execute: (instance, data) => chatwootController.createChatwoot(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => chatwootController.findChatwoot(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => chatwootController.findChatwoot(instance), + }); - res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('webhook'), async (req, res) => { - logger.verbose('request received in findChatwoot'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('webhook'), async (req, res) => { + logger.verbose('request received in findChatwoot'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance, data) => chatwootController.receiveWebhook(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance, data) => chatwootController.receiveWebhook(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/group.router.ts b/src/whatsapp/routers/group.router.ts index 33c22f9b..f59e82a4 100644 --- a/src/whatsapp/routers/group.router.ts +++ b/src/whatsapp/routers/group.router.ts @@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - createGroupSchema, - getParticipantsSchema, - groupInviteSchema, - groupJidSchema, - groupSendInviteSchema, - toggleEphemeralSchema, - updateGroupDescriptionSchema, - updateGroupPictureSchema, - updateGroupSubjectSchema, - updateParticipantsSchema, - updateSettingsSchema, + createGroupSchema, + getParticipantsSchema, + groupInviteSchema, + groupJidSchema, + groupSendInviteSchema, + toggleEphemeralSchema, + updateGroupDescriptionSchema, + updateGroupPictureSchema, + updateGroupSubjectSchema, + updateParticipantsSchema, + updateSettingsSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { groupController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; @@ -34,251 +34,251 @@ import { HttpStatus } from './index.router'; const logger = new Logger('GroupRouter'); export class GroupRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('create'), ...guards, async (req, res) => { - logger.verbose('request received in createGroup'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('create'), ...guards, async (req, res) => { + logger.verbose('request received in createGroup'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: createGroupSchema, - ClassRef: CreateGroupDto, - execute: (instance, data) => groupController.createGroup(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: createGroupSchema, + ClassRef: CreateGroupDto, + execute: (instance, data) => groupController.createGroup(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupSubject'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupSubject'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupSubjectSchema, - ClassRef: GroupSubjectDto, - execute: (instance, data) => groupController.updateGroupSubject(instance, data), - }); + const response = await this.groupValidate({ + request: req, + schema: updateGroupSubjectSchema, + ClassRef: GroupSubjectDto, + execute: (instance, data) => groupController.updateGroupSubject(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupPicture'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupPicture'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupPictureSchema, - ClassRef: GroupPictureDto, - execute: (instance, data) => groupController.updateGroupPicture(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateGroupPictureSchema, + ClassRef: GroupPictureDto, + execute: (instance, data) => groupController.updateGroupPicture(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => { - logger.verbose('request received in updateGroupDescription'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => { + logger.verbose('request received in updateGroupDescription'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateGroupDescriptionSchema, - ClassRef: GroupDescriptionDto, - execute: (instance, data) => groupController.updateGroupDescription(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateGroupDescriptionSchema, + ClassRef: GroupDescriptionDto, + execute: (instance, data) => groupController.updateGroupDescription(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => { - logger.verbose('request received in findGroupInfos'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => { + logger.verbose('request received in findGroupInfos'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.findGroupInfo(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.findGroupInfo(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => { - logger.verbose('request received in fetchAllGroups'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => { + logger.verbose('request received in fetchAllGroups'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.getParticipantsValidate({ - request: req, - schema: getParticipantsSchema, - ClassRef: GetParticipant, - execute: (instance, data) => groupController.fetchAllGroups(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.getParticipantsValidate({ + request: req, + schema: getParticipantsSchema, + ClassRef: GetParticipant, + execute: (instance, data) => groupController.fetchAllGroups(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('participants'), ...guards, async (req, res) => { - logger.verbose('request received in participants'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('participants'), ...guards, async (req, res) => { + logger.verbose('request received in participants'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.findParticipants(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.findParticipants(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('inviteCode'), ...guards, async (req, res) => { - logger.verbose('request received in inviteCode'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('inviteCode'), ...guards, async (req, res) => { + logger.verbose('request received in inviteCode'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.inviteCode(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.inviteCode(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('inviteInfo'), ...guards, async (req, res) => { - logger.verbose('request received in inviteInfo'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('inviteInfo'), ...guards, async (req, res) => { + logger.verbose('request received in inviteInfo'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.inviteCodeValidate({ - request: req, - schema: groupInviteSchema, - ClassRef: GroupInvite, - execute: (instance, data) => groupController.inviteInfo(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.inviteCodeValidate({ + request: req, + schema: groupInviteSchema, + ClassRef: GroupInvite, + execute: (instance, data) => groupController.inviteInfo(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .post(this.routerPath('sendInvite'), ...guards, async (req, res) => { - logger.verbose('request received in sendInvite'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('sendInvite'), ...guards, async (req, res) => { + logger.verbose('request received in sendInvite'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupNoValidate({ - request: req, - schema: groupSendInviteSchema, - ClassRef: GroupSendInvite, - execute: (instance, data) => groupController.sendInvite(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupNoValidate({ + request: req, + schema: groupSendInviteSchema, + ClassRef: GroupSendInvite, + execute: (instance, data) => groupController.sendInvite(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }) - .put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => { - logger.verbose('request received in revokeInviteCode'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.OK).json(response); + }) + .put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => { + logger.verbose('request received in revokeInviteCode'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: groupJidSchema, - ClassRef: GroupJid, - execute: (instance, data) => groupController.revokeInviteCode(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: groupJidSchema, + ClassRef: GroupJid, + execute: (instance, data) => groupController.revokeInviteCode(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateParticipant'), ...guards, async (req, res) => { - logger.verbose('request received in updateParticipant'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateParticipant'), ...guards, async (req, res) => { + logger.verbose('request received in updateParticipant'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateParticipantsSchema, - ClassRef: GroupUpdateParticipantDto, - execute: (instance, data) => groupController.updateGParticipate(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateParticipantsSchema, + ClassRef: GroupUpdateParticipantDto, + execute: (instance, data) => groupController.updateGParticipate(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('updateSetting'), ...guards, async (req, res) => { - logger.verbose('request received in updateSetting'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('updateSetting'), ...guards, async (req, res) => { + logger.verbose('request received in updateSetting'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: updateSettingsSchema, - ClassRef: GroupUpdateSettingDto, - execute: (instance, data) => groupController.updateGSetting(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: updateSettingsSchema, + ClassRef: GroupUpdateSettingDto, + execute: (instance, data) => groupController.updateGSetting(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => { - logger.verbose('request received in toggleEphemeral'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => { + logger.verbose('request received in toggleEphemeral'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: toggleEphemeralSchema, - ClassRef: GroupToggleEphemeralDto, - execute: (instance, data) => groupController.toggleEphemeral(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: toggleEphemeralSchema, + ClassRef: GroupToggleEphemeralDto, + execute: (instance, data) => groupController.toggleEphemeral(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => { - logger.verbose('request received in leaveGroup'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => { + logger.verbose('request received in leaveGroup'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.groupValidate({ - request: req, - schema: {}, - ClassRef: GroupJid, - execute: (instance, data) => groupController.leaveGroup(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.groupValidate({ + request: req, + schema: {}, + ClassRef: GroupJid, + execute: (instance, data) => groupController.leaveGroup(instance, data), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 941efeda..db082799 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -14,13 +14,13 @@ import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; enum HttpStatus { - OK = 200, - CREATED = 201, - NOT_FOUND = 404, - FORBIDDEN = 403, - BAD_REQUEST = 400, - UNAUTHORIZED = 401, - INTERNAL_SERVER_ERROR = 500, + OK = 200, + CREATED = 201, + NOT_FOUND = 404, + FORBIDDEN = 403, + BAD_REQUEST = 400, + UNAUTHORIZED = 401, + INTERNAL_SERVER_ERROR = 500, } const router = Router(); @@ -30,19 +30,19 @@ const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]]; const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); router - .get('/', (req, res) => { - res.status(HttpStatus.OK).json({ - status: HttpStatus.OK, - message: 'Welcome to the Evolution API, it is working!', - version: packageJson.version, - }); - }) - .use('/instance', new InstanceRouter(configService, ...guards).router, new ViewsRouter(instanceExistsGuard).router) - .use('/message', new MessageRouter(...guards).router) - .use('/chat', new ChatRouter(...guards).router) - .use('/group', new GroupRouter(...guards).router) - .use('/webhook', new WebhookRouter(...guards).router) - .use('/chatwoot', new ChatwootRouter(...guards).router) - .use('/settings', new SettingsRouter(...guards).router); + .get('/', (req, res) => { + res.status(HttpStatus.OK).json({ + status: HttpStatus.OK, + message: 'Welcome to the Evolution API, it is working!', + version: packageJson.version, + }); + }) + .use('/instance', new InstanceRouter(configService, ...guards).router, new ViewsRouter(instanceExistsGuard).router) + .use('/message', new MessageRouter(...guards).router) + .use('/chat', new ChatRouter(...guards).router) + .use('/group', new GroupRouter(...guards).router) + .use('/webhook', new WebhookRouter(...guards).router) + .use('/chatwoot', new ChatwootRouter(...guards).router) + .use('/settings', new SettingsRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 2c0f6a38..ae6d4066 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -13,165 +13,163 @@ import { HttpStatus } from './index.router'; const logger = new Logger('InstanceRouter'); export class InstanceRouter extends RouterBroker { - constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) { - super(); - const auth = configService.get('AUTHENTICATION'); - this.router - .post('/create', ...guards, async (req, res) => { - logger.verbose('request received in createInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) { + super(); + const auth = configService.get('AUTHENTICATION'); + this.router + .post('/create', ...guards, async (req, res) => { + logger.verbose('request received in createInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.createInstance(instance), - }); - - return res.status(HttpStatus.CREATED).json(response); - }) - .put(this.routerPath('restart'), ...guards, async (req, res) => { - logger.verbose('request received in restartInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.restartInstance(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('connect'), ...guards, async (req, res) => { - logger.verbose('request received in connectInstance'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.connectToWhatsapp(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('connectionState'), ...guards, async (req, res) => { - logger.verbose('request received in connectionState'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.connectionState(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => { - logger.verbose('request received in fetchInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: null, - ClassRef: InstanceDto, - execute: (instance) => instanceController.fetchInstances(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('logout'), ...guards, async (req, res) => { - logger.verbose('request received in logoutInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.logout(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }) - .delete(this.routerPath('delete'), ...guards, async (req, res) => { - logger.verbose('request received in deleteInstances'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => instanceController.deleteInstance(instance), - }); - - return res.status(HttpStatus.OK).json(response); - }); - - if (auth.TYPE === 'jwt') { - this.router.put('/refreshToken', async (req, res) => { - logger.verbose('request received in refreshToken'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: oldTokenSchema, - ClassRef: OldToken, - execute: (_, data) => instanceController.refreshToken(_, data), - }); - - return res.status(HttpStatus.CREATED).json(response); - }); - } - - this.router.delete('/deleteDatabase', async (req, res) => { - logger.verbose('request received in deleteDatabase'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const db = this.configService.get('DATABASE'); - if (db.ENABLED) { - try { - await dbserver.dropDatabase(); - return res.status(HttpStatus.CREATED).json({ error: false, message: 'Database deleted' }); - } catch (error) { - return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message }); - } - } - - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ error: true, message: 'Database is not enabled' }); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.createInstance(instance), }); + + return res.status(HttpStatus.CREATED).json(response); + }) + .put(this.routerPath('restart'), ...guards, async (req, res) => { + logger.verbose('request received in restartInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.restartInstance(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('connect'), ...guards, async (req, res) => { + logger.verbose('request received in connectInstance'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.connectToWhatsapp(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('connectionState'), ...guards, async (req, res) => { + logger.verbose('request received in connectionState'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.connectionState(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => { + logger.verbose('request received in fetchInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: null, + ClassRef: InstanceDto, + execute: (instance) => instanceController.fetchInstances(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('logout'), ...guards, async (req, res) => { + logger.verbose('request received in logoutInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.logout(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }) + .delete(this.routerPath('delete'), ...guards, async (req, res) => { + logger.verbose('request received in deleteInstances'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => instanceController.deleteInstance(instance), + }); + + return res.status(HttpStatus.OK).json(response); + }); + + if (auth.TYPE === 'jwt') { + this.router.put('/refreshToken', async (req, res) => { + logger.verbose('request received in refreshToken'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: oldTokenSchema, + ClassRef: OldToken, + execute: (_, data) => instanceController.refreshToken(_, data), + }); + + return res.status(HttpStatus.CREATED).json(response); + }); } - public readonly router = Router(); + this.router.delete('/deleteDatabase', async (req, res) => { + logger.verbose('request received in deleteDatabase'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const db = this.configService.get('DATABASE'); + if (db.ENABLED) { + try { + await dbserver.dropDatabase(); + return res.status(HttpStatus.CREATED).json({ error: false, message: 'Database deleted' }); + } catch (error) { + return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message }); + } + } + + return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: 'Database is not enabled' }); + }); + } + + public readonly router = Router(); } diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index 4550ff8b..d87db44d 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; import { - audioMessageSchema, - buttonMessageSchema, - contactMessageSchema, - listMessageSchema, - locationMessageSchema, - mediaMessageSchema, - pollMessageSchema, - reactionMessageSchema, - statusMessageSchema, - stickerMessageSchema, - textMessageSchema, + audioMessageSchema, + buttonMessageSchema, + contactMessageSchema, + listMessageSchema, + locationMessageSchema, + mediaMessageSchema, + pollMessageSchema, + reactionMessageSchema, + statusMessageSchema, + stickerMessageSchema, + textMessageSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, } from '../dto/sendMessage.dto'; import { sendMessageController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; @@ -34,186 +34,186 @@ import { HttpStatus } from './index.router'; const logger = new Logger('MessageRouter'); export class MessageRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('sendText'), ...guards, async (req, res) => { - logger.verbose('request received in sendText'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('sendText'), ...guards, async (req, res) => { + logger.verbose('request received in sendText'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: textMessageSchema, - ClassRef: SendTextDto, - execute: (instance, data) => sendMessageController.sendText(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: textMessageSchema, + ClassRef: SendTextDto, + execute: (instance, data) => sendMessageController.sendText(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendMedia'), ...guards, async (req, res) => { - logger.verbose('request received in sendMedia'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendMedia'), ...guards, async (req, res) => { + logger.verbose('request received in sendMedia'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: mediaMessageSchema, - ClassRef: SendMediaDto, - execute: (instance, data) => sendMessageController.sendMedia(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: mediaMessageSchema, + ClassRef: SendMediaDto, + execute: (instance, data) => sendMessageController.sendMedia(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => { - logger.verbose('request received in sendWhatsAppAudio'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => { + logger.verbose('request received in sendWhatsAppAudio'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: audioMessageSchema, - ClassRef: SendMediaDto, - execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: audioMessageSchema, + ClassRef: SendMediaDto, + execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendButtons'), ...guards, async (req, res) => { - logger.verbose('request received in sendButtons'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendButtons'), ...guards, async (req, res) => { + logger.verbose('request received in sendButtons'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: buttonMessageSchema, - ClassRef: SendButtonDto, - execute: (instance, data) => sendMessageController.sendButtons(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: buttonMessageSchema, + ClassRef: SendButtonDto, + execute: (instance, data) => sendMessageController.sendButtons(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendLocation'), ...guards, async (req, res) => { - logger.verbose('request received in sendLocation'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendLocation'), ...guards, async (req, res) => { + logger.verbose('request received in sendLocation'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: locationMessageSchema, - ClassRef: SendLocationDto, - execute: (instance, data) => sendMessageController.sendLocation(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: locationMessageSchema, + ClassRef: SendLocationDto, + execute: (instance, data) => sendMessageController.sendLocation(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendList'), ...guards, async (req, res) => { - logger.verbose('request received in sendList'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendList'), ...guards, async (req, res) => { + logger.verbose('request received in sendList'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: listMessageSchema, - ClassRef: SendListDto, - execute: (instance, data) => sendMessageController.sendList(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: listMessageSchema, + ClassRef: SendListDto, + execute: (instance, data) => sendMessageController.sendList(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendContact'), ...guards, async (req, res) => { - logger.verbose('request received in sendContact'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendContact'), ...guards, async (req, res) => { + logger.verbose('request received in sendContact'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: contactMessageSchema, - ClassRef: SendContactDto, - execute: (instance, data) => sendMessageController.sendContact(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: contactMessageSchema, + ClassRef: SendContactDto, + execute: (instance, data) => sendMessageController.sendContact(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendReaction'), ...guards, async (req, res) => { - logger.verbose('request received in sendReaction'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendReaction'), ...guards, async (req, res) => { + logger.verbose('request received in sendReaction'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: reactionMessageSchema, - ClassRef: SendReactionDto, - execute: (instance, data) => sendMessageController.sendReaction(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: reactionMessageSchema, + ClassRef: SendReactionDto, + execute: (instance, data) => sendMessageController.sendReaction(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendPoll'), ...guards, async (req, res) => { - logger.verbose('request received in sendPoll'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendPoll'), ...guards, async (req, res) => { + logger.verbose('request received in sendPoll'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: pollMessageSchema, - ClassRef: SendPollDto, - execute: (instance, data) => sendMessageController.sendPoll(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: pollMessageSchema, + ClassRef: SendPollDto, + execute: (instance, data) => sendMessageController.sendPoll(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendStatus'), ...guards, async (req, res) => { - logger.verbose('request received in sendStatus'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendStatus'), ...guards, async (req, res) => { + logger.verbose('request received in sendStatus'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: statusMessageSchema, - ClassRef: SendStatusDto, - execute: (instance, data) => sendMessageController.sendStatus(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: statusMessageSchema, + ClassRef: SendStatusDto, + execute: (instance, data) => sendMessageController.sendStatus(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }) - .post(this.routerPath('sendSticker'), ...guards, async (req, res) => { - logger.verbose('request received in sendSticker'); - logger.verbose('request body: '); - logger.verbose(req.body); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('sendSticker'), ...guards, async (req, res) => { + logger.verbose('request received in sendSticker'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: stickerMessageSchema, - ClassRef: SendStickerDto, - execute: (instance, data) => sendMessageController.sendSticker(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: stickerMessageSchema, + ClassRef: SendStickerDto, + execute: (instance, data) => sendMessageController.sendSticker(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }); - } + return res.status(HttpStatus.CREATED).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts index be364885..6bd4d549 100644 --- a/src/whatsapp/routers/settings.router.ts +++ b/src/whatsapp/routers/settings.router.ts @@ -12,42 +12,42 @@ import { HttpStatus } from './index.router'; const logger = new Logger('SettingsRouter'); export class SettingsRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setSettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: settingsSchema, - ClassRef: SettingsDto, - execute: (instance, data) => settingsController.createSettings(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: settingsSchema, + ClassRef: SettingsDto, + execute: (instance, data) => settingsController.createSettings(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findSettings'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findSettings'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => settingsController.findSettings(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => settingsController.findSettings(instance), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/view.router.ts b/src/whatsapp/routers/view.router.ts index 297f0125..c5e18129 100644 --- a/src/whatsapp/routers/view.router.ts +++ b/src/whatsapp/routers/view.router.ts @@ -4,13 +4,13 @@ import { RouterBroker } from '../abstract/abstract.router'; import { viewsController } from '../whatsapp.module'; export class ViewsRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); + constructor(...guards: RequestHandler[]) { + super(); - this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => { - return viewsController.qrcode(req, res); - }); - } + this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => { + return viewsController.qrcode(req, res); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/routers/webhook.router.ts b/src/whatsapp/routers/webhook.router.ts index ef95e5a2..835d6014 100644 --- a/src/whatsapp/routers/webhook.router.ts +++ b/src/whatsapp/routers/webhook.router.ts @@ -11,42 +11,42 @@ import { HttpStatus } from './index.router'; const logger = new Logger('WebhookRouter'); export class WebhookRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { - super(); - this.router - .post(this.routerPath('set'), ...guards, async (req, res) => { - logger.verbose('request received in setWebhook'); - logger.verbose('request body: '); - logger.verbose(req.body); + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setWebhook'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: webhookSchema, - ClassRef: WebhookDto, - execute: (instance, data) => webhookController.createWebhook(instance, data), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: webhookSchema, + ClassRef: WebhookDto, + execute: (instance, data) => webhookController.createWebhook(instance, data), + }); - res.status(HttpStatus.CREATED).json(response); - }) - .get(this.routerPath('find'), ...guards, async (req, res) => { - logger.verbose('request received in findWebhook'); - logger.verbose('request body: '); - logger.verbose(req.body); + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findWebhook'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: instanceNameSchema, - ClassRef: InstanceDto, - execute: (instance) => webhookController.findWebhook(instance), - }); + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => webhookController.findWebhook(instance), + }); - res.status(HttpStatus.OK).json(response); - }); - } + res.status(HttpStatus.OK).json(response); + }); + } - public readonly router = Router(); + public readonly router = Router(); } diff --git a/src/whatsapp/services/auth.service.ts b/src/whatsapp/services/auth.service.ts index f5cd0c38..915a07b7 100644 --- a/src/whatsapp/services/auth.service.ts +++ b/src/whatsapp/services/auth.service.ts @@ -12,166 +12,166 @@ import { RepositoryBroker } from '../repository/repository.manager'; import { WAMonitoringService } from './monitor.service'; export type JwtPayload = { - instanceName: string; - apiName: string; - jwt?: string; - apikey?: string; - tokenId: string; + instanceName: string; + apiName: string; + jwt?: string; + apikey?: string; + tokenId: string; }; export class OldToken { - oldToken: string; + oldToken: string; } export class AuthService { - constructor( - private readonly configService: ConfigService, - private readonly waMonitor: WAMonitoringService, - private readonly repository: RepositoryBroker, - ) {} + constructor( + private readonly configService: ConfigService, + private readonly waMonitor: WAMonitoringService, + private readonly repository: RepositoryBroker, + ) {} - private readonly logger = new Logger(AuthService.name); + private readonly logger = new Logger(AuthService.name); - private async jwt(instance: InstanceDto) { - const jwtOpts = this.configService.get('AUTHENTICATION').JWT; - const token = sign( + private async jwt(instance: InstanceDto) { + const jwtOpts = this.configService.get('AUTHENTICATION').JWT; + const token = sign( + { + instanceName: instance.instanceName, + apiName, + tokenId: v4(), + }, + jwtOpts.SECRET, + { expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' }, + ); + + this.logger.verbose('JWT token created: ' + token); + + const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName); + + this.logger.verbose('JWT token saved in database'); + + if (auth['error']) { + this.logger.error({ + localError: AuthService.name + '.jwt', + error: auth['error'], + }); + throw new BadRequestException('Authentication error', auth['error']?.toString()); + } + + return { jwt: token }; + } + + private async apikey(instance: InstanceDto, token?: string) { + const apikey = token ? token : v4().toUpperCase(); + + this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey); + + const auth = await this.repository.auth.create({ apikey }, instance.instanceName); + + this.logger.verbose('APIKEY saved in database'); + + if (auth['error']) { + this.logger.error({ + localError: AuthService.name + '.apikey', + error: auth['error'], + }); + throw new BadRequestException('Authentication error', auth['error']?.toString()); + } + + return { apikey }; + } + + public async checkDuplicateToken(token: string) { + const instances = await this.waMonitor.instanceInfo(); + + this.logger.verbose('checking duplicate token'); + + const instance = instances.find((instance) => instance.instance.apikey === token); + + if (instance) { + throw new BadRequestException('Token already exists'); + } + + this.logger.verbose('available token'); + + return true; + } + + public async generateHash(instance: InstanceDto, token?: string) { + const options = this.configService.get('AUTHENTICATION'); + + this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName); + + return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string }; + } + + public async refreshToken({ oldToken }: OldToken) { + this.logger.verbose('refreshing token'); + + if (!isJWT(oldToken)) { + throw new BadRequestException('Invalid "oldToken"'); + } + + try { + const jwtOpts = this.configService.get('AUTHENTICATION').JWT; + + this.logger.verbose('checking oldToken'); + + const decode = verify(oldToken, jwtOpts.SECRET, { + ignoreExpiration: true, + }) as Pick; + + this.logger.verbose('checking token in database'); + + const tokenStore = await this.repository.auth.find(decode.instanceName); + + const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, { + ignoreExpiration: true, + }) as Pick; + + this.logger.verbose('checking tokenId'); + + if (decode.tokenId !== decodeTokenStore.tokenId) { + throw new BadRequestException('Invalid "oldToken"'); + } + + this.logger.verbose('generating new token'); + + const token = { + jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt, + instanceName: decode.instanceName, + }; + + try { + this.logger.verbose('checking webhook'); + const webhook = await this.repository.webhook.find(decode.instanceName); + if (webhook?.enabled && this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN) { + this.logger.verbose('sending webhook'); + + const httpService = axios.create({ baseURL: webhook.url }); + await httpService.post( + '', { - instanceName: instance.instanceName, - apiName, - tokenId: v4(), + event: 'new.jwt', + instance: decode.instanceName, + data: token, }, - jwtOpts.SECRET, - { expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' }, - ); - - this.logger.verbose('JWT token created: ' + token); - - const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName); - - this.logger.verbose('JWT token saved in database'); - - if (auth['error']) { - this.logger.error({ - localError: AuthService.name + '.jwt', - error: auth['error'], - }); - throw new BadRequestException('Authentication error', auth['error']?.toString()); + { params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } }, + ); } + } catch (error) { + this.logger.error(error); + } - return { jwt: token }; - } - - private async apikey(instance: InstanceDto, token?: string) { - const apikey = token ? token : v4().toUpperCase(); - - this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey); - - const auth = await this.repository.auth.create({ apikey }, instance.instanceName); - - this.logger.verbose('APIKEY saved in database'); - - if (auth['error']) { - this.logger.error({ - localError: AuthService.name + '.apikey', - error: auth['error'], - }); - throw new BadRequestException('Authentication error', auth['error']?.toString()); - } - - return { apikey }; - } - - public async checkDuplicateToken(token: string) { - const instances = await this.waMonitor.instanceInfo(); - - this.logger.verbose('checking duplicate token'); - - const instance = instances.find((instance) => instance.instance.apikey === token); - - if (instance) { - throw new BadRequestException('Token already exists'); - } - - this.logger.verbose('available token'); - - return true; - } - - public async generateHash(instance: InstanceDto, token?: string) { - const options = this.configService.get('AUTHENTICATION'); - - this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName); - - return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string }; - } - - public async refreshToken({ oldToken }: OldToken) { - this.logger.verbose('refreshing token'); - - if (!isJWT(oldToken)) { - throw new BadRequestException('Invalid "oldToken"'); - } - - try { - const jwtOpts = this.configService.get('AUTHENTICATION').JWT; - - this.logger.verbose('checking oldToken'); - - const decode = verify(oldToken, jwtOpts.SECRET, { - ignoreExpiration: true, - }) as Pick; - - this.logger.verbose('checking token in database'); - - const tokenStore = await this.repository.auth.find(decode.instanceName); - - const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, { - ignoreExpiration: true, - }) as Pick; - - this.logger.verbose('checking tokenId'); - - if (decode.tokenId !== decodeTokenStore.tokenId) { - throw new BadRequestException('Invalid "oldToken"'); - } - - this.logger.verbose('generating new token'); - - const token = { - jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt, - instanceName: decode.instanceName, - }; - - try { - this.logger.verbose('checking webhook'); - const webhook = await this.repository.webhook.find(decode.instanceName); - if (webhook?.enabled && this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN) { - this.logger.verbose('sending webhook'); - - const httpService = axios.create({ baseURL: webhook.url }); - await httpService.post( - '', - { - event: 'new.jwt', - instance: decode.instanceName, - data: token, - }, - { params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } }, - ); - } - } catch (error) { - this.logger.error(error); - } - - this.logger.verbose('token refreshed'); - - return token; - } catch (error) { - this.logger.error({ - localError: AuthService.name + '.refreshToken', - error, - }); - throw new BadRequestException('Invalid "oldToken"'); - } + this.logger.verbose('token refreshed'); + + return token; + } catch (error) { + this.logger.error({ + localError: AuthService.name + '.refreshToken', + error, + }); + throw new BadRequestException('Invalid "oldToken"'); } + } } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index a2bd9bff..5acfe05b 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -15,1570 +15,1539 @@ import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto' import { WAMonitoringService } from './monitor.service'; export class ChatwootService { - private messageCacheFile: string; - private messageCache: Set; + private messageCacheFile: string; + private messageCache: Set; - private readonly logger = new Logger(ChatwootService.name); + private readonly logger = new Logger(ChatwootService.name); - private provider: any; + private provider: any; - constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { - this.messageCache = new Set(); + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { + this.messageCache = new Set(); + } + + private loadMessageCache(): Set { + this.logger.verbose('load message cache'); + try { + const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); + const cacheArray = cacheData.split('\n'); + return new Set(cacheArray); + } catch (error) { + return new Set(); + } + } + + private saveMessageCache() { + this.logger.verbose('save message cache'); + const cacheData = Array.from(this.messageCache).join('\n'); + writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); + this.logger.verbose('message cache saved'); + } + + private clearMessageCache() { + this.logger.verbose('clear message cache'); + this.messageCache.clear(); + this.saveMessageCache(); + } + + private async getProvider(instance: InstanceDto) { + this.logger.verbose('get provider to instance: ' + instance.instanceName); + try { + const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + + if (!provider) { + this.logger.warn('provider not found'); + return null; + } + + this.logger.verbose('provider found'); + + return provider; + } catch (error) { + this.logger.error('provider not found'); + return null; + } + } + + private async clientCw(instance: InstanceDto) { + this.logger.verbose('get client to instance: ' + instance.instanceName); + const provider = await this.getProvider(instance); + + if (!provider) { + this.logger.error('provider not found'); + return null; } - private loadMessageCache(): Set { - this.logger.verbose('load message cache'); - try { - const cacheData = readFileSync(this.messageCacheFile, 'utf-8'); - const cacheArray = cacheData.split('\n'); - return new Set(cacheArray); - } catch (error) { - return new Set(); - } + this.logger.verbose('provider found'); + + this.provider = provider; + + this.logger.verbose('create client to instance: ' + instance.instanceName); + const client = new ChatwootClient({ + config: { + basePath: provider.url, + with_credentials: true, + credentials: 'include', + token: provider.token, + }, + }); + + this.logger.verbose('client created'); + + return client; + } + + public create(instance: InstanceDto, data: ChatwootDto) { + this.logger.verbose('create chatwoot: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + + this.logger.verbose('chatwoot created'); + return data; + } + + public async find(instance: InstanceDto): Promise { + this.logger.verbose('find chatwoot: ' + instance.instanceName); + try { + return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + } catch (error) { + this.logger.error('chatwoot not found'); + return { enabled: null, url: '' }; + } + } + + public async getContact(instance: InstanceDto, id: number) { + this.logger.verbose('get contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; } - private saveMessageCache() { - this.logger.verbose('save message cache'); - const cacheData = Array.from(this.messageCache).join('\n'); - writeFileSync(this.messageCacheFile, cacheData, 'utf-8'); - this.logger.verbose('message cache saved'); + if (!id) { + this.logger.warn('id is required'); + return null; } - private clearMessageCache() { - this.logger.verbose('clear message cache'); - this.messageCache.clear(); - this.saveMessageCache(); + this.logger.verbose('find contact in chatwoot'); + const contact = await client.contact.getContactable({ + accountId: this.provider.account_id, + id, + }); + + if (!contact) { + this.logger.warn('contact not found'); + return null; } - private async getProvider(instance: InstanceDto) { - this.logger.verbose('get provider to instance: ' + instance.instanceName); - try { - const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); + this.logger.verbose('contact found'); + return contact; + } - if (!provider) { - this.logger.warn('provider not found'); - return null; - } + public async initInstanceChatwoot( + instance: InstanceDto, + inboxName: string, + webhookUrl: string, + qrcode: boolean, + number: string, + ) { + this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - this.logger.verbose('provider found'); + const client = await this.clientCw(instance); - return provider; - } catch (error) { - this.logger.error('provider not found'); - return null; - } + if (!client) { + this.logger.warn('client not found'); + return null; } - private async clientCw(instance: InstanceDto) { - this.logger.verbose('get client to instance: ' + instance.instanceName); - const provider = await this.getProvider(instance); + this.logger.verbose('find inbox in chatwoot'); + const findInbox: any = await client.inboxes.list({ + accountId: this.provider.account_id, + }); - if (!provider) { - this.logger.error('provider not found'); - return null; - } + this.logger.verbose('check duplicate inbox'); + const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); - this.logger.verbose('provider found'); + let inboxId: number; - this.provider = provider; + if (!checkDuplicate) { + this.logger.verbose('create inbox in chatwoot'); + const data = { + type: 'api', + webhook_url: webhookUrl, + }; - this.logger.verbose('create client to instance: ' + instance.instanceName); - const client = new ChatwootClient({ - config: { - basePath: provider.url, - with_credentials: true, - credentials: 'include', - token: provider.token, - }, - }); + const inbox = await client.inboxes.create({ + accountId: this.provider.account_id, + data: { + name: inboxName, + channel: data as any, + }, + }); - this.logger.verbose('client created'); + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } - return client; + inboxId = inbox.id; + } else { + this.logger.verbose('find inbox in chatwoot'); + const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); + + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } + + inboxId = inbox.id; } - public create(instance: InstanceDto, data: ChatwootDto) { - this.logger.verbose('create chatwoot: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); + this.logger.verbose('find contact in chatwoot and create if not exists'); + const contact = + (await this.findContact(instance, '123456')) || + ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); - this.logger.verbose('chatwoot created'); - return data; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async find(instance: InstanceDto): Promise { - this.logger.verbose('find chatwoot: ' + instance.instanceName); - try { - return await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); - } catch (error) { - this.logger.error('chatwoot not found'); - return { enabled: null, url: '' }; - } + const contactId = contact.id || contact.payload.contact.id; + + if (qrcode) { + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('create message for init instance in chatwoot'); + + let contentMsg = '/init'; + + if (number) { + contentMsg = `/init:${number}`; + } + + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: contentMsg, + message_type: 'outgoing', + }, + }); + + if (!message) { + this.logger.warn('conversation not found'); + return null; + } } - public async getContact(instance: InstanceDto, id: number) { - this.logger.verbose('get contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + this.logger.verbose('instance chatwoot initialized'); + return true; + } - if (!client) { - this.logger.warn('client not found'); - return null; - } + public async createContact( + instance: InstanceDto, + phoneNumber: string, + inboxId: number, + isGroup: boolean, + name?: string, + avatar_url?: string, + ) { + this.logger.verbose('create contact to instance: ' + instance.instanceName); - if (!id) { - this.logger.warn('id is required'); - return null; - } + const client = await this.clientCw(instance); - this.logger.verbose('find contact in chatwoot'); - const contact = await client.contact.getContactable({ - accountId: this.provider.account_id, - id, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact found'); - return contact; + if (!client) { + this.logger.warn('client not found'); + return null; } - public async initInstanceChatwoot( - instance: InstanceDto, - inboxName: string, - webhookUrl: string, - qrcode: boolean, - number: string, - ) { - this.logger.verbose('init instance chatwoot: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inbox in chatwoot'); - const findInbox: any = await client.inboxes.list({ - accountId: this.provider.account_id, - }); - - this.logger.verbose('check duplicate inbox'); - const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); - - let inboxId: number; - - if (!checkDuplicate) { - this.logger.verbose('create inbox in chatwoot'); - const data = { - type: 'api', - webhook_url: webhookUrl, - }; - - const inbox = await client.inboxes.create({ - accountId: this.provider.account_id, - data: { - name: inboxName, - channel: data as any, - }, - }); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } else { - this.logger.verbose('find inbox in chatwoot'); - const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName); - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - inboxId = inbox.id; - } - - this.logger.verbose('find contact in chatwoot and create if not exists'); - const contact = - (await this.findContact(instance, '123456')) || - ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact.id || contact.payload.contact.id; - - if (qrcode) { - this.logger.verbose('create conversation in chatwoot'); - const data = { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }; - - if (this.provider.conversation_pending) { - data['status'] = 'pending'; - } - - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('create message for init instance in chatwoot'); - - let contentMsg = '/init'; - - if (number) { - contentMsg = `/init:${number}`; - } - - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: contentMsg, - message_type: 'outgoing', - }, - }); - - if (!message) { - this.logger.warn('conversation not found'); - return null; - } - } - - this.logger.verbose('instance chatwoot initialized'); - return true; + let data: any = {}; + if (!isGroup) { + this.logger.verbose('create contact in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + phone_number: `+${phoneNumber}`, + avatar_url: avatar_url, + }; + } else { + this.logger.verbose('create contact group in chatwoot'); + data = { + inbox_id: inboxId, + name: name || phoneNumber, + identifier: phoneNumber, + avatar_url: avatar_url, + }; } - public async createContact( - instance: InstanceDto, - phoneNumber: string, - inboxId: number, - isGroup: boolean, - name?: string, - avatar_url?: string, - ) { - this.logger.verbose('create contact to instance: ' + instance.instanceName); + this.logger.verbose('create contact in chatwoot'); + const contact = await client.contacts.create({ + accountId: this.provider.account_id, + data, + }); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let data: any = {}; - if (!isGroup) { - this.logger.verbose('create contact in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - phone_number: `+${phoneNumber}`, - avatar_url: avatar_url, - }; - } else { - this.logger.verbose('create contact group in chatwoot'); - data = { - inbox_id: inboxId, - name: name || phoneNumber, - identifier: phoneNumber, - avatar_url: avatar_url, - }; - } - - this.logger.verbose('create contact in chatwoot'); - const contact = await client.contacts.create({ - accountId: this.provider.account_id, - data, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - this.logger.verbose('contact created'); - return contact; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async updateContact(instance: InstanceDto, id: number, data: any) { - this.logger.verbose('update contact to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + this.logger.verbose('contact created'); + return contact; + } - if (!client) { - this.logger.warn('client not found'); - return null; - } + public async updateContact(instance: InstanceDto, id: number, data: any) { + this.logger.verbose('update contact to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); - if (!id) { - this.logger.warn('id is required'); - return null; - } - - this.logger.verbose('update contact in chatwoot'); - const contact = await client.contacts.update({ - accountId: this.provider.account_id, - id, - data, - }); - - this.logger.verbose('contact updated'); - return contact; + if (!client) { + this.logger.warn('client not found'); + return null; } - public async findContact(instance: InstanceDto, phoneNumber: string) { - this.logger.verbose('find contact to instance: ' + instance.instanceName); - - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - let query: any; - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('format phone number'); - query = `+${phoneNumber}`; - } else { - this.logger.verbose('format group id'); - query = phoneNumber; - } - - this.logger.verbose('find contact in chatwoot'); - const contact: any = await client.contacts.search({ - accountId: this.provider.account_id, - q: query, - }); - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - if (!phoneNumber.includes('@g.us')) { - this.logger.verbose('return contact'); - return contact.payload.find((contact) => contact.phone_number === query); - } else { - this.logger.verbose('return group'); - return contact.payload.find((contact) => contact.identifier === query); - } + if (!id) { + this.logger.warn('id is required'); + return null; } - public async createConversation(instance: InstanceDto, body: any) { - this.logger.verbose('create conversation to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); + this.logger.verbose('update contact in chatwoot'); + const contact = await client.contacts.update({ + accountId: this.provider.account_id, + id, + data, + }); - if (!client) { - this.logger.warn('client not found'); - return null; - } + this.logger.verbose('contact updated'); + return contact; + } - const isGroup = body.key.remoteJid.includes('@g.us'); + public async findContact(instance: InstanceDto, phoneNumber: string) { + this.logger.verbose('find contact to instance: ' + instance.instanceName); - this.logger.verbose('is group: ' + isGroup); + const client = await this.clientCw(instance); - const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - - this.logger.verbose('chat id: ' + chatId); - - let nameContact: string; - - nameContact = !body.key.fromMe ? body.pushName : chatId; - - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); - - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } - - if (isGroup) { - this.logger.verbose('get group name'); - const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); - - nameContact = `${group.subject} (GROUP)`; - - this.logger.verbose('find or create participant in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( - body.key.participant.split('@')[0], - ); - - const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); - - if (findParticipant) { - if (!findParticipant.name || findParticipant.name === chatId) { - await this.updateContact(instance, findParticipant.id, { - name: body.pushName, - avatar_url: picture_url.profilePictureUrl || null, - }); - } - } else { - await this.createContact( - instance, - body.key.participant.split('@')[0], - filterInbox.id, - false, - body.pushName, - picture_url.profilePictureUrl || null, - ); - } - } - - this.logger.verbose('find or create contact in chatwoot'); - - const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); - - const findContact = await this.findContact(instance, chatId); - - let contact: any; - if (body.key.fromMe) { - if (findContact) { - contact = findContact; - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } else { - if (findContact) { - if (!findContact.name || findContact.name === chatId) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); - } else { - contact = findContact; - } - } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); - } - } - - if (!contact) { - this.logger.warn('contact not found'); - return null; - } - - const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; - - if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { - this.logger.verbose('update contact name in chatwoot'); - await this.updateContact(instance, contactId, { - name: nameContact, - }); - } - - this.logger.verbose('get contact conversations in chatwoot'); - const contactConversations = (await client.contacts.listConversations({ - accountId: this.provider.account_id, - id: contactId, - })) as any; - - if (contactConversations) { - let conversation: any; - if (this.provider.reopen_conversation) { - conversation = contactConversations.payload.find( - (conversation) => conversation.inbox_id == filterInbox.id, - ); - } else { - conversation = contactConversations.payload.find( - (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, - ); - } - this.logger.verbose('return conversation if exists'); - - if (conversation) { - this.logger.verbose('conversation found'); - return conversation.id; - } - } - - this.logger.verbose('create conversation in chatwoot'); - const data = { - contact_id: contactId.toString(), - inbox_id: filterInbox.id.toString(), - }; - - if (this.provider.conversation_pending) { - data['status'] = 'pending'; - } - - const conversation = await client.conversations.create({ - accountId: this.provider.account_id, - data, - }); - - if (!conversation) { - this.logger.warn('conversation not found'); - return null; - } - - this.logger.verbose('conversation created'); - return conversation.id; - } catch (error) { - this.logger.error(error); - } + if (!client) { + this.logger.warn('client not found'); + return null; } - public async getInbox(instance: InstanceDto) { - this.logger.verbose('get inbox to instance: ' + instance.instanceName); + let query: any; - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('find inboxes in chatwoot'); - const inbox = (await client.inboxes.list({ - accountId: this.provider.account_id, - })) as any; - - if (!inbox) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); - - if (!findByName) { - this.logger.warn('inbox not found'); - return null; - } - - this.logger.verbose('return inbox'); - return findByName; + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('format phone number'); + query = `+${phoneNumber}`; + } else { + this.logger.verbose('format group id'); + query = phoneNumber; } - public async createMessage( - instance: InstanceDto, - conversationId: number, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - privateMessage?: boolean, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create message to instance: ' + instance.instanceName); + this.logger.verbose('find contact in chatwoot'); + const contact: any = await client.contacts.search({ + accountId: this.provider.account_id, + q: query, + }); - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversationId, - data: { - content: content, - message_type: messageType, - attachments: attachments, - private: privateMessage || false, - }, - }); - - if (!message) { - this.logger.warn('message not found'); - return null; - } - - this.logger.verbose('message created'); - - return message; + if (!contact) { + this.logger.warn('contact not found'); + return null; } - public async createBotMessage( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - attachments?: { - content: unknown; - encoding: string; - filename: string; - }[], - ) { - this.logger.verbose('create bot message to instance: ' + instance.instanceName); + if (!phoneNumber.includes('@g.us')) { + this.logger.verbose('return contact'); + return contact.payload.find((contact) => contact.phone_number === query); + } else { + this.logger.verbose('return group'); + return contact.payload.find((contact) => contact.identifier === query); + } + } - const client = await this.clientCw(instance); + public async createConversation(instance: InstanceDto, body: any) { + this.logger.verbose('create conversation to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); - if (!client) { - this.logger.warn('client not found'); - return null; - } + if (!client) { + this.logger.warn('client not found'); + return null; + } - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); + const isGroup = body.key.remoteJid.includes('@g.us'); - if (!contact) { - this.logger.warn('contact not found'); - return null; - } + this.logger.verbose('is group: ' + isGroup); - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); + const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0]; - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; - } + this.logger.verbose('chat id: ' + chatId); - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); + let nameContact: string; - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } + nameContact = !body.key.fromMe ? body.pushName : chatId; - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + if (isGroup) { + this.logger.verbose('get group name'); + const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); + + nameContact = `${group.subject} (GROUP)`; + + this.logger.verbose('find or create participant in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( + body.key.participant.split('@')[0], ); - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } + const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); - this.logger.verbose('create message in chatwoot'); - const message = await client.messages.create({ - accountId: this.provider.account_id, - conversationId: conversation.id, - data: { - content: content, - message_type: messageType, - attachments: attachments, - }, + if (findParticipant) { + if (!findParticipant.name || findParticipant.name === chatId) { + await this.updateContact(instance, findParticipant.id, { + name: body.pushName, + avatar_url: picture_url.profilePictureUrl || null, + }); + } + } else { + await this.createContact( + instance, + body.key.participant.split('@')[0], + filterInbox.id, + false, + body.pushName, + picture_url.profilePictureUrl || null, + ); + } + } + + this.logger.verbose('find or create contact in chatwoot'); + + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); + + const findContact = await this.findContact(instance, chatId); + + let contact: any; + if (body.key.fromMe) { + if (findContact) { + contact = findContact; + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } else { + if (findContact) { + if (!findContact.name || findContact.name === chatId) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = findContact; + } + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } + } + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; + + if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { + this.logger.verbose('update contact name in chatwoot'); + await this.updateContact(instance, contactId, { + name: nameContact, }); + } - if (!message) { - this.logger.warn('message not found'); - return null; + this.logger.verbose('get contact conversations in chatwoot'); + const contactConversations = (await client.contacts.listConversations({ + accountId: this.provider.account_id, + id: contactId, + })) as any; + + if (contactConversations) { + let conversation: any; + if (this.provider.reopen_conversation) { + conversation = contactConversations.payload.find((conversation) => conversation.inbox_id == filterInbox.id); + } else { + conversation = contactConversations.payload.find( + (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, + ); } + this.logger.verbose('return conversation if exists'); - this.logger.verbose('bot message created'); + if (conversation) { + this.logger.verbose('conversation found'); + return conversation.id; + } + } - return message; + this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: filterInbox.id.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + const conversation = await client.conversations.create({ + accountId: this.provider.account_id, + data, + }); + + if (!conversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('conversation created'); + return conversation.id; + } catch (error) { + this.logger.error(error); + } + } + + public async getInbox(instance: InstanceDto) { + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; } - private async sendData( - conversationId: number, - file: string, - messageType: 'incoming' | 'outgoing' | undefined, - content?: string, - ) { - this.logger.verbose('send data to chatwoot'); + this.logger.verbose('find inboxes in chatwoot'); + const inbox = (await client.inboxes.list({ + accountId: this.provider.account_id, + })) as any; - const data = new FormData(); + if (!inbox) { + this.logger.warn('inbox not found'); + return null; + } - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } + this.logger.verbose('find inbox by name'); + const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); + if (!findByName) { + this.logger.warn('inbox not found'); + return null; + } - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); + this.logger.verbose('return inbox'); + return findByName; + } - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, - headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), - }, - data: data, + public async createMessage( + instance: InstanceDto, + conversationId: number, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + privateMessage?: boolean, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversationId, + data: { + content: content, + message_type: messageType, + attachments: attachments, + private: privateMessage || false, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('message created'); + + return message; + } + + public async createBotMessage( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + attachments?: { + content: unknown; + encoding: string; + filename: string; + }[], + ) { + this.logger.verbose('create bot message to instance: ' + instance.instanceName); + + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('create message in chatwoot'); + const message = await client.messages.create({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + content: content, + message_type: messageType, + attachments: attachments, + }, + }); + + if (!message) { + this.logger.warn('message not found'); + return null; + } + + this.logger.verbose('bot message created'); + + return message; + } + + private async sendData( + conversationId: number, + file: string, + messageType: 'incoming' | 'outgoing' | undefined, + content?: string, + ) { + this.logger.verbose('send data to chatwoot'); + + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversationId}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + unlinkSync(file); + } + } + + public async createBotQr( + instance: InstanceDto, + content: string, + messageType: 'incoming' | 'outgoing' | undefined, + file?: string, + ) { + this.logger.verbose('create bot qr to instance: ' + instance.instanceName); + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('find contact in chatwoot'); + const contact = await this.findContact(instance, '123456'); + + if (!contact) { + this.logger.warn('contact not found'); + return null; + } + + this.logger.verbose('get inbox to instance: ' + instance.instanceName); + const filterInbox = await this.getInbox(instance); + + if (!filterInbox) { + this.logger.warn('inbox not found'); + return null; + } + + this.logger.verbose('find conversation in chatwoot'); + const findConversation = await client.conversations.list({ + accountId: this.provider.account_id, + inboxId: filterInbox.id, + }); + + if (!findConversation) { + this.logger.warn('conversation not found'); + return null; + } + + this.logger.verbose('find conversation by contact id'); + const conversation = findConversation.data.payload.find( + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + ); + + if (!conversation) { + this.logger.warn('conversation not found'); + return; + } + + this.logger.verbose('send data to chatwoot'); + const data = new FormData(); + + if (content) { + this.logger.verbose('content found'); + data.append('content', content); + } + + this.logger.verbose('message type: ' + messageType); + data.append('message_type', messageType); + + if (file) { + this.logger.verbose('temp file found'); + data.append('attachments[]', createReadStream(file)); + } + + this.logger.verbose('get client to instance: ' + this.provider.instanceName); + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, + headers: { + api_access_token: this.provider.token, + ...data.getHeaders(), + }, + data: data, + }; + + this.logger.verbose('send data to chatwoot'); + try { + const { data } = await axios.request(config); + + this.logger.verbose('remove temp file'); + unlinkSync(file); + + this.logger.verbose('data sent'); + return data; + } catch (error) { + this.logger.error(error); + } + } + + public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { + this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); + + try { + this.logger.verbose('get media type'); + const parts = media.split('/'); + + const fileName = decodeURIComponent(parts[parts.length - 1]); + this.logger.verbose('file name: ' + fileName); + + const mimeType = mimeTypes.lookup(fileName).toString(); + this.logger.verbose('mime type: ' + mimeType); + + let type = 'document'; + + switch (mimeType.split('/')[0]) { + case 'image': + type = 'image'; + break; + case 'video': + type = 'video'; + break; + case 'audio': + type = 'audio'; + break; + default: + type = 'document'; + break; + } + + this.logger.verbose('type: ' + type); + + if (type === 'audio') { + this.logger.verbose('send audio to instance: ' + waInstance.instanceName); + const data: SendAudioDto = { + number: number, + audioMessage: { + audio: media, + }, + options: { + delay: 1200, + presence: 'recording', + }, }; - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); + await waInstance?.audioWhatsapp(data); - this.logger.verbose('remove temp file'); - unlinkSync(file); + this.logger.verbose('audio sent'); + return; + } - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); - unlinkSync(file); - } + this.logger.verbose('send media to instance: ' + waInstance.instanceName); + const data: SendMediaDto = { + number: number, + mediaMessage: { + mediatype: type as any, + fileName: fileName, + media: media, + }, + options: { + delay: 1200, + presence: 'composing', + }, + }; + + if (caption) { + this.logger.verbose('caption found'); + data.mediaMessage.caption = caption; + } + + await waInstance?.mediaMessage(data); + + this.logger.verbose('media sent'); + return; + } catch (error) { + this.logger.error(error); } + } - public async createBotQr( - instance: InstanceDto, - content: string, - messageType: 'incoming' | 'outgoing' | undefined, - file?: string, - ) { - this.logger.verbose('create bot qr to instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + public async receiveWebhook(instance: InstanceDto, body: any) { + try { + this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); + const client = await this.clientCw(instance); - if (!client) { - this.logger.warn('client not found'); - return null; + if (!client) { + this.logger.warn('client not found'); + return null; + } + + this.logger.verbose('check if is bot'); + if (!body?.conversation || body.private) return { message: 'bot' }; + + this.logger.verbose('check if is group'); + const chatId = + body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; + const messageReceived = body.content; + const senderName = body?.sender?.name; + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (chatId === '123456' && body.message_type === 'outgoing') { + this.logger.verbose('check if is command'); + + const command = messageReceived.replace('/', ''); + + if (command.includes('init') || command.includes('iniciar')) { + this.logger.verbose('command init found'); + const state = waInstance?.connectionStatus?.state; + + if (state !== 'open') { + this.logger.verbose('connect to whatsapp'); + const number = command.split(':')[1]; + await waInstance.connectToWhatsapp(number); + } else { + this.logger.verbose('whatsapp already connected'); + await this.createBotMessage(instance, `🚨 ${body.inbox.name} instance is connected.`, 'incoming'); + } } - this.logger.verbose('find contact in chatwoot'); - const contact = await this.findContact(instance, '123456'); + if (command === 'status') { + this.logger.verbose('command status found'); - if (!contact) { - this.logger.warn('contact not found'); - return null; + const state = waInstance?.connectionStatus?.state; + + if (!state) { + this.logger.verbose('state not found'); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); + } + + if (state) { + this.logger.verbose('state: ' + state + ' found'); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance status: *${state}*`, 'incoming'); + } } - this.logger.verbose('get inbox to instance: ' + instance.instanceName); - const filterInbox = await this.getInbox(instance); + if (command === 'disconnect' || command === 'desconectar') { + this.logger.verbose('command disconnect found'); - if (!filterInbox) { - this.logger.warn('inbox not found'); - return null; + const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgLogout, 'incoming'); + + this.logger.verbose('disconnect to whatsapp'); + await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); + await waInstance?.client?.ws?.close(); } - this.logger.verbose('find conversation in chatwoot'); - const findConversation = await client.conversations.list({ - accountId: this.provider.account_id, - inboxId: filterInbox.id, - }); + if (command.includes('new_instance')) { + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - if (!findConversation) { - this.logger.warn('conversation not found'); - return null; - } + const data = { + instanceName: command.split(':')[1], + qrcode: true, + chatwoot_account_id: this.provider.account_id, + chatwoot_token: this.provider.token, + chatwoot_url: this.provider.url, + chatwoot_sign_msg: this.provider.sign_msg, + }; - this.logger.verbose('find conversation by contact id'); - const conversation = findConversation.data.payload.find( - (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', - ); + if (command.split(':')[2]) { + data['number'] = command.split(':')[2]; + } - if (!conversation) { - this.logger.warn('conversation not found'); - return; - } - - this.logger.verbose('send data to chatwoot'); - const data = new FormData(); - - if (content) { - this.logger.verbose('content found'); - data.append('content', content); - } - - this.logger.verbose('message type: ' + messageType); - data.append('message_type', messageType); - - if (file) { - this.logger.verbose('temp file found'); - data.append('attachments[]', createReadStream(file)); - } - - this.logger.verbose('get client to instance: ' + this.provider.instanceName); - const config = { + const config = { method: 'post', maxBodyLength: Infinity, - url: `${this.provider.url}/api/v1/accounts/${this.provider.account_id}/conversations/${conversation.id}/messages`, + url: `${urlServer}/instance/create`, headers: { - api_access_token: this.provider.token, - ...data.getHeaders(), + 'Content-Type': 'application/json', + apikey: apiKey, }, data: data, - }; + }; - this.logger.verbose('send data to chatwoot'); - try { - const { data } = await axios.request(config); - - this.logger.verbose('remove temp file'); - unlinkSync(file); - - this.logger.verbose('data sent'); - return data; - } catch (error) { - this.logger.error(error); + await axios.request(config); } - } + } - public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { - this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); + if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { + this.logger.verbose('check if is group'); - try { - this.logger.verbose('get media type'); - const parts = media.split('/'); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + this.logger.verbose('cache file path: ' + this.messageCacheFile); - const fileName = decodeURIComponent(parts[parts.length - 1]); - this.logger.verbose('file name: ' + fileName); + this.messageCache = this.loadMessageCache(); + this.logger.verbose('cache file loaded'); + this.logger.verbose(this.messageCache); - const mimeType = mimeTypes.lookup(fileName).toString(); - this.logger.verbose('mime type: ' + mimeType); + this.logger.verbose('check if message is cached'); + if (this.messageCache.has(body.id.toString())) { + this.logger.verbose('message is cached'); + return { message: 'bot' }; + } - let type = 'document'; + this.logger.verbose('clear cache'); + this.clearMessageCache(); - switch (mimeType.split('/')[0]) { - case 'image': - type = 'image'; - break; - case 'video': - type = 'video'; - break; - case 'audio': - type = 'audio'; - break; - default: - type = 'document'; - break; + this.logger.verbose('Format message to send'); + let formatText: string; + if (senderName === null || senderName === undefined) { + formatText = messageReceived; + } else { + formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; + } + + for (const message of body.conversation.messages) { + this.logger.verbose('check if message is media'); + if (message.attachments && message.attachments.length > 0) { + this.logger.verbose('message is media'); + for (const attachment of message.attachments) { + this.logger.verbose('send media to whatsapp'); + if (!messageReceived) { + this.logger.verbose('message do not have text'); + formatText = null; + } + + await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); } + } else { + this.logger.verbose('message is text'); - this.logger.verbose('type: ' + type); - - if (type === 'audio') { - this.logger.verbose('send audio to instance: ' + waInstance.instanceName); - const data: SendAudioDto = { - number: number, - audioMessage: { - audio: media, - }, - options: { - delay: 1200, - presence: 'recording', - }, - }; - - await waInstance?.audioWhatsapp(data); - - this.logger.verbose('audio sent'); - return; - } - - this.logger.verbose('send media to instance: ' + waInstance.instanceName); - const data: SendMediaDto = { - number: number, - mediaMessage: { - mediatype: type as any, - fileName: fileName, - media: media, - }, - options: { - delay: 1200, - presence: 'composing', - }, + this.logger.verbose('send text to whatsapp'); + const data: SendTextDto = { + number: chatId, + textMessage: { + text: formatText, + }, + options: { + delay: 1200, + presence: 'composing', + }, }; - if (caption) { - this.logger.verbose('caption found'); - data.mediaMessage.caption = caption; - } - - await waInstance?.mediaMessage(data); - - this.logger.verbose('media sent'); - return; - } catch (error) { - this.logger.error(error); + await waInstance?.textMessage(data); + } } - } + } - public async receiveWebhook(instance: InstanceDto, body: any) { - try { - this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); - const client = await this.clientCw(instance); + if (body.message_type === 'template' && body.event === 'message_created') { + this.logger.verbose('check if is template'); - if (!client) { - this.logger.warn('client not found'); - return null; - } - - this.logger.verbose('check if is bot'); - if (!body?.conversation || body.private) return { message: 'bot' }; - - this.logger.verbose('check if is group'); - const chatId = - body.conversation.meta.sender?.phone_number?.replace('+', '') || - body.conversation.meta.sender?.identifier; - const messageReceived = body.content; - const senderName = body?.sender?.name; - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (chatId === '123456' && body.message_type === 'outgoing') { - this.logger.verbose('check if is command'); - - const command = messageReceived.replace('/', ''); - - if (command.includes('init') || command.includes('iniciar')) { - this.logger.verbose('command init found'); - const state = waInstance?.connectionStatus?.state; - - if (state !== 'open') { - this.logger.verbose('connect to whatsapp'); - const number = command.split(':')[1]; - await waInstance.connectToWhatsapp(number); - } else { - this.logger.verbose('whatsapp already connected'); - await this.createBotMessage( - instance, - `🚨 ${body.inbox.name} instance is connected.`, - 'incoming', - ); - } - } - - if (command === 'status') { - this.logger.verbose('command status found'); - - const state = waInstance?.connectionStatus?.state; - - if (!state) { - this.logger.verbose('state not found'); - await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); - } - - if (state) { - this.logger.verbose('state: ' + state + ' found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance status: *${state}*`, - 'incoming', - ); - } - } - - if (command === 'disconnect' || command === 'desconectar') { - this.logger.verbose('command disconnect found'); - - const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgLogout, 'incoming'); - - this.logger.verbose('disconnect to whatsapp'); - await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); - await waInstance?.client?.ws?.close(); - } - - if (command.includes('new_instance')) { - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const data = { - instanceName: command.split(':')[1], - qrcode: true, - chatwoot_account_id: this.provider.account_id, - chatwoot_token: this.provider.token, - chatwoot_url: this.provider.url, - chatwoot_sign_msg: this.provider.sign_msg, - }; - - if (command.split(':')[2]) { - data['number'] = command.split(':')[2]; - } - - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: data, - }; - - await axios.request(config); - } - } - - if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { - this.logger.verbose('check if is group'); - - this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); - this.logger.verbose('cache file path: ' + this.messageCacheFile); - - this.messageCache = this.loadMessageCache(); - this.logger.verbose('cache file loaded'); - this.logger.verbose(this.messageCache); - - this.logger.verbose('check if message is cached'); - if (this.messageCache.has(body.id.toString())) { - this.logger.verbose('message is cached'); - return { message: 'bot' }; - } - - this.logger.verbose('clear cache'); - this.clearMessageCache(); - - this.logger.verbose('Format message to send'); - let formatText: string; - if (senderName === null || senderName === undefined) { - formatText = messageReceived; - } else { - formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; - } - - for (const message of body.conversation.messages) { - this.logger.verbose('check if message is media'); - if (message.attachments && message.attachments.length > 0) { - this.logger.verbose('message is media'); - for (const attachment of message.attachments) { - this.logger.verbose('send media to whatsapp'); - if (!messageReceived) { - this.logger.verbose('message do not have text'); - formatText = null; - } - - await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); - } - } else { - this.logger.verbose('message is text'); - - this.logger.verbose('send text to whatsapp'); - const data: SendTextDto = { - number: chatId, - textMessage: { - text: formatText, - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - await waInstance?.textMessage(data); - } - } - } - - if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is template'); - - const data: SendTextDto = { - number: chatId, - textMessage: { - text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), - }, - options: { - delay: 1200, - presence: 'composing', - }, - }; - - this.logger.verbose('send text to whatsapp'); - - await waInstance?.textMessage(data); - } - - return { message: 'bot' }; - } catch (error) { - this.logger.error(error); - - return { message: 'bot' }; - } - } - - private isMediaMessage(message: any) { - this.logger.verbose('check if is media message'); - const media = [ - 'imageMessage', - 'documentMessage', - 'documentWithCaptionMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', - ]; - - const messageKeys = Object.keys(message); - - const result = messageKeys.some((key) => media.includes(key)); - - this.logger.verbose('is media message: ' + result); - return result; - } - - private getTypeMessage(msg: any) { - this.logger.verbose('get type message'); - - const types = { - conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, - extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: undefined, - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage, - liveLocationMessage: msg.liveLocationMessage, + const data: SendTextDto = { + number: chatId, + textMessage: { + text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), + }, + options: { + delay: 1200, + presence: 'composing', + }, }; - this.logger.verbose('type message: ' + types); + this.logger.verbose('send text to whatsapp'); - return types; + await waInstance?.textMessage(data); + } + + return { message: 'bot' }; + } catch (error) { + this.logger.error(error); + + return { message: 'bot' }; } + } - private getMessageContent(types: any) { - this.logger.verbose('get message content'); - const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + private isMediaMessage(message: any) { + this.logger.verbose('check if is media message'); + const media = [ + 'imageMessage', + 'documentMessage', + 'documentWithCaptionMessage', + 'audioMessage', + 'videoMessage', + 'stickerMessage', + ]; - const result = typeKey ? types[typeKey] : undefined; + const messageKeys = Object.keys(message); - if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { - const latitude = result.degreesLatitude; - const longitude = result.degreesLongitude; + const result = messageKeys.some((key) => media.includes(key)); - const formattedLocation = `**Location:** + this.logger.verbose('is media message: ' + result); + return result; + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + imageMessage: msg.imageMessage?.caption, + videoMessage: msg.videoMessage?.caption, + extendedTextMessage: msg.extendedTextMessage?.text, + messageContextInfo: msg.messageContextInfo?.stanzaId, + stickerMessage: undefined, + documentMessage: msg.documentMessage?.caption, + documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { + const latitude = result.degreesLatitude; + const longitude = result.degreesLongitude; + + const formattedLocation = `**Location:** **latitude:** ${latitude} **longitude:** ${longitude} https://www.google.com/maps/search/?api=1&query=${latitude},${longitude} `; - this.logger.verbose('message content: ' + formattedLocation); + this.logger.verbose('message content: ' + formattedLocation); - return formattedLocation; + return formattedLocation; + } + + if (typeKey === 'contactMessage') { + const vCardData = result.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; } + }); - if (typeKey === 'contactMessage') { - const vCardData = result.split('\n'); - const contactInfo = {}; - - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); - - let formattedContact = `**Contact:** + let formattedContact = `**Contact:** **name:** ${contactInfo['FN']}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); - - this.logger.verbose('message content: ' + formattedContact); - return formattedContact; + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; } + }); - if (typeKey === 'contactsArrayMessage') { - const formattedContacts = result.contacts.map((contact) => { - const vCardData = contact.vcard.split('\n'); - const contactInfo = {}; + this.logger.verbose('message content: ' + formattedContact); + return formattedContact; + } - vCardData.forEach((line) => { - const [key, value] = line.split(':'); - if (key && value) { - contactInfo[key] = value; - } - }); + if (typeKey === 'contactsArrayMessage') { + const formattedContacts = result.contacts.map((contact) => { + const vCardData = contact.vcard.split('\n'); + const contactInfo = {}; - let formattedContact = `**Contact:** + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + let formattedContact = `**Contact:** **name:** ${contact.displayName}`; - let numberCount = 1; - Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL')) { - const phoneNumber = contactInfo[key]; - formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; - numberCount++; - } - }); + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); - return formattedContact; - }); + return formattedContact; + }); - const formattedContactsArray = formattedContacts.join('\n\n'); + const formattedContactsArray = formattedContacts.join('\n\n'); - this.logger.verbose('formatted contacts: ' + formattedContactsArray); + this.logger.verbose('formatted contacts: ' + formattedContactsArray); - return formattedContactsArray; - } - - this.logger.verbose('message content: ' + result); - - return result; + return formattedContactsArray; } - private getConversationMessage(msg: any) { + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { + this.logger.verbose('get conversation message'); + + const types = this.getTypeMessage(msg); + + const messageContent = this.getMessageContent(types); + + this.logger.verbose('conversation message: ' + messageContent); + + return messageContent; + } + + public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { + this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); + try { + const client = await this.clientCw(instance); + + if (!client) { + this.logger.warn('client not found'); + return null; + } + + const waInstance = this.waMonitor.waInstances[instance.instanceName]; + + if (!waInstance) { + this.logger.warn('wa instance not found'); + return null; + } + + if (event === 'messages.upsert') { + this.logger.verbose('event messages.upsert'); + + if (body.key.remoteJid === 'status@broadcast') { + this.logger.verbose('status broadcast found'); + return; + } + this.logger.verbose('get conversation message'); + const bodyMessage = await this.getConversationMessage(body.message); - const types = this.getTypeMessage(msg); + const isMedia = this.isMediaMessage(body.message); - const messageContent = this.getMessageContent(types); - - this.logger.verbose('conversation message: ' + messageContent); - - return messageContent; - } - - public async eventWhatsapp(event: string, instance: InstanceDto, body: any) { - this.logger.verbose('event whatsapp to instance: ' + instance.instanceName); - try { - const client = await this.clientCw(instance); - - if (!client) { - this.logger.warn('client not found'); - return null; - } - - const waInstance = this.waMonitor.waInstances[instance.instanceName]; - - if (!waInstance) { - this.logger.warn('wa instance not found'); - return null; - } - - if (event === 'messages.upsert') { - this.logger.verbose('event messages.upsert'); - - if (body.key.remoteJid === 'status@broadcast') { - this.logger.verbose('status broadcast found'); - return; - } - - this.logger.verbose('get conversation message'); - const bodyMessage = await this.getConversationMessage(body.message); - - const isMedia = this.isMediaMessage(body.message); - - if (!bodyMessage && !isMedia) { - this.logger.warn('no body message found'); - return; - } - - this.logger.verbose('get conversation in chatwoot'); - const getConversion = await this.createConversation(instance, body); - - if (!getConversion) { - this.logger.warn('conversation not found'); - return; - } - - const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; - - this.logger.verbose('message type: ' + messageType); - - this.logger.verbose('is media: ' + isMedia); - - this.logger.verbose('check if is media'); - if (isMedia) { - this.logger.verbose('message is media'); - - this.logger.verbose('get base64 from media message'); - const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ - message: { - ...body, - }, - }); - - const random = Math.random().toString(36).substring(7); - const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; - - const fileData = Buffer.from(downloadBase64.base64, 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; - - this.logger.verbose('temp file name: ' + nameFile); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData(getConversion, fileName, messageType, content); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - this.logger.verbose('check if is group'); - if (body.key.remoteJid.includes('@g.us')) { - this.logger.verbose('message is group'); - const participantName = body.pushName; - - let content: string; - - if (!body.key.fromMe) { - this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; - } else { - this.logger.verbose('message is from me'); - content = `${bodyMessage}`; - } - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage(instance, getConversion, content, messageType); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } else { - this.logger.verbose('message is not group'); - - this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); - - if (!send) { - this.logger.warn('message not sent'); - return; - } - - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); - - this.messageCache = this.loadMessageCache(); - - this.messageCache.add(send.id.toString()); - - this.logger.verbose('save message cache'); - this.saveMessageCache(); - - return send; - } - } - - if (event === 'status.instance') { - this.logger.verbose('event status.instance'); - const data = body; - const inbox = await this.getInbox(instance); - - if (!inbox) { - this.logger.warn('inbox not found'); - return; - } - - const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgStatus, 'incoming'); - } - - if (event === 'connection.update') { - this.logger.verbose('event connection.update'); - - if (body.status === 'open') { - const msgConnection = `🚀 Connection successfully established!`; - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgConnection, 'incoming'); - } - } - - if (event === 'qrcode.updated') { - this.logger.verbose('event qrcode.updated'); - if (body.statusCode === 500) { - this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; - - this.logger.verbose('send message to chatwoot'); - return await this.createBotMessage(instance, erroQRcode, 'incoming'); - } else { - this.logger.verbose('qrcode success'); - const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); - - const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; - - this.logger.verbose('temp file name: ' + fileName); - - this.logger.verbose('create temp file'); - writeFileSync(fileName, fileData, 'utf8'); - - this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); - - let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; - - if (body?.qrcode?.pairingCode) { - msgQrCode = - msgQrCode + - `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( - 0, - 4, - )}-${body.qrcode.pairingCode.substring(4, 8)}`; - } - - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgQrCode, 'incoming'); - } - } - } catch (error) { - this.logger.error(error); + if (!bodyMessage && !isMedia) { + this.logger.warn('no body message found'); + return; } - } - public async newInstance(data: any) { - try { - const instanceName = data.instanceName; - const qrcode = true; - const number = data.number; - const accountId = data.accountId; - const chatwootToken = data.token; - const chatwootUrl = data.url; - const signMsg = true; - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + this.logger.verbose('get conversation in chatwoot'); + const getConversion = await this.createConversation(instance, body); - const requestData = { - instanceName, - qrcode, - chatwoot_account_id: accountId, - chatwoot_token: chatwootToken, - chatwoot_url: chatwootUrl, - chatwoot_sign_msg: signMsg, - }; + if (!getConversion) { + this.logger.warn('conversation not found'); + return; + } - if (number) { - requestData['number'] = number; + const messageType = body.key.fromMe ? 'outgoing' : 'incoming'; + + this.logger.verbose('message type: ' + messageType); + + this.logger.verbose('is media: ' + isMedia); + + this.logger.verbose('check if is media'); + if (isMedia) { + this.logger.verbose('message is media'); + + this.logger.verbose('get base64 from media message'); + const downloadBase64 = await waInstance?.getBase64FromMediaMessage({ + message: { + ...body, + }, + }); + + const random = Math.random().toString(36).substring(7); + const nameFile = `${random}.${mimeTypes.extension(downloadBase64.mimetype)}`; + + const fileData = Buffer.from(downloadBase64.base64, 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`; + + this.logger.verbose('temp file name: ' + nameFile); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; } - // eslint-disable-next-line + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, content); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + this.logger.verbose('check if is group'); + if (body.key.remoteJid.includes('@g.us')) { + this.logger.verbose('message is group'); + const participantName = body.pushName; + + let content: string; + + if (!body.key.fromMe) { + this.logger.verbose('message is not from me'); + content = `**${participantName}**\n\n${bodyMessage}`; + } else { + this.logger.verbose('message is from me'); + content = `${bodyMessage}`; + } + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, content, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } else { + this.logger.verbose('message is not group'); + + this.logger.verbose('send data to chatwoot'); + const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); + + if (!send) { + this.logger.warn('message not sent'); + return; + } + + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); + + this.messageCache = this.loadMessageCache(); + + this.messageCache.add(send.id.toString()); + + this.logger.verbose('save message cache'); + this.saveMessageCache(); + + return send; + } + } + + if (event === 'status.instance') { + this.logger.verbose('event status.instance'); + const data = body; + const inbox = await this.getInbox(instance); + + if (!inbox) { + this.logger.warn('inbox not found'); + return; + } + + const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgStatus, 'incoming'); + } + + if (event === 'connection.update') { + this.logger.verbose('event connection.update'); + + if (body.status === 'open') { + const msgConnection = `🚀 Connection successfully established!`; + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgConnection, 'incoming'); + } + } + + if (event === 'qrcode.updated') { + this.logger.verbose('event qrcode.updated'); + if (body.statusCode === 500) { + this.logger.verbose('qrcode error'); + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; + + this.logger.verbose('send message to chatwoot'); + return await this.createBotMessage(instance, erroQRcode, 'incoming'); + } else { + this.logger.verbose('qrcode success'); + const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); + + const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; + + this.logger.verbose('temp file name: ' + fileName); + + this.logger.verbose('create temp file'); + writeFileSync(fileName, fileData, 'utf8'); + + this.logger.verbose('send qrcode to chatwoot'); + await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); + + let msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; + + if (body?.qrcode?.pairingCode) { + msgQrCode = + msgQrCode + + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring(0, 4)}-${body.qrcode.pairingCode.substring( + 4, + 8, + )}`; + } + + this.logger.verbose('send message to chatwoot'); + await this.createBotMessage(instance, msgQrCode, 'incoming'); + } + } + } catch (error) { + this.logger.error(error); + } + } + + public async newInstance(data: any) { + try { + const instanceName = data.instanceName; + const qrcode = true; + const number = data.number; + const accountId = data.accountId; + const chatwootToken = data.token; + const chatwootUrl = data.url; + const signMsg = true; + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + const requestData = { + instanceName, + qrcode, + chatwoot_account_id: accountId, + chatwoot_token: chatwootToken, + chatwoot_url: chatwootUrl, + chatwoot_sign_msg: signMsg, + }; + + if (number) { + requestData['number'] = number; + } + + // eslint-disable-next-line const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: requestData, - }; + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: requestData, + }; - // await axios.request(config); + // await axios.request(config); - return true; - } catch (error) { - this.logger.error(error); - return null; - } + return true; + } catch (error) { + this.logger.error(error); + return null; } + } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 1504366a..50f671d9 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -11,344 +11,344 @@ import { dbserver } from '../../db/db.connect'; import { RedisCache } from '../../db/redis.client'; import { NotFoundException } from '../../exceptions'; import { - AuthModel, - ChatwootModel, - ContactModel, - MessageModel, - MessageUpModel, - SettingsModel, - WebhookModel, + AuthModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + SettingsModel, + WebhookModel, } from '../models'; import { RepositoryBroker } from '../repository/repository.manager'; import { WAStartupService } from './whatsapp.service'; export class WAMonitoringService { - constructor( - private readonly eventEmitter: EventEmitter2, - private readonly configService: ConfigService, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('instance created'); + constructor( + private readonly eventEmitter: EventEmitter2, + private readonly configService: ConfigService, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('instance created'); - this.removeInstance(); - this.noConnection(); - this.delInstanceFiles(); + this.removeInstance(); + this.noConnection(); + this.delInstanceFiles(); - Object.assign(this.db, configService.get('DATABASE')); - Object.assign(this.redis, configService.get('REDIS')); + Object.assign(this.db, configService.get('DATABASE')); + Object.assign(this.redis, configService.get('REDIS')); - this.dbInstance = this.db.ENABLED - ? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances') - : undefined; + this.dbInstance = this.db.ENABLED + ? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances') + : undefined; + } + + private readonly db: Partial = {}; + private readonly redis: Partial = {}; + + private dbInstance: Db; + + private dbStore = dbserver; + + private readonly logger = new Logger(WAMonitoringService.name); + public readonly waInstances: Record = {}; + + public delInstanceTime(instance: string) { + const time = this.configService.get('DEL_INSTANCE'); + if (typeof time === 'number' && time > 0) { + this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`); + + setTimeout(async () => { + if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { + if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { + await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance); + this.waInstances[instance]?.client?.ws?.close(); + this.waInstances[instance]?.client?.end(undefined); + delete this.waInstances[instance]; + } else { + delete this.waInstances[instance]; + this.eventEmitter.emit('remove.instance', instance, 'inner'); + } + } + }, 1000 * 60 * time); + } + } + + public async instanceInfo(instanceName?: string) { + this.logger.verbose('get instance info'); + if (instanceName && !this.waInstances[instanceName]) { + throw new NotFoundException(`Instance "${instanceName}" not found`); } - private readonly db: Partial = {}; - private readonly redis: Partial = {}; + const instances: any[] = []; - private dbInstance: Db; + for await (const [key, value] of Object.entries(this.waInstances)) { + if (value) { + this.logger.verbose('get instance info: ' + key); + let chatwoot: any; - private dbStore = dbserver; + const urlServer = this.configService.get('SERVER').URL; - private readonly logger = new Logger(WAMonitoringService.name); - public readonly waInstances: Record = {}; + const findChatwoot = await this.waInstances[key].findChatwoot(); - public delInstanceTime(instance: string) { - const time = this.configService.get('DEL_INSTANCE'); - if (typeof time === 'number' && time > 0) { - this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`); - - setTimeout(async () => { - if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { - if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { - await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance); - this.waInstances[instance]?.client?.ws?.close(); - this.waInstances[instance]?.client?.end(undefined); - delete this.waInstances[instance]; - } else { - delete this.waInstances[instance]; - this.eventEmitter.emit('remove.instance', instance, 'inner'); - } - } - }, 1000 * 60 * time); + if (findChatwoot && findChatwoot.enabled) { + chatwoot = { + ...findChatwoot, + webhook_url: `${urlServer}/chatwoot/webhook/${key}`, + }; } + + if (value.connectionStatus.state === 'open') { + this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); + + const instanceData = { + instance: { + instanceName: key, + owner: value.wuid, + profileName: (await value.getProfileName()) || 'not loaded', + profilePictureUrl: value.profilePictureUrl, + profileStatus: (await value.getProfileStatus()) || '', + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } else { + this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state); + + const instanceData = { + instance: { + instanceName: key, + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } + } } - public async instanceInfo(instanceName?: string) { - this.logger.verbose('get instance info'); - if (instanceName && !this.waInstances[instanceName]) { - throw new NotFoundException(`Instance "${instanceName}" not found`); - } + this.logger.verbose('return instance info: ' + instances.length); - const instances: any[] = []; + return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; + } - for await (const [key, value] of Object.entries(this.waInstances)) { - if (value) { - this.logger.verbose('get instance info: ' + key); - let chatwoot: any; - - const urlServer = this.configService.get('SERVER').URL; - - const findChatwoot = await this.waInstances[key].findChatwoot(); - - if (findChatwoot && findChatwoot.enabled) { - chatwoot = { - ...findChatwoot, - webhook_url: `${urlServer}/chatwoot/webhook/${key}`, - }; - } - - if (value.connectionStatus.state === 'open') { - this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); - - const instanceData = { - instance: { - instanceName: key, - owner: value.wuid, - profileName: (await value.getProfileName()) || 'not loaded', - profilePictureUrl: value.profilePictureUrl, - profileStatus: (await value.getProfileStatus()) || '', - status: value.connectionStatus.state, - }, - }; - - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; - - instanceData.instance['chatwoot'] = chatwoot; - } - - instances.push(instanceData); - } else { - this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state); - - const instanceData = { - instance: { - instanceName: key, - status: value.connectionStatus.state, - }, - }; - - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; - - instanceData.instance['chatwoot'] = chatwoot; - } - - instances.push(instanceData); - } - } - } - - this.logger.verbose('return instance info: ' + instances.length); - - return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; - } - - private delInstanceFiles() { - this.logger.verbose('cron to delete instance files started'); - setInterval(async () => { - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - const collections = await this.dbInstance.collections(); - collections.forEach(async (collection) => { - const name = collection.namespace.replace(/^[\w-]+./, ''); - await this.dbInstance.collection(name).deleteMany({ - $or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }], - }); - this.logger.verbose('instance files deleted: ' + name); + private delInstanceFiles() { + this.logger.verbose('cron to delete instance files started'); + setInterval(async () => { + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + const collections = await this.dbInstance.collections(); + collections.forEach(async (collection) => { + const name = collection.namespace.replace(/^[\w-]+./, ''); + await this.dbInstance.collection(name).deleteMany({ + $or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }], + }); + this.logger.verbose('instance files deleted: ' + name); + }); + // } else if (this.redis.ENABLED) { + } else { + const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); + for await (const dirent of dir) { + if (dirent.isDirectory()) { + const files = readdirSync(join(INSTANCE_DIR, dirent.name), { + encoding: 'utf-8', + }); + files.forEach(async (file) => { + if (file.match(/^app.state.*/) || file.match(/^session-.*/)) { + rmSync(join(INSTANCE_DIR, dirent.name, file), { + recursive: true, + force: true, }); - // } else if (this.redis.ENABLED) { - } else { - const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); - for await (const dirent of dir) { - if (dirent.isDirectory()) { - const files = readdirSync(join(INSTANCE_DIR, dirent.name), { - encoding: 'utf-8', - }); - files.forEach(async (file) => { - if (file.match(/^app.state.*/) || file.match(/^session-.*/)) { - rmSync(join(INSTANCE_DIR, dirent.name, file), { - recursive: true, - force: true, - }); - } - }); - this.logger.verbose('instance files deleted: ' + dirent.name); - } - } - } - }, 3600 * 1000 * 2); + } + }); + this.logger.verbose('instance files deleted: ' + dirent.name); + } + } + } + }, 3600 * 1000 * 2); + } + + public async cleaningUp(instanceName: string) { + this.logger.verbose('cleaning up instance: ' + instanceName); + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + this.logger.verbose('cleaning up instance in database: ' + instanceName); + await this.repository.dbServer.connect(); + const collections: any[] = await this.dbInstance.collections(); + if (collections.length > 0) { + await this.dbInstance.dropCollection(instanceName); + } + return; } - public async cleaningUp(instanceName: string) { - this.logger.verbose('cleaning up instance: ' + instanceName); - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - this.logger.verbose('cleaning up instance in database: ' + instanceName); - await this.repository.dbServer.connect(); - const collections: any[] = await this.dbInstance.collections(); - if (collections.length > 0) { - await this.dbInstance.dropCollection(instanceName); - } - return; - } - - if (this.redis.ENABLED) { - this.logger.verbose('cleaning up instance in redis: ' + instanceName); - this.cache.reference = instanceName; - await this.cache.delAll(); - return; - } - - this.logger.verbose('cleaning up instance in files: ' + instanceName); - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + if (this.redis.ENABLED) { + this.logger.verbose('cleaning up instance in redis: ' + instanceName); + this.cache.reference = instanceName; + await this.cache.delAll(); + return; } - public async cleaningStoreFiles(instanceName: string) { - if (!this.db.ENABLED) { - this.logger.verbose('cleaning store files instance: ' + instanceName); - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + this.logger.verbose('cleaning up instance in files: ' + instanceName); + rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + } - execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`); + public async cleaningStoreFiles(instanceName: string) { + if (!this.db.ENABLED) { + this.logger.verbose('cleaning store files instance: ' + instanceName); + rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); - execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`); + execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`); - return; + execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); + execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); + execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); + + return; + } + + this.logger.verbose('cleaning store database instance: ' + instanceName); + + await AuthModel.deleteMany({ owner: instanceName }); + await ContactModel.deleteMany({ owner: instanceName }); + await MessageModel.deleteMany({ owner: instanceName }); + await MessageUpModel.deleteMany({ owner: instanceName }); + await AuthModel.deleteMany({ _id: instanceName }); + await WebhookModel.deleteMany({ _id: instanceName }); + await ChatwootModel.deleteMany({ _id: instanceName }); + await SettingsModel.deleteMany({ _id: instanceName }); + + return; + } + + public async loadInstance() { + this.logger.verbose('load instances'); + const set = async (name: string) => { + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); + instance.instanceName = name; + this.logger.verbose('instance loaded: ' + name); + + await instance.connectToWhatsapp(); + this.logger.verbose('connectToWhatsapp: ' + name); + + this.waInstances[name] = instance; + }; + + try { + if (this.redis.ENABLED) { + this.logger.verbose('redis enabled'); + await this.cache.connect(this.redis as Redis); + const keys = await this.cache.instanceKeys(); + if (keys?.length > 0) { + this.logger.verbose('reading instance keys and setting instances'); + keys.forEach(async (k) => await set(k.split(':')[1])); + } else { + this.logger.verbose('no instance keys found'); } - - this.logger.verbose('cleaning store database instance: ' + instanceName); - - await AuthModel.deleteMany({ owner: instanceName }); - await ContactModel.deleteMany({ owner: instanceName }); - await MessageModel.deleteMany({ owner: instanceName }); - await MessageUpModel.deleteMany({ owner: instanceName }); - await AuthModel.deleteMany({ _id: instanceName }); - await WebhookModel.deleteMany({ _id: instanceName }); - await ChatwootModel.deleteMany({ _id: instanceName }); - await SettingsModel.deleteMany({ _id: instanceName }); - return; - } + } - public async loadInstance() { - this.logger.verbose('load instances'); - const set = async (name: string) => { - const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); - instance.instanceName = name; - this.logger.verbose('instance loaded: ' + name); - - await instance.connectToWhatsapp(); - this.logger.verbose('connectToWhatsapp: ' + name); - - this.waInstances[name] = instance; - }; - - try { - if (this.redis.ENABLED) { - this.logger.verbose('redis enabled'); - await this.cache.connect(this.redis as Redis); - const keys = await this.cache.instanceKeys(); - if (keys?.length > 0) { - this.logger.verbose('reading instance keys and setting instances'); - keys.forEach(async (k) => await set(k.split(':')[1])); - } else { - this.logger.verbose('no instance keys found'); - } - return; - } - - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { - this.logger.verbose('database enabled'); - await this.repository.dbServer.connect(); - const collections: any[] = await this.dbInstance.collections(); - if (collections.length > 0) { - this.logger.verbose('reading collections and setting instances'); - collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, ''))); - } else { - this.logger.verbose('no collections found'); - } - return; - } - - this.logger.verbose('store in files enabled'); - const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); - for await (const dirent of dir) { - if (dirent.isDirectory()) { - this.logger.verbose('reading instance files and setting instances'); - const files = readdirSync(join(INSTANCE_DIR, dirent.name), { - encoding: 'utf-8', - }); - if (files.length === 0) { - rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true }); - break; - } - - await set(dirent.name); - } else { - this.logger.verbose('no instance files found'); - } - } - } catch (error) { - this.logger.error(error); + if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + this.logger.verbose('database enabled'); + await this.repository.dbServer.connect(); + const collections: any[] = await this.dbInstance.collections(); + if (collections.length > 0) { + this.logger.verbose('reading collections and setting instances'); + collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, ''))); + } else { + this.logger.verbose('no collections found'); } + return; + } + + this.logger.verbose('store in files enabled'); + const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); + for await (const dirent of dir) { + if (dirent.isDirectory()) { + this.logger.verbose('reading instance files and setting instances'); + const files = readdirSync(join(INSTANCE_DIR, dirent.name), { + encoding: 'utf-8', + }); + if (files.length === 0) { + rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true }); + break; + } + + await set(dirent.name); + } else { + this.logger.verbose('no instance files found'); + } + } + } catch (error) { + this.logger.error(error); } + } - private removeInstance() { - this.eventEmitter.on('remove.instance', async (instanceName: string) => { - this.logger.verbose('remove instance: ' + instanceName); - try { - this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); - this.waInstances[instanceName] = undefined; - } catch (error) { - this.logger.error(error); - } + private removeInstance() { + this.eventEmitter.on('remove.instance', async (instanceName: string) => { + this.logger.verbose('remove instance: ' + instanceName); + try { + this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); + this.waInstances[instanceName] = undefined; + } catch (error) { + this.logger.error(error); + } - try { - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - this.cleaningStoreFiles(instanceName); - } finally { - this.logger.warn(`Instance "${instanceName}" - REMOVED`); - } + try { + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + this.cleaningStoreFiles(instanceName); + } finally { + this.logger.warn(`Instance "${instanceName}" - REMOVED`); + } + }); + this.eventEmitter.on('logout.instance', async (instanceName: string) => { + this.logger.verbose('logout instance: ' + instanceName); + try { + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + } finally { + this.logger.warn(`Instance "${instanceName}" - LOGOUT`); + } + }); + } + + private noConnection() { + this.logger.verbose('checking instances without connection'); + this.eventEmitter.on('no.connection', async (instanceName) => { + try { + this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); + this.waInstances[instanceName] = undefined; + + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); + } catch (error) { + this.logger.error({ + localError: 'noConnection', + warn: 'Error deleting instance from memory.', + error, }); - this.eventEmitter.on('logout.instance', async (instanceName: string) => { - this.logger.verbose('logout instance: ' + instanceName); - try { - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - } finally { - this.logger.warn(`Instance "${instanceName}" - LOGOUT`); - } - }); - } - - private noConnection() { - this.logger.verbose('checking instances without connection'); - this.eventEmitter.on('no.connection', async (instanceName) => { - try { - this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); - this.waInstances[instanceName] = undefined; - - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); - } catch (error) { - this.logger.error({ - localError: 'noConnection', - warn: 'Error deleting instance from memory.', - error, - }); - } finally { - this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`); - } - }); - } + } finally { + this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`); + } + }); + } } diff --git a/src/whatsapp/services/settings.service.ts b/src/whatsapp/services/settings.service.ts index bbd5076f..6815ca40 100644 --- a/src/whatsapp/services/settings.service.ts +++ b/src/whatsapp/services/settings.service.ts @@ -4,29 +4,29 @@ import { SettingsDto } from '../dto/settings.dto'; import { WAMonitoringService } from './monitor.service'; export class SettingsService { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - private readonly logger = new Logger(SettingsService.name); + private readonly logger = new Logger(SettingsService.name); - public create(instance: InstanceDto, data: SettingsDto) { - this.logger.verbose('create settings: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setSettings(data); + public create(instance: InstanceDto, data: SettingsDto) { + this.logger.verbose('create settings: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setSettings(data); - return { settings: { ...instance, settings: data } }; - } - - public async find(instance: InstanceDto): Promise { - try { - this.logger.verbose('find settings: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[instance.instanceName].findSettings(); - - if (Object.keys(result).length === 0) { - throw new Error('Settings not found'); - } - - return result; - } catch (error) { - return { reject_call: false, msg_call: '', groups_ignore: false }; - } + return { settings: { ...instance, settings: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find settings: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findSettings(); + + if (Object.keys(result).length === 0) { + throw new Error('Settings not found'); + } + + return result; + } catch (error) { + return { reject_call: false, msg_call: '', groups_ignore: false }; } + } } diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index 36233f1f..dd0a88cd 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -4,29 +4,29 @@ import { WebhookDto } from '../dto/webhook.dto'; import { WAMonitoringService } from './monitor.service'; export class WebhookService { - constructor(private readonly waMonitor: WAMonitoringService) {} + constructor(private readonly waMonitor: WAMonitoringService) {} - private readonly logger = new Logger(WebhookService.name); + private readonly logger = new Logger(WebhookService.name); - public create(instance: InstanceDto, data: WebhookDto) { - this.logger.verbose('create webhook: ' + instance.instanceName); - this.waMonitor.waInstances[instance.instanceName].setWebhook(data); + public create(instance: InstanceDto, data: WebhookDto) { + this.logger.verbose('create webhook: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setWebhook(data); - return { webhook: { ...instance, webhook: data } }; - } - - public async find(instance: InstanceDto): Promise { - try { - this.logger.verbose('find webhook: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[instance.instanceName].findWebhook(); - - if (Object.keys(result).length === 0) { - throw new Error('Webhook not found'); - } - - return result; - } catch (error) { - return { enabled: false, url: '', events: [], webhook_by_events: false }; - } + return { webhook: { ...instance, webhook: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find webhook: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findWebhook(); + + if (Object.keys(result).length === 0) { + throw new Error('Webhook not found'); + } + + return result; + } catch (error) { + return { enabled: false, url: '', events: [], webhook_by_events: false }; } + } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1678822f..59245103 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,37 +1,37 @@ import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { Boom } from '@hapi/boom'; import makeWASocket, { - AnyMessageContent, - BufferedEventData, - BufferJSON, - CacheStore, - Chat, - ConnectionState, - Contact, - delay, - DisconnectReason, - downloadMediaMessage, - fetchLatestBaileysVersion, - generateWAMessageFromContent, - getAggregateVotesInPollMessage, - getContentType, - getDevice, - GroupMetadata, - isJidGroup, - isJidUser, - makeCacheableSignalKeyStore, - MessageUpsertType, - MiscMessageGenerationOptions, - ParticipantAction, - prepareWAMessageMedia, - proto, - useMultiFileAuthState, - UserFacingSocketConfig, - WABrowserDescription, - WAMediaUpload, - WAMessage, - WAMessageUpdate, - WASocket, + AnyMessageContent, + BufferedEventData, + BufferJSON, + CacheStore, + Chat, + ConnectionState, + Contact, + delay, + DisconnectReason, + downloadMediaMessage, + fetchLatestBaileysVersion, + generateWAMessageFromContent, + getAggregateVotesInPollMessage, + getContentType, + getDevice, + GroupMetadata, + isJidGroup, + isJidUser, + makeCacheableSignalKeyStore, + MessageUpsertType, + MiscMessageGenerationOptions, + ParticipantAction, + prepareWAMessageMedia, + proto, + useMultiFileAuthState, + UserFacingSocketConfig, + WABrowserDescription, + WAMediaUpload, + WAMessage, + WAMessageUpdate, + WASocket, } from '@whiskeysockets/baileys'; import axios from 'axios'; import { exec, execSync } from 'child_process'; @@ -50,16 +50,16 @@ import sharp from 'sharp'; import { v4 } from 'uuid'; import { - Auth, - CleanStoreConf, - ConfigService, - ConfigSessionPhone, - Database, - HttpServer, - Log, - QrCode, - Redis, - Webhook, + Auth, + CleanStoreConf, + ConfigService, + ConfigSessionPhone, + Database, + HttpServer, + Log, + QrCode, + Redis, + Webhook, } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; @@ -69,44 +69,44 @@ import { BadRequestException, InternalServerErrorException, NotFoundException } import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import { - ArchiveChatDto, - DeleteMessage, - getBase64FromMediaMessageDto, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, } from '../dto/chat.dto'; import { - CreateGroupDto, - GetParticipant, - GroupDescriptionDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupSendInvite, - GroupSubjectDto, - GroupToggleEphemeralDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, } from '../dto/group.dto'; import { - ContactMessage, - MediaMessage, - Options, - SendAudioDto, - SendButtonDto, - SendContactDto, - SendListDto, - SendLocationDto, - SendMediaDto, - SendPollDto, - SendReactionDto, - SendStatusDto, - SendStickerDto, - SendTextDto, - StatusMessage, + ContactMessage, + MediaMessage, + Options, + SendAudioDto, + SendButtonDto, + SendContactDto, + SendListDto, + SendLocationDto, + SendMediaDto, + SendPollDto, + SendReactionDto, + SendStatusDto, + SendStickerDto, + SendTextDto, + StatusMessage, } from '../dto/sendMessage.dto'; import { SettingsRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; @@ -123,2804 +123,2791 @@ import { waMonitor } from '../whatsapp.module'; import { ChatwootService } from './chatwoot.service'; export class WAStartupService { - constructor( - private readonly configService: ConfigService, - private readonly eventEmitter: EventEmitter2, - private readonly repository: RepositoryBroker, - private readonly cache: RedisCache, - ) { - this.logger.verbose('WAStartupService initialized'); - this.cleanStore(); - this.instance.qrcode = { count: 0 }; + constructor( + private readonly configService: ConfigService, + private readonly eventEmitter: EventEmitter2, + private readonly repository: RepositoryBroker, + private readonly cache: RedisCache, + ) { + this.logger.verbose('WAStartupService initialized'); + this.cleanStore(); + this.instance.qrcode = { count: 0 }; + } + + private readonly logger = new Logger(WAStartupService.name); + private readonly instance: wa.Instance = {}; + public client: WASocket; + private readonly localWebhook: wa.LocalWebHook = {}; + private readonly localChatwoot: wa.LocalChatwoot = {}; + private readonly localSettings: wa.LocalSettings = {}; + private stateConnection: wa.StateConnection = { state: 'close' }; + public readonly storePath = join(ROOT_DIR, 'store'); + private readonly msgRetryCounterCache: CacheStore = new NodeCache(); + private readonly userDevicesCache: CacheStore = new NodeCache(); + private endSession = false; + private logBaileys = this.configService.get('LOG').BAILEYS; + + private phoneNumber: string; + + private chatwootService = new ChatwootService(waMonitor, this.configService); + + public set instanceName(name: string) { + this.logger.verbose(`Initializing instance '${name}'`); + if (!name) { + this.logger.verbose('Instance name not found, generating random name with uuid'); + this.instance.name = v4(); + return; + } + this.instance.name = name; + this.logger.verbose(`Instance '${this.instance.name}' initialized`); + this.logger.verbose('Sending instance status to webhook'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'created', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'created', + }, + ); + } + } + + public get instanceName() { + this.logger.verbose('Getting instance name'); + return this.instance.name; + } + + public get wuid() { + this.logger.verbose('Getting remoteJid of instance'); + return this.instance.wuid; + } + + public async getProfileName() { + this.logger.verbose('Getting profile name'); + let profileName = this.client.user?.name ?? this.client.user?.verifiedName; + if (!profileName) { + this.logger.verbose('Profile name not found, trying to get from database'); + if (this.configService.get('DATABASE').ENABLED) { + this.logger.verbose('Database enabled, trying to get from database'); + const collection = dbserver + .getClient() + .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(this.instanceName); + const data = await collection.findOne({ _id: 'creds' }); + if (data) { + this.logger.verbose('Profile name found in database'); + const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); + profileName = creds.me?.name || creds.me?.verifiedName; + } + } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { + this.logger.verbose('Profile name found in file'); + const creds = JSON.parse( + readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { + encoding: 'utf-8', + }), + ); + profileName = creds.me?.name || creds.me?.verifiedName; + } } - private readonly logger = new Logger(WAStartupService.name); - private readonly instance: wa.Instance = {}; - public client: WASocket; - private readonly localWebhook: wa.LocalWebHook = {}; - private readonly localChatwoot: wa.LocalChatwoot = {}; - private readonly localSettings: wa.LocalSettings = {}; - private stateConnection: wa.StateConnection = { state: 'close' }; - public readonly storePath = join(ROOT_DIR, 'store'); - private readonly msgRetryCounterCache: CacheStore = new NodeCache(); - private readonly userDevicesCache: CacheStore = new NodeCache(); - private endSession = false; - private logBaileys = this.configService.get('LOG').BAILEYS; + this.logger.verbose(`Profile name: ${profileName}`); + return profileName; + } - private phoneNumber: string; + public async getProfileStatus() { + this.logger.verbose('Getting profile status'); + const status = await this.client.fetchStatus(this.instance.wuid); - private chatwootService = new ChatwootService(waMonitor, this.configService); + this.logger.verbose(`Profile status: ${status.status}`); + return status.status; + } - public set instanceName(name: string) { - this.logger.verbose(`Initializing instance '${name}'`); - if (!name) { - this.logger.verbose('Instance name not found, generating random name with uuid'); - this.instance.name = v4(); - return; + public get profilePictureUrl() { + this.logger.verbose('Getting profile picture url'); + return this.instance.profilePictureUrl; + } + + public get qrCode(): wa.QrCode { + this.logger.verbose('Getting qrcode'); + + return { + pairingCode: this.instance.qrcode?.pairingCode, + code: this.instance.qrcode?.code, + base64: this.instance.qrcode?.base64, + }; + } + + private async loadWebhook() { + this.logger.verbose('Loading webhook'); + const data = await this.repository.webhook.find(this.instanceName); + this.localWebhook.url = data?.url; + this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + + this.localWebhook.enabled = data?.enabled; + this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + + this.localWebhook.events = data?.events; + this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); + + this.localWebhook.webhook_by_events = data?.webhook_by_events; + this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + + this.logger.verbose('Webhook loaded'); + } + + public async setWebhook(data: WebhookRaw) { + this.logger.verbose('Setting webhook'); + await this.repository.webhook.create(data, this.instanceName); + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + Object.assign(this.localWebhook, data); + this.logger.verbose('Webhook set'); + } + + public async findWebhook() { + this.logger.verbose('Finding webhook'); + const data = await this.repository.webhook.find(this.instanceName); + + if (!data) { + this.logger.verbose('Webhook not found'); + throw new NotFoundException('Webhook not found'); + } + + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + return data; + } + + private async loadChatwoot() { + this.logger.verbose('Loading chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + this.localChatwoot.enabled = data?.enabled; + this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + + this.localChatwoot.account_id = data?.account_id; + this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); + + this.localChatwoot.token = data?.token; + this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); + + this.localChatwoot.url = data?.url; + this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); + + this.localChatwoot.name_inbox = data?.name_inbox; + this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); + + this.localChatwoot.sign_msg = data?.sign_msg; + this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + + this.localChatwoot.number = data?.number; + this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); + + this.localChatwoot.reopen_conversation = data?.reopen_conversation; + this.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`); + + this.localChatwoot.conversation_pending = data?.conversation_pending; + this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`); + + this.logger.verbose('Chatwoot loaded'); + } + + public async setChatwoot(data: ChatwootRaw) { + this.logger.verbose('Setting chatwoot'); + await this.repository.chatwoot.create(data, this.instanceName); + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + Object.assign(this.localChatwoot, data); + this.logger.verbose('Chatwoot set'); + } + + public async findChatwoot() { + this.logger.verbose('Finding chatwoot'); + const data = await this.repository.chatwoot.find(this.instanceName); + + if (!data) { + this.logger.verbose('Chatwoot not found'); + return null; + } + + this.logger.verbose(`Chatwoot account id: ${data.account_id}`); + this.logger.verbose(`Chatwoot token: ${data.token}`); + this.logger.verbose(`Chatwoot url: ${data.url}`); + this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); + this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + + return data; + } + + private async loadSettings() { + this.logger.verbose('Loading settings'); + const data = await this.repository.settings.find(this.instanceName); + this.localSettings.reject_call = data?.reject_call; + this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); + + this.localSettings.msg_call = data?.msg_call; + this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); + + this.localSettings.groups_ignore = data?.groups_ignore; + this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + + this.logger.verbose('Settings loaded'); + } + + public async setSettings(data: SettingsRaw) { + this.logger.verbose('Setting settings'); + await this.repository.settings.create(data, this.instanceName); + this.logger.verbose(`Settings reject_call: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + Object.assign(this.localSettings, data); + this.logger.verbose('Settings set'); + + this.client?.ws?.close(); + } + + public async findSettings() { + this.logger.verbose('Finding settings'); + const data = await this.repository.settings.find(this.instanceName); + + if (!data) { + this.logger.verbose('Settings not found'); + return null; + } + + this.logger.verbose(`Settings url: ${data.reject_call}`); + this.logger.verbose(`Settings msg_call: ${data.msg_call}`); + this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); + return data; + } + + public async sendDataWebhook(event: Events, data: T, local = true) { + const webhookGlobal = this.configService.get('WEBHOOK'); + const webhookLocal = this.localWebhook.events; + const serverUrl = this.configService.get('SERVER').URL; + const we = event.replace(/[.-]/gm, '_').toUpperCase(); + const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + + const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const tokenStore = await this.repository.auth.find(this.instanceName); + const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + + const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + if (local) { + if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { + this.logger.verbose('Sending data to webhook local'); + let baseURL: string; + + if (this.localWebhook.webhook_by_events) { + baseURL = `${this.localWebhook.url}/${transformedWe}`; + } else { + baseURL = this.localWebhook.url; } - this.instance.name = name; - this.logger.verbose(`Instance '${this.instance.name}' initialized`); - this.logger.verbose('Sending instance status to webhook'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-local', + url: baseURL, + event, instance: this.instance.name, - status: 'created', + data, + destination: this.localWebhook.url, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } + + try { + if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { + const httpService = axios.create({ baseURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: this.localWebhook.url, + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + postData['apikey'] = instanceApikey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-local', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: baseURL, + server_url: serverUrl, + }); + } + } + } + + if (webhookGlobal.GLOBAL?.ENABLED) { + if (webhookGlobal.EVENTS[we]) { + this.logger.verbose('Sending data to webhook global'); + const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; + + let globalURL; + + if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { + globalURL = `${globalWebhook.URL}/${transformedWe}`; + } else { + globalURL = globalWebhook.URL; + } + + const localUrl = this.localWebhook.url; + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendDataWebhook-global', + url: globalURL, + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + logData['apikey'] = globalApiKey; + } + + this.logger.log(logData); + } + + try { + if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { + const httpService = axios.create({ baseURL: globalURL }); + const postData = { + event, + instance: this.instance.name, + data, + destination: localUrl, + server_url: serverUrl, + }; + + if (expose && globalApiKey) { + postData['apikey'] = globalApiKey; + } + + await httpService.post('', postData); + } + } catch (error) { + this.logger.error({ + local: WAStartupService.name + '.sendDataWebhook-global', + message: error?.message, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: globalURL, + server_url: serverUrl, + }); + } + } + } + } + + private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { + this.logger.verbose('Connection update'); + if (qr) { + this.logger.verbose('QR code found'); + if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { + this.logger.verbose('QR code limit reached'); + + this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); + this.sendDataWebhook(Events.QRCODE_UPDATED, { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, }); if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'created', - }, - ); - } - } - - public get instanceName() { - this.logger.verbose('Getting instance name'); - return this.instance.name; - } - - public get wuid() { - this.logger.verbose('Getting remoteJid of instance'); - return this.instance.wuid; - } - - public async getProfileName() { - this.logger.verbose('Getting profile name'); - let profileName = this.client.user?.name ?? this.client.user?.verifiedName; - if (!profileName) { - this.logger.verbose('Profile name not found, trying to get from database'); - if (this.configService.get('DATABASE').ENABLED) { - this.logger.verbose('Database enabled, trying to get from database'); - const collection = dbserver - .getClient() - .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(this.instanceName); - const data = await collection.findOne({ _id: 'creds' }); - if (data) { - this.logger.verbose('Profile name found in database'); - const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); - profileName = creds.me?.name || creds.me?.verifiedName; - } - } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { - this.logger.verbose('Profile name found in file'); - const creds = JSON.parse( - readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { - encoding: 'utf-8', - }), - ); - profileName = creds.me?.name || creds.me?.verifiedName; - } + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + message: 'QR code limit reached, please login again', + statusCode: DisconnectReason.badSession, + }, + ); } - this.logger.verbose(`Profile name: ${profileName}`); - return profileName; - } + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + state: 'refused', + statusReason: DisconnectReason.connectionClosed, + }); - public async getProfileStatus() { - this.logger.verbose('Getting profile status'); - const status = await this.client.fetchStatus(this.instance.wuid); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); - this.logger.verbose(`Profile status: ${status.status}`); - return status.status; - } - - public get profilePictureUrl() { - this.logger.verbose('Getting profile picture url'); - return this.instance.profilePictureUrl; - } - - public get qrCode(): wa.QrCode { - this.logger.verbose('Getting qrcode'); - - return { - pairingCode: this.instance.qrcode?.pairingCode, - code: this.instance.qrcode?.code, - base64: this.instance.qrcode?.base64, - }; - } - - private async loadWebhook() { - this.logger.verbose('Loading webhook'); - const data = await this.repository.webhook.find(this.instanceName); - this.localWebhook.url = data?.url; - this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); - - this.localWebhook.enabled = data?.enabled; - this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); - - this.localWebhook.events = data?.events; - this.logger.verbose(`Webhook events: ${this.localWebhook.events}`); - - this.localWebhook.webhook_by_events = data?.webhook_by_events; - this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); - - this.logger.verbose('Webhook loaded'); - } - - public async setWebhook(data: WebhookRaw) { - this.logger.verbose('Setting webhook'); - await this.repository.webhook.create(data, this.instanceName); - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - Object.assign(this.localWebhook, data); - this.logger.verbose('Webhook set'); - } - - public async findWebhook() { - this.logger.verbose('Finding webhook'); - const data = await this.repository.webhook.find(this.instanceName); - - if (!data) { - this.logger.verbose('Webhook not found'); - throw new NotFoundException('Webhook not found'); + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); } - this.logger.verbose(`Webhook url: ${data.url}`); - this.logger.verbose(`Webhook events: ${data.events}`); - return data; - } + this.logger.verbose('endSession defined as true'); + this.endSession = true; - private async loadChatwoot() { - this.logger.verbose('Loading chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - this.localChatwoot.enabled = data?.enabled; - this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`); + this.logger.verbose('Emmiting event logout.instance'); + return this.eventEmitter.emit('no.connection', this.instance.name); + } - this.localChatwoot.account_id = data?.account_id; - this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`); + this.logger.verbose('Incrementing QR code count'); + this.instance.qrcode.count++; - this.localChatwoot.token = data?.token; - this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`); + const optsQrcode: QRCodeToDataURLOptions = { + margin: 3, + scale: 4, + errorCorrectionLevel: 'H', + color: { light: '#ffffff', dark: '#198754' }, + }; - this.localChatwoot.url = data?.url; - this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`); + if (this.phoneNumber) { + await delay(2000); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); + } else { + this.instance.qrcode.pairingCode = null; + } - this.localChatwoot.name_inbox = data?.name_inbox; - this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`); - - this.localChatwoot.sign_msg = data?.sign_msg; - this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); - - this.localChatwoot.number = data?.number; - this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); - - this.localChatwoot.reopen_conversation = data?.reopen_conversation; - this.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`); - - this.localChatwoot.conversation_pending = data?.conversation_pending; - this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`); - - this.logger.verbose('Chatwoot loaded'); - } - - public async setChatwoot(data: ChatwootRaw) { - this.logger.verbose('Setting chatwoot'); - await this.repository.chatwoot.create(data, this.instanceName); - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); - this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); - - Object.assign(this.localChatwoot, data); - this.logger.verbose('Chatwoot set'); - } - - public async findChatwoot() { - this.logger.verbose('Finding chatwoot'); - const data = await this.repository.chatwoot.find(this.instanceName); - - if (!data) { - this.logger.verbose('Chatwoot not found'); - return null; + this.logger.verbose('Generating QR code'); + qrcode.toDataURL(qr, optsQrcode, (error, base64) => { + if (error) { + this.logger.error('Qrcode generate failed:' + error.toString()); + return; } - this.logger.verbose(`Chatwoot account id: ${data.account_id}`); - this.logger.verbose(`Chatwoot token: ${data.token}`); - this.logger.verbose(`Chatwoot url: ${data.url}`); - this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); - this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); - this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); - this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); + this.instance.qrcode.base64 = base64; + this.instance.qrcode.code = qr; - return data; - } + this.sendDataWebhook(Events.QRCODE_UPDATED, { + qrcode: { + instance: this.instance.name, + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }); - private async loadSettings() { - this.logger.verbose('Loading settings'); - const data = await this.repository.settings.find(this.instanceName); - this.localSettings.reject_call = data?.reject_call; - this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`); - - this.localSettings.msg_call = data?.msg_call; - this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`); - - this.localSettings.groups_ignore = data?.groups_ignore; - this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); - - this.localSettings.always_online = data?.always_online; - this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); - - this.localSettings.read_messages = data?.read_messages; - this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); - - this.localSettings.read_status = data?.read_status; - this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); - - this.logger.verbose('Settings loaded'); - } - - public async setSettings(data: SettingsRaw) { - this.logger.verbose('Setting settings'); - await this.repository.settings.create(data, this.instanceName); - this.logger.verbose(`Settings reject_call: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - this.logger.verbose(`Settings always_online: ${data.always_online}`); - this.logger.verbose(`Settings read_messages: ${data.read_messages}`); - this.logger.verbose(`Settings read_status: ${data.read_status}`); - Object.assign(this.localSettings, data); - this.logger.verbose('Settings set'); - - this.client?.ws?.close(); - } - - public async findSettings() { - this.logger.verbose('Finding settings'); - const data = await this.repository.settings.find(this.instanceName); - - if (!data) { - this.logger.verbose('Settings not found'); - return null; - } - - this.logger.verbose(`Settings url: ${data.reject_call}`); - this.logger.verbose(`Settings msg_call: ${data.msg_call}`); - this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); - this.logger.verbose(`Settings always_online: ${data.always_online}`); - this.logger.verbose(`Settings read_messages: ${data.read_messages}`); - this.logger.verbose(`Settings read_status: ${data.read_status}`); - return data; - } - - public async sendDataWebhook(event: Events, data: T, local = true) { - const webhookGlobal = this.configService.get('WEBHOOK'); - const webhookLocal = this.localWebhook.events; - const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[.-]/gm, '_').toUpperCase(); - const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - - const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; - const tokenStore = await this.repository.auth.find(this.instanceName); - const instanceApikey = tokenStore?.apikey || 'Apikey not found'; - - const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - if (local) { - if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { - this.logger.verbose('Sending data to webhook local'); - let baseURL: string; - - if (this.localWebhook.webhook_by_events) { - baseURL = `${this.localWebhook.url}/${transformedWe}`; - } else { - baseURL = this.localWebhook.url; - } - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-local', - url: baseURL, - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - apikey: (expose && instanceApikey) || null, - }; - - if (expose && instanceApikey) { - logData['apikey'] = instanceApikey; - } - - this.logger.log(logData); - } - - try { - if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { - const httpService = axios.create({ baseURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: this.localWebhook.url, - server_url: serverUrl, - }; - - if (expose && instanceApikey) { - postData['apikey'] = instanceApikey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-local', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: baseURL, - server_url: serverUrl, - }); - } - } - } - - if (webhookGlobal.GLOBAL?.ENABLED) { - if (webhookGlobal.EVENTS[we]) { - this.logger.verbose('Sending data to webhook global'); - const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; - - let globalURL; - - if (webhookGlobal.GLOBAL.WEBHOOK_BY_EVENTS) { - globalURL = `${globalWebhook.URL}/${transformedWe}`; - } else { - globalURL = globalWebhook.URL; - } - - const localUrl = this.localWebhook.url; - - if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - const logData = { - local: WAStartupService.name + '.sendDataWebhook-global', - url: globalURL, - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - logData['apikey'] = globalApiKey; - } - - this.logger.log(logData); - } - - try { - if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { - const httpService = axios.create({ baseURL: globalURL }); - const postData = { - event, - instance: this.instance.name, - data, - destination: localUrl, - server_url: serverUrl, - }; - - if (expose && globalApiKey) { - postData['apikey'] = globalApiKey; - } - - await httpService.post('', postData); - } - } catch (error) { - this.logger.error({ - local: WAStartupService.name + '.sendDataWebhook-global', - message: error?.message, - hostName: error?.hostname, - syscall: error?.syscall, - code: error?.code, - error: error?.errno, - stack: error?.stack, - name: error?.name, - url: globalURL, - server_url: serverUrl, - }); - } - } - } - } - - private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { - this.logger.verbose('Connection update'); - if (qr) { - this.logger.verbose('QR code found'); - if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { - this.logger.verbose('QR code limit reached'); - - this.logger.verbose('Sending data to webhook in event QRCODE_UPDATED'); - this.sendDataWebhook(Events.QRCODE_UPDATED, { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - message: 'QR code limit reached, please login again', - statusCode: DisconnectReason.badSession, - }, - ); - } - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { - instance: this.instance.name, - state: 'refused', - statusReason: DisconnectReason.connectionClosed, - }); - - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('endSession defined as true'); - this.endSession = true; - - this.logger.verbose('Emmiting event logout.instance'); - return this.eventEmitter.emit('no.connection', this.instance.name); - } - - this.logger.verbose('Incrementing QR code count'); - this.instance.qrcode.count++; - - const optsQrcode: QRCodeToDataURLOptions = { - margin: 3, - scale: 4, - errorCorrectionLevel: 'H', - color: { light: '#ffffff', dark: '#198754' }, - }; - - if (this.phoneNumber) { - await delay(2000); - this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); - } else { - this.instance.qrcode.pairingCode = null; - } - - this.logger.verbose('Generating QR code'); - qrcode.toDataURL(qr, optsQrcode, (error, base64) => { - if (error) { - this.logger.error('Qrcode generate failed:' + error.toString()); - return; - } - - this.instance.qrcode.base64 = base64; - this.instance.qrcode.code = qr; - - this.sendDataWebhook(Events.QRCODE_UPDATED, { - qrcode: { - instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, - { - qrcode: { - instance: this.instance.name, - pairingCode: this.instance.qrcode.pairingCode, - code: qr, - base64, - }, - }, - ); - } - }); - - this.logger.verbose('Generating QR code in terminal'); - qrcodeTerminal.generate(qr, { small: true }, (qrcode) => - this.logger.log( - `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + - qrcode, - ), - ); - } - - if (connection) { - this.logger.verbose('Connection found'); - this.stateConnection = { - state: connection, - statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, - }; - - this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); - this.sendDataWebhook(Events.CONNECTION_UPDATE, { + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.QRCODE_UPDATED, + { instanceName: this.instance.name }, + { + qrcode: { instance: this.instance.name, - ...this.stateConnection, - }); + pairingCode: this.instance.qrcode.pairingCode, + code: qr, + base64, + }, + }, + ); + } + }); + + this.logger.verbose('Generating QR code in terminal'); + qrcodeTerminal.generate(qr, { small: true }, (qrcode) => + this.logger.log( + `\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` + + qrcode, + ), + ); + } + + if (connection) { + this.logger.verbose('Connection found'); + this.stateConnection = { + state: connection, + statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200, + }; + + this.logger.verbose('Sending data to webhook in event CONNECTION_UPDATE'); + this.sendDataWebhook(Events.CONNECTION_UPDATE, { + instance: this.instance.name, + ...this.stateConnection, + }); + } + + if (connection === 'close') { + this.logger.verbose('Connection closed'); + const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; + if (shouldReconnect) { + this.logger.verbose('Reconnecting to whatsapp'); + await this.connectToWhatsapp(); + } else { + this.logger.verbose('Do not reconnect to whatsapp'); + this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); + this.sendDataWebhook(Events.STATUS_INSTANCE, { + instance: this.instance.name, + status: 'removed', + }); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.STATUS_INSTANCE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'removed', + }, + ); } - if (connection === 'close') { - this.logger.verbose('Connection closed'); - const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; - if (shouldReconnect) { - this.logger.verbose('Reconnecting to whatsapp'); - await this.connectToWhatsapp(); - } else { - this.logger.verbose('Do not reconnect to whatsapp'); - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); + this.logger.verbose('Emittin event logout.instance'); + this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); + this.client?.ws?.close(); + this.client.end(new Error('Close connection')); + this.logger.verbose('Connection closed'); + } + } - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - - this.logger.verbose('Emittin event logout.instance'); - this.eventEmitter.emit('logout.instance', this.instance.name, 'inner'); - this.client?.ws?.close(); - this.client.end(new Error('Close connection')); - this.logger.verbose('Connection closed'); - } - } - - if (connection === 'open') { - this.logger.verbose('Connection opened'); - this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); - this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; - this.logger.info( - ` + if (connection === 'open') { + this.logger.verbose('Connection opened'); + this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); + this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; + this.logger.info( + ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ └──────────────────────────────┘`.replace(/^ +/gm, ' '), - ); + ); - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.CONNECTION_UPDATE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'open', - }, - ); - } - } + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.CONNECTION_UPDATE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'open', + }, + ); + } } + } - private async getMessage(key: proto.IMessageKey, full = false) { - this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); + private async getMessage(key: proto.IMessageKey, full = false) { + this.logger.verbose('Getting message with key: ' + JSON.stringify(key)); + try { + const webMessageInfo = (await this.repository.message.find({ + where: { owner: this.instance.name, key: { id: key.id } }, + })) as unknown as proto.IWebMessageInfo[]; + if (full) { + this.logger.verbose('Returning full message'); + return webMessageInfo[0]; + } + if (webMessageInfo[0].message?.pollCreationMessage) { + this.logger.verbose('Returning poll message'); + const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; + + if (typeof messageSecretBase64 === 'string') { + const messageSecret = Buffer.from(messageSecretBase64, 'base64'); + + const msg = { + messageContextInfo: { + messageSecret, + }, + pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, + }; + + return msg; + } + } + + this.logger.verbose('Returning message'); + return webMessageInfo[0].message; + } catch (error) { + return { conversation: '' }; + } + } + + private cleanStore() { + this.logger.verbose('Cronjob to clean store initialized'); + const cleanStore = this.configService.get('CLEAN_STORE'); + const database = this.configService.get('DATABASE'); + if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { + this.logger.verbose('Cronjob to clean store enabled'); + setInterval(() => { try { - const webMessageInfo = (await this.repository.message.find({ - where: { owner: this.instance.name, key: { id: key.id } }, - })) as unknown as proto.IWebMessageInfo[]; - if (full) { - this.logger.verbose('Returning full message'); - return webMessageInfo[0]; + for (const [key, value] of Object.entries(cleanStore)) { + if (value === true) { + execSync( + `rm -rf ${join(this.storePath, key.toLowerCase().replace('_', '-'), this.instance.name)}/*.json`, + ); + this.logger.verbose( + `Cleaned ${join(this.storePath, key.toLowerCase().replace('_', '-'), this.instance.name)}/*.json`, + ); } - if (webMessageInfo[0].message?.pollCreationMessage) { - this.logger.verbose('Returning poll message'); - const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; - - if (typeof messageSecretBase64 === 'string') { - const messageSecret = Buffer.from(messageSecretBase64, 'base64'); - - const msg = { - messageContextInfo: { - messageSecret, - }, - pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage, - }; - - return msg; - } - } - - this.logger.verbose('Returning message'); - return webMessageInfo[0].message; + } } catch (error) { - return { conversation: '' }; + this.logger.error(error); } + }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); + } + } + + private async defineAuthState() { + this.logger.verbose('Defining auth state'); + const db = this.configService.get('DATABASE'); + const redis = this.configService.get('REDIS'); + + if (redis?.ENABLED) { + this.logger.verbose('Redis enabled'); + this.cache.reference = this.instance.name; + return await useMultiFileAuthStateRedisDb(this.cache); } - private cleanStore() { - this.logger.verbose('Cronjob to clean store initialized'); - const cleanStore = this.configService.get('CLEAN_STORE'); + if (db.SAVE_DATA.INSTANCE && db.ENABLED) { + this.logger.verbose('Database enabled'); + return await useMultiFileAuthStateDb(this.instance.name); + } + + this.logger.verbose('Store file enabled'); + return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); + } + + public async connectToWhatsapp(number?: string): Promise { + this.logger.verbose('Connecting to whatsapp'); + try { + this.loadWebhook(); + this.loadChatwoot(); + this.loadSettings(); + + this.instance.authState = await this.defineAuthState(); + + const { version } = await fetchLatestBaileysVersion(); + this.logger.verbose('Baileys version: ' + version); + const session = this.configService.get('CONFIG_SESSION_PHONE'); + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + this.logger.verbose('Browser: ' + JSON.stringify(browser)); + + const socketConfig: UserFacingSocketConfig = { + auth: { + creds: this.instance.authState.state.creds, + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + }, + logger: P({ level: this.logBaileys }), + printQRInTerminal: false, + browser, + version, + markOnlineOnConnect: this.localSettings.always_online, + connectTimeoutMs: 60_000, + qrTimeout: 40_000, + defaultQueryTimeoutMs: undefined, + emitOwnEvents: false, + msgRetryCounterCache: this.msgRetryCounterCache, + getMessage: async (key) => (await this.getMessage(key)) as Promise, + generateHighQualityLinkPreview: true, + syncFullHistory: true, + userDevicesCache: this.userDevicesCache, + transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, + patchMessageBeforeSending: (message) => { + const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); + if (requiresPatch) { + message = { + viewOnceMessageV2: { + message: { + messageContextInfo: { + deviceListMetadataVersion: 2, + deviceListMetadata: {}, + }, + ...message, + }, + }, + }; + } + + return message; + }, + }; + + this.endSession = false; + + this.logger.verbose('Creating socket'); + + this.client = makeWASocket(socketConfig); + + this.logger.verbose('Socket created'); + + this.eventHandler(); + + this.logger.verbose('Socket event handler initialized'); + + this.phoneNumber = number; + + return this.client; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString()); + } + } + + private readonly chatHandle = { + 'chats.upsert': async (chats: Chat[], database: Database) => { + this.logger.verbose('Event received: chats.upsert'); + + this.logger.verbose('Finding chats in database'); + const chatsRepository = await this.repository.chat.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if chats exists in database to insert'); + const chatsRaw: ChatRaw[] = []; + for await (const chat of chats) { + if (chatsRepository.find((cr) => cr.id === chat.id)) { + continue; + } + + chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); + } + + this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); + await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + }, + + 'chats.update': async ( + chats: Partial< + proto.IConversation & { + lastMessageRecvTimestamp?: number; + } & { + conditional: (bufferedData: BufferedEventData) => boolean; + } + >[], + ) => { + this.logger.verbose('Event received: chats.update'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { id: chat.id, owner: this.instance.wuid }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); + await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); + }, + + 'chats.delete': async (chats: string[]) => { + this.logger.verbose('Event received: chats.delete'); + + this.logger.verbose('Deleting chats in database'); + chats.forEach( + async (chat) => + await this.repository.chat.delete({ + where: { owner: this.instance.name, id: chat }, + }), + ); + + this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); + await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); + }, + }; + + private readonly contactHandle = { + 'contacts.upsert': async (contacts: Contact[], database: Database) => { + this.logger.verbose('Event received: contacts.upsert'); + + this.logger.verbose('Finding contacts in database'); + const contactsRepository = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + this.logger.verbose('Verifying if contacts exists in database to insert'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + if (contactsRepository.find((cr) => cr.id === contact.id)) { + continue; + } + + contactsRaw.push({ + id: contact.id, + pushName: contact?.name || contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); + + this.logger.verbose('Inserting contacts in database'); + await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + + 'contacts.update': async (contacts: Partial[], database: Database) => { + this.logger.verbose('Event received: contacts.update'); + + this.logger.verbose('Verifying if contacts exists in database to update'); + const contactsRaw: ContactRaw[] = []; + for await (const contact of contacts) { + contactsRaw.push({ + id: contact.id, + pushName: contact?.name ?? contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); + + this.logger.verbose('Updating contacts in database'); + await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); + }, + }; + + private readonly messageHandle = { + 'messaging-history.set': async ( + { + messages, + chats, + isLatest, + }: { + chats: Chat[]; + contacts: Contact[]; + messages: proto.IWebMessageInfo[]; + isLatest: boolean; + }, + database: Database, + ) => { + this.logger.verbose('Event received: messaging-history.set'); + if (isLatest) { + this.logger.verbose('isLatest defined as true'); + const chatsRaw: ChatRaw[] = chats.map((chat) => { + return { + id: chat.id, + owner: this.instance.name, + lastMsgTimestamp: chat.lastMessageRecvTimestamp, + }; + }); + + this.logger.verbose('Sending data to webhook in event CHATS_SET'); + await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); + + this.logger.verbose('Inserting chats in database'); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); + } + + const messagesRaw: MessageRaw[] = []; + const messagesRepository = await this.repository.message.find({ + where: { owner: this.instance.name }, + }); + for await (const [, m] of Object.entries(messages)) { + if (!m.message) { + continue; + } + if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { + continue; + } + + if (Long.isLong(m?.messageTimestamp)) { + m.messageTimestamp = m.messageTimestamp?.toNumber(); + } + + messagesRaw.push({ + key: m.key, + pushName: m.pushName, + participant: m.participant, + message: { ...m.message }, + messageType: getContentType(m.message), + messageTimestamp: m.messageTimestamp as number, + owner: this.instance.name, + }); + } + + this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); + this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); + + messages = undefined; + }, + + 'messages.upsert': async ( + { + messages, + type, + }: { + messages: proto.IWebMessageInfo[]; + type: MessageUpsertType; + }, + database: Database, + settings: SettingsRaw, + ) => { + this.logger.verbose('Event received: messages.upsert'); + const received = messages[0]; + + if (type !== 'notify' || received.message?.protocolMessage || received.message?.pollUpdateMessage) { + this.logger.verbose('message rejected'); + return; + } + + if (Long.isLong(received.messageTimestamp)) { + received.messageTimestamp = received.messageTimestamp?.toNumber(); + } + + if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + + const messageRaw: MessageRaw = { + key: received.key, + pushName: received.pushName, + message: { ...received.message }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), + }; + + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); + await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.MESSAGES_UPSERT, + { instanceName: this.instance.name }, + messageRaw, + ); + } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); + + this.logger.verbose('Verifying contact from message'); + const contact = await this.repository.contact.find({ + where: { owner: this.instance.name, id: received.key.remoteJid }, + }); + + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: received.pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, + }; + + if (contactRaw.id === 'status@broadcast') { + this.logger.verbose('Contact is status@broadcast'); + return; + } + + if (contact?.length) { + this.logger.verbose('Contact found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: contact[0].pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, + owner: this.instance.name, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); + + if (this.localChatwoot.enabled) { + await this.chatwootService.eventWhatsapp( + Events.CONTACTS_UPDATE, + { instanceName: this.instance.name }, + contactRaw, + ); + } + + this.logger.verbose('Updating contact in database'); + await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); + return; + } + + this.logger.verbose('Contact not found in database'); + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); + + this.logger.verbose('Inserting contact in database'); + await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); + }, + + 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { + this.logger.verbose('Event received: messages.update'); + const status: Record = { + 0: 'ERROR', + 1: 'PENDING', + 2: 'SERVER_ACK', + 3: 'DELIVERY_ACK', + 4: 'READ', + 5: 'PLAYED', + }; + for await (const { key, update } of args) { + if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { + this.logger.verbose('Message update is valid'); + + let pollUpdates: any; + if (update.pollUpdates) { + this.logger.verbose('Poll update found'); + + this.logger.verbose('Getting poll message'); + const pollCreation = await this.getMessage(key); + this.logger.verbose(pollCreation); + + if (pollCreation) { + this.logger.verbose('Getting aggregate votes in poll message'); + pollUpdates = getAggregateVotesInPollMessage({ + message: pollCreation as proto.IMessage, + pollUpdates: update.pollUpdates, + }); + } + } + + if (status[update.status] === 'READ' && !key.fromMe) return; + + if (update.message === null && update.status === undefined) { + this.logger.verbose('Message deleted'); + + this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); + await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + + const message: MessageUpdateRaw = { + ...key, + status: 'DELETED', + datetime: Date.now(), + owner: this.instance.name, + }; + + this.logger.verbose(message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert( + [message], + this.instance.name, + database.SAVE_DATA.MESSAGE_UPDATE, + ); + return; + } + + const message: MessageUpdateRaw = { + ...key, + status: status[update.status], + datetime: Date.now(), + owner: this.instance.name, + pollUpdates, + }; + + this.logger.verbose(message); + + this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); + await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); + + this.logger.verbose('Inserting message in database'); + await this.repository.messageUpdate.insert([message], this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE); + } + } + }, + }; + + private readonly groupHandler = { + 'groups.upsert': (groupMetadata: GroupMetadata[]) => { + this.logger.verbose('Event received: groups.upsert'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); + this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); + }, + + 'groups.update': (groupMetadataUpdate: Partial[]) => { + this.logger.verbose('Event received: groups.update'); + + this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); + this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); + }, + + 'group-participants.update': (participantsUpdate: { + id: string; + participants: string[]; + action: ParticipantAction; + }) => { + this.logger.verbose('Event received: group-participants.update'); + + this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); + this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); + }, + }; + + private eventHandler() { + this.logger.verbose('Initializing event handler'); + this.client.ev.process(async (events) => { + if (!this.endSession) { const database = this.configService.get('DATABASE'); - if (cleanStore?.CLEANING_INTERVAL && !database.ENABLED) { - this.logger.verbose('Cronjob to clean store enabled'); - setInterval(() => { - try { - for (const [key, value] of Object.entries(cleanStore)) { - if (value === true) { - execSync( - `rm -rf ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - this.logger.verbose( - `Cleaned ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, - ); - } - } - } catch (error) { - this.logger.error(error); - } - }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); + const settings = await this.findSettings(); + + if (events.call) { + this.logger.verbose('Listening event: call'); + const call = events.call[0]; + + if (settings?.reject_call && call.status == 'offer') { + this.logger.verbose('Rejecting call'); + this.client.rejectCall(call.id, call.from); + } + + if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { + this.logger.verbose('Sending message in call'); + const msg = await this.client.sendMessage(call.from, { + text: settings.msg_call, + }); + + this.logger.verbose('Sending data to event messages.upsert'); + this.client.ev.emit('messages.upsert', { + messages: [msg], + type: 'notify', + }); + } + + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); } + + if (events['connection.update']) { + this.logger.verbose('Listening event: connection.update'); + this.connectionUpdate(events['connection.update']); + } + + if (events['creds.update']) { + this.logger.verbose('Listening event: creds.update'); + this.instance.authState.saveCreds(); + } + + if (events['messaging-history.set']) { + this.logger.verbose('Listening event: messaging-history.set'); + const payload = events['messaging-history.set']; + this.messageHandle['messaging-history.set'](payload, database); + } + + if (events['messages.upsert']) { + this.logger.verbose('Listening event: messages.upsert'); + const payload = events['messages.upsert']; + this.messageHandle['messages.upsert'](payload, database, settings); + } + + if (events['messages.update']) { + this.logger.verbose('Listening event: messages.update'); + const payload = events['messages.update']; + this.messageHandle['messages.update'](payload, database, settings); + } + + if (events['presence.update']) { + this.logger.verbose('Listening event: presence.update'); + const payload = events['presence.update']; + + if (settings.groups_ignore && payload.id.includes('@g.us')) { + this.logger.verbose('group ignored'); + return; + } + this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); + } + + if (!settings?.groups_ignore) { + if (events['groups.upsert']) { + this.logger.verbose('Listening event: groups.upsert'); + const payload = events['groups.upsert']; + this.groupHandler['groups.upsert'](payload); + } + + if (events['groups.update']) { + this.logger.verbose('Listening event: groups.update'); + const payload = events['groups.update']; + this.groupHandler['groups.update'](payload); + } + + if (events['group-participants.update']) { + this.logger.verbose('Listening event: group-participants.update'); + const payload = events['group-participants.update']; + this.groupHandler['group-participants.update'](payload); + } + } + + if (events['chats.upsert']) { + this.logger.verbose('Listening event: chats.upsert'); + const payload = events['chats.upsert']; + this.chatHandle['chats.upsert'](payload, database); + } + + if (events['chats.update']) { + this.logger.verbose('Listening event: chats.update'); + const payload = events['chats.update']; + this.chatHandle['chats.update'](payload); + } + + if (events['chats.delete']) { + this.logger.verbose('Listening event: chats.delete'); + const payload = events['chats.delete']; + this.chatHandle['chats.delete'](payload); + } + + if (events['contacts.upsert']) { + this.logger.verbose('Listening event: contacts.upsert'); + const payload = events['contacts.upsert']; + this.contactHandle['contacts.upsert'](payload, database); + } + + if (events['contacts.update']) { + this.logger.verbose('Listening event: contacts.update'); + const payload = events['contacts.update']; + this.contactHandle['contacts.update'](payload, database); + } + } + }); + } + + // Check if the number is MX or AR + private formatMXOrARNumber(jid: string): string { + const countryCode = jid.substring(0, 2); + + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; + } + + return jid; + } + return jid; + } + + // Check if the number is br + private formatBRNumber(jid: string) { + const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); + if (regexp.test(jid)) { + const match = regexp.exec(jid); + if (match && match[1] === '55') { + const joker = Number.parseInt(match[3][0]); + const ddd = Number.parseInt(match[2]); + if (joker < 7 || ddd < 31) { + return match[0]; + } + return match[1] + match[2] + match[3]; + } + return jid; + } else { + return jid; + } + } + + private createJid(number: string): string { + this.logger.verbose('Creating jid with number: ' + number); + + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { + this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); + return number; } - private async defineAuthState() { - this.logger.verbose('Defining auth state'); - const db = this.configService.get('DATABASE'); - const redis = this.configService.get('REDIS'); - - if (redis?.ENABLED) { - this.logger.verbose('Redis enabled'); - this.cache.reference = this.instance.name; - return await useMultiFileAuthStateRedisDb(this.cache); - } - - if (db.SAVE_DATA.INSTANCE && db.ENABLED) { - this.logger.verbose('Database enabled'); - return await useMultiFileAuthStateDb(this.instance.name); - } - - this.logger.verbose('Store file enabled'); - return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); + if (number.includes('@broadcast')) { + this.logger.verbose('Number already contains @broadcast'); + return number; } - public async connectToWhatsapp(number?: string): Promise { - this.logger.verbose('Connecting to whatsapp'); + number = number + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(':')[0] + .split('@')[0]; + + if (number.includes('-') && number.length >= 24) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = number.replace(/\D/g, ''); + + if (number.length >= 18) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); + return `${number}@s.whatsapp.net`; + } + + public async profilePicture(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile picture with jid: ' + jid); + try { + this.logger.verbose('Getting profile picture url'); + return { + wuid: jid, + profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), + }; + } catch (error) { + this.logger.verbose('Profile picture not found'); + return { + wuid: jid, + profilePictureUrl: null, + }; + } + } + + public async getStatus(number: string) { + const jid = this.createJid(number); + + this.logger.verbose('Getting profile status with jid:' + jid); + try { + this.logger.verbose('Getting status'); + return { + wuid: jid, + status: (await this.client.fetchStatus(jid))?.status, + }; + } catch (error) { + this.logger.verbose('Status not found'); + return { + wuid: jid, + status: null, + }; + } + } + + public async fetchProfile(instanceName: string, number?: string) { + const jid = number ? this.createJid(number) : this.client?.user?.id; + + this.logger.verbose('Getting profile with jid: ' + jid); + try { + this.logger.verbose('Getting profile info'); + const business = await this.fetchBusinessProfile(jid); + + if (number) { + const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); + const picture = await this.profilePicture(jid); + const status = await this.getStatus(jid); + + return { + wuid: jid, + name: info?.name, + numberExists: info?.exists, + picture: picture?.profilePictureUrl, + status: status?.status, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } else { + const info = await waMonitor.instanceInfo(instanceName); + + return { + wuid: jid, + name: info?.instance?.profileName, + numberExists: true, + picture: info?.instance?.profilePictureUrl, + status: info?.instance?.profileStatus, + isBusiness: business.isBusiness, + email: business?.email, + description: business?.description, + website: business?.website?.shift(), + }; + } + } catch (error) { + this.logger.verbose('Profile not found'); + return { + wuid: jid, + name: null, + picture: null, + status: null, + os: null, + isBusiness: false, + }; + } + } + + private async sendMessageWithTyping(number: string, message: T, options?: Options) { + this.logger.verbose('Sending message with typing'); + + const numberWA = await this.whatsappNumber({ numbers: [number] }); + const isWA = numberWA[0]; + + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { + throw new BadRequestException(isWA); + } + + const sender = isWA.jid; + + try { + if (options?.delay) { + this.logger.verbose('Delaying message'); + + await this.client.presenceSubscribe(sender); + this.logger.verbose('Subscribing to presence'); + + await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); + this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); + + await delay(options.delay); + this.logger.verbose('Set delay: ' + options.delay); + + await this.client.sendPresenceUpdate('paused', sender); + this.logger.verbose('Sending presence update: paused'); + } + + const linkPreview = options?.linkPreview != false ? undefined : false; + + let quoted: WAMessage; + + if (options?.quoted) { + const m = options?.quoted; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + quoted = msg; + this.logger.verbose('Quoted message'); + } + + let mentions: string[]; + if (isJidGroup(sender)) { try { - this.loadWebhook(); - this.loadChatwoot(); - this.loadSettings(); + const groupMetadata = await this.client.groupMetadata(sender); - this.instance.authState = await this.defineAuthState(); + if (!groupMetadata) { + throw new NotFoundException('Group not found'); + } - const { version } = await fetchLatestBaileysVersion(); - this.logger.verbose('Baileys version: ' + version); - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - this.logger.verbose('Browser: ' + JSON.stringify(browser)); + if (options?.mentions) { + this.logger.verbose('Mentions defined'); - const socketConfig: UserFacingSocketConfig = { - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + if (options.mentions?.everyOne) { + this.logger.verbose('Mentions everyone'); + + this.logger.verbose('Getting group metadata'); + mentions = groupMetadata.participants.map((participant) => participant.id); + this.logger.verbose('Getting group metadata for mentions'); + } else if (options.mentions?.mentioned?.length) { + this.logger.verbose('Mentions manually defined'); + mentions = options.mentions.mentioned.map((mention) => { + const jid = this.createJid(mention); + if (isJidGroup(jid)) { + return null; + // throw new BadRequestException('Mentions must be a number'); + } + return jid; + }); + } + } + } catch (error) { + throw new NotFoundException('Group not found'); + } + } + + const messageSent = await (async () => { + const option = { + quoted, + }; + + if ( + !message['audio'] && + !message['poll'] && + !message['sticker'] && + !message['conversation'] && + sender !== 'status@broadcast' + ) { + if (!message['audio']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + forward: { + key: { remoteJid: this.instance.wuid, fromMe: true }, + message, }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - browser, - version, - markOnlineOnConnect: this.localSettings.always_online, - connectTimeoutMs: 60_000, - qrTimeout: 40_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: true, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, - patchMessageBeforeSending: (message) => { - const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); - if (requiresPatch) { - message = { - viewOnceMessageV2: { - message: { - messageContextInfo: { - deviceListMetadataVersion: 2, - deviceListMetadata: {}, - }, - ...message, - }, - }, - }; - } - - return message; - }, - }; - - this.endSession = false; - - this.logger.verbose('Creating socket'); - - this.client = makeWASocket(socketConfig); - - this.logger.verbose('Socket created'); - - this.eventHandler(); - - this.logger.verbose('Socket event handler initialized'); - - this.phoneNumber = number; - - return this.client; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString()); - } - } - - private readonly chatHandle = { - 'chats.upsert': async (chats: Chat[], database: Database) => { - this.logger.verbose('Event received: chats.upsert'); - - this.logger.verbose('Finding chats in database'); - const chatsRepository = await this.repository.chat.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if chats exists in database to insert'); - const chatsRaw: ChatRaw[] = []; - for await (const chat of chats) { - if (chatsRepository.find((cr) => cr.id === chat.id)) { - continue; - } - - chatsRaw.push({ id: chat.id, owner: this.instance.wuid }); - } - - this.logger.verbose('Sending data to webhook in event CHATS_UPSERT'); - await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); - }, - - 'chats.update': async ( - chats: Partial< - proto.IConversation & { - lastMessageRecvTimestamp?: number; - } & { - conditional: (bufferedData: BufferedEventData) => boolean; - } - >[], - ) => { - this.logger.verbose('Event received: chats.update'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { id: chat.id, owner: this.instance.wuid }; - }); - - this.logger.verbose('Sending data to webhook in event CHATS_UPDATE'); - await this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw); - }, - - 'chats.delete': async (chats: string[]) => { - this.logger.verbose('Event received: chats.delete'); - - this.logger.verbose('Deleting chats in database'); - chats.forEach( - async (chat) => - await this.repository.chat.delete({ - where: { owner: this.instance.name, id: chat }, - }), + mentions, + }, + option as unknown as MiscMessageGenerationOptions, ); + } + } - this.logger.verbose('Sending data to webhook in event CHATS_DELETE'); - await this.sendDataWebhook(Events.CHATS_DELETE, [...chats]); - }, - }; - - private readonly contactHandle = { - 'contacts.upsert': async (contacts: Contact[], database: Database) => { - this.logger.verbose('Event received: contacts.upsert'); - - this.logger.verbose('Finding contacts in database'); - const contactsRepository = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - this.logger.verbose('Verifying if contacts exists in database to insert'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - if (contactsRepository.find((cr) => cr.id === contact.id)) { - continue; - } - - contactsRaw.push({ - id: contact.id, - pushName: contact?.name || contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); - - this.logger.verbose('Inserting contacts in database'); - await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); - }, - - 'contacts.update': async (contacts: Partial[], database: Database) => { - this.logger.verbose('Event received: contacts.update'); - - this.logger.verbose('Verifying if contacts exists in database to update'); - const contactsRaw: ContactRaw[] = []; - for await (const contact of contacts) { - contactsRaw.push({ - id: contact.id, - pushName: contact?.name ?? contact?.verifiedName, - profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); - - this.logger.verbose('Updating contacts in database'); - await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); - }, - }; - - private readonly messageHandle = { - 'messaging-history.set': async ( + if (message['conversation']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, { - messages, - chats, - isLatest, - }: { - chats: Chat[]; - contacts: Contact[]; - messages: proto.IWebMessageInfo[]; - isLatest: boolean; - }, - database: Database, - ) => { - this.logger.verbose('Event received: messaging-history.set'); - if (isLatest) { - this.logger.verbose('isLatest defined as true'); - const chatsRaw: ChatRaw[] = chats.map((chat) => { - return { - id: chat.id, - owner: this.instance.name, - lastMsgTimestamp: chat.lastMessageRecvTimestamp, - }; - }); + text: message['conversation'], + mentions, + linkPreview: linkPreview, + } as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, + ); + } - this.logger.verbose('Sending data to webhook in event CHATS_SET'); - await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); - - this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); - } - - const messagesRaw: MessageRaw[] = []; - const messagesRepository = await this.repository.message.find({ - where: { owner: this.instance.name }, - }); - for await (const [, m] of Object.entries(messages)) { - if (!m.message) { - continue; - } - if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { - continue; - } - - if (Long.isLong(m?.messageTimestamp)) { - m.messageTimestamp = m.messageTimestamp?.toNumber(); - } - - messagesRaw.push({ - key: m.key, - pushName: m.pushName, - participant: m.participant, - message: { ...m.message }, - messageType: getContentType(m.message), - messageTimestamp: m.messageTimestamp as number, - owner: this.instance.name, - }); - } - - this.logger.verbose('Sending data to webhook in event MESSAGES_SET'); - this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw]); - - messages = undefined; - }, - - 'messages.upsert': async ( + if (sender === 'status@broadcast') { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message['status'].content as unknown as AnyMessageContent, { - messages, - type, - }: { - messages: proto.IWebMessageInfo[]; - type: MessageUpsertType; - }, - database: Database, - settings: SettingsRaw, - ) => { - this.logger.verbose('Event received: messages.upsert'); - const received = messages[0]; - - if (type !== 'notify' || received.message?.protocolMessage || received.message?.pollUpdateMessage) { - this.logger.verbose('message rejected'); - return; - } - - if (Long.isLong(received.messageTimestamp)) { - received.messageTimestamp = received.messageTimestamp?.toNumber(); - } - - if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - - const messageRaw: MessageRaw = { - key: received.key, - pushName: received.pushName, - message: { ...received.message }, - messageType: getContentType(received.message), - messageTimestamp: received.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(received.key.id), - }; - - if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { - await this.client.readMessages([received.key]); - } - - if (this.localSettings.read_status && received.key.id === 'status@broadcast') { - await this.client.readMessages([received.key]); - } - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); - await this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, - messageRaw, - ); - } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); - - this.logger.verbose('Verifying contact from message'); - const contact = await this.repository.contact.find({ - where: { owner: this.instance.name, id: received.key.remoteJid }, - }); - - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: received.pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, - owner: this.instance.name, - }; - - if (contactRaw.id === 'status@broadcast') { - this.logger.verbose('Contact is status@broadcast'); - return; - } - - if (contact?.length) { - this.logger.verbose('Contact found in database'); - const contactRaw: ContactRaw = { - id: received.key.remoteJid, - pushName: contact[0].pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, - owner: this.instance.name, - }; - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); - await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); - - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, - contactRaw, - ); - } - - this.logger.verbose('Updating contact in database'); - await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); - return; - } - - this.logger.verbose('Contact not found in database'); - - this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); - await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); - - this.logger.verbose('Inserting contact in database'); - await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); - }, - - 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { - this.logger.verbose('Event received: messages.update'); - const status: Record = { - 0: 'ERROR', - 1: 'PENDING', - 2: 'SERVER_ACK', - 3: 'DELIVERY_ACK', - 4: 'READ', - 5: 'PLAYED', - }; - for await (const { key, update } of args) { - if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { - this.logger.verbose('Message update is valid'); - - let pollUpdates: any; - if (update.pollUpdates) { - this.logger.verbose('Poll update found'); - - this.logger.verbose('Getting poll message'); - const pollCreation = await this.getMessage(key); - this.logger.verbose(pollCreation); - - if (pollCreation) { - this.logger.verbose('Getting aggregate votes in poll message'); - pollUpdates = getAggregateVotesInPollMessage({ - message: pollCreation as proto.IMessage, - pollUpdates: update.pollUpdates, - }); - } - } - - if (status[update.status] === 'READ' && !key.fromMe) return; - - if (update.message === null && update.status === undefined) { - this.logger.verbose('Message deleted'); - - this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); - await this.sendDataWebhook(Events.MESSAGES_DELETE, key); - - const message: MessageUpdateRaw = { - ...key, - status: 'DELETED', - datetime: Date.now(), - owner: this.instance.name, - }; - - this.logger.verbose(message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - return; - } - - const message: MessageUpdateRaw = { - ...key, - status: status[update.status], - datetime: Date.now(), - owner: this.instance.name, - pollUpdates, - }; - - this.logger.verbose(message); - - this.logger.verbose('Sending data to webhook in event MESSAGES_UPDATE'); - await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); - - this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); - } - } - }, - }; - - private readonly groupHandler = { - 'groups.upsert': (groupMetadata: GroupMetadata[]) => { - this.logger.verbose('Event received: groups.upsert'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPSERT'); - this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata); - }, - - 'groups.update': (groupMetadataUpdate: Partial[]) => { - this.logger.verbose('Event received: groups.update'); - - this.logger.verbose('Sending data to webhook in event GROUPS_UPDATE'); - this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - }, - - 'group-participants.update': (participantsUpdate: { - id: string; - participants: string[]; - action: ParticipantAction; - }) => { - this.logger.verbose('Event received: group-participants.update'); - - this.logger.verbose('Sending data to webhook in event GROUP_PARTICIPANTS_UPDATE'); - this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - }, - }; - - private eventHandler() { - this.logger.verbose('Initializing event handler'); - this.client.ev.process(async (events) => { - if (!this.endSession) { - const database = this.configService.get('DATABASE'); - const settings = await this.findSettings(); - - if (events.call) { - this.logger.verbose('Listening event: call'); - const call = events.call[0]; - - if (settings?.reject_call && call.status == 'offer') { - this.logger.verbose('Rejecting call'); - this.client.rejectCall(call.id, call.from); - } - - if (settings?.msg_call.trim().length > 0 && call.status == 'offer') { - this.logger.verbose('Sending message in call'); - const msg = await this.client.sendMessage(call.from, { - text: settings.msg_call, - }); - - this.logger.verbose('Sending data to event messages.upsert'); - this.client.ev.emit('messages.upsert', { - messages: [msg], - type: 'notify', - }); - } - - this.logger.verbose('Sending data to webhook in event CALL'); - this.sendDataWebhook(Events.CALL, call); - } - - if (events['connection.update']) { - this.logger.verbose('Listening event: connection.update'); - this.connectionUpdate(events['connection.update']); - } - - if (events['creds.update']) { - this.logger.verbose('Listening event: creds.update'); - this.instance.authState.saveCreds(); - } - - if (events['messaging-history.set']) { - this.logger.verbose('Listening event: messaging-history.set'); - const payload = events['messaging-history.set']; - this.messageHandle['messaging-history.set'](payload, database); - } - - if (events['messages.upsert']) { - this.logger.verbose('Listening event: messages.upsert'); - const payload = events['messages.upsert']; - this.messageHandle['messages.upsert'](payload, database, settings); - } - - if (events['messages.update']) { - this.logger.verbose('Listening event: messages.update'); - const payload = events['messages.update']; - this.messageHandle['messages.update'](payload, database, settings); - } - - if (events['presence.update']) { - this.logger.verbose('Listening event: presence.update'); - const payload = events['presence.update']; - - if (settings.groups_ignore && payload.id.includes('@g.us')) { - this.logger.verbose('group ignored'); - return; - } - this.sendDataWebhook(Events.PRESENCE_UPDATE, payload); - } - - if (!settings?.groups_ignore) { - if (events['groups.upsert']) { - this.logger.verbose('Listening event: groups.upsert'); - const payload = events['groups.upsert']; - this.groupHandler['groups.upsert'](payload); - } - - if (events['groups.update']) { - this.logger.verbose('Listening event: groups.update'); - const payload = events['groups.update']; - this.groupHandler['groups.update'](payload); - } - - if (events['group-participants.update']) { - this.logger.verbose('Listening event: group-participants.update'); - const payload = events['group-participants.update']; - this.groupHandler['group-participants.update'](payload); - } - } - - if (events['chats.upsert']) { - this.logger.verbose('Listening event: chats.upsert'); - const payload = events['chats.upsert']; - this.chatHandle['chats.upsert'](payload, database); - } - - if (events['chats.update']) { - this.logger.verbose('Listening event: chats.update'); - const payload = events['chats.update']; - this.chatHandle['chats.update'](payload); - } - - if (events['chats.delete']) { - this.logger.verbose('Listening event: chats.delete'); - const payload = events['chats.delete']; - this.chatHandle['chats.delete'](payload); - } - - if (events['contacts.upsert']) { - this.logger.verbose('Listening event: contacts.upsert'); - const payload = events['contacts.upsert']; - this.contactHandle['contacts.upsert'](payload, database); - } - - if (events['contacts.update']) { - this.logger.verbose('Listening event: contacts.update'); - const payload = events['contacts.update']; - this.contactHandle['contacts.update'](payload, database); - } - } - }); - } - - // Check if the number is MX or AR - private formatMXOrARNumber(jid: string): string { - const countryCode = jid.substring(0, 2); - - if (Number(countryCode) === 52 || Number(countryCode) === 54) { - if (jid.length === 13) { - const number = countryCode + jid.substring(3); - return number; - } - - return jid; - } - return jid; - } - - // Check if the number is br - private formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } - return jid; - } else { - return jid; - } - } - - private createJid(number: string): string { - this.logger.verbose('Creating jid with number: ' + number); - - if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { - this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return number; + backgroundColor: message['status'].option.backgroundColor, + font: message['status'].option.font, + statusJidList: message['status'].option.statusJidList, + } as unknown as MiscMessageGenerationOptions, + ); } - if (number.includes('@broadcast')) { - this.logger.verbose('Number already contains @broadcast'); - return number; - } - - number = number - ?.replace(/\s/g, '') - .replace(/\+/g, '') - .replace(/\(/g, '') - .replace(/\)/g, '') - .split(':')[0] - .split('@')[0]; - - if (number.includes('-') && number.length >= 24) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = number.replace(/\D/g, ''); - - if (number.length >= 18) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); - return `${number}@s.whatsapp.net`; - } - - public async profilePicture(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile picture with jid: ' + jid); - try { - this.logger.verbose('Getting profile picture url'); - return { - wuid: jid, - profilePictureUrl: await this.client.profilePictureUrl(jid, 'image'), - }; - } catch (error) { - this.logger.verbose('Profile picture not found'); - return { - wuid: jid, - profilePictureUrl: null, - }; - } - } - - public async getStatus(number: string) { - const jid = this.createJid(number); - - this.logger.verbose('Getting profile status with jid:' + jid); - try { - this.logger.verbose('Getting status'); - return { - wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, - }; - } catch (error) { - this.logger.verbose('Status not found'); - return { - wuid: jid, - status: null, - }; - } - } - - public async fetchProfile(instanceName: string, number?: string) { - const jid = number ? this.createJid(number) : this.client?.user?.id; - - this.logger.verbose('Getting profile with jid: ' + jid); - try { - this.logger.verbose('Getting profile info'); - const business = await this.fetchBusinessProfile(jid); - - if (number) { - const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); - const picture = await this.profilePicture(jid); - const status = await this.getStatus(jid); - - return { - wuid: jid, - name: info?.name, - numberExists: info?.exists, - picture: picture?.profilePictureUrl, - status: status?.status, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } else { - const info = await waMonitor.instanceInfo(instanceName); - - return { - wuid: jid, - name: info?.instance?.profileName, - numberExists: true, - picture: info?.instance?.profilePictureUrl, - status: info?.instance?.profileStatus, - isBusiness: business.isBusiness, - email: business?.email, - description: business?.description, - website: business?.website?.shift(), - }; - } - } catch (error) { - this.logger.verbose('Profile not found'); - return { - wuid: jid, - name: null, - picture: null, - status: null, - os: null, - isBusiness: false, - }; - } - } - - private async sendMessageWithTyping(number: string, message: T, options?: Options) { - this.logger.verbose('Sending message with typing'); - - const numberWA = await this.whatsappNumber({ numbers: [number] }); - const isWA = numberWA[0]; - - if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { - throw new BadRequestException(isWA); - } - - const sender = isWA.jid; - - try { - if (options?.delay) { - this.logger.verbose('Delaying message'); - - await this.client.presenceSubscribe(sender); - this.logger.verbose('Subscribing to presence'); - - await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); - this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); - - await delay(options.delay); - this.logger.verbose('Set delay: ' + options.delay); - - await this.client.sendPresenceUpdate('paused', sender); - this.logger.verbose('Sending presence update: paused'); - } - - const linkPreview = options?.linkPreview != false ? undefined : false; - - let quoted: WAMessage; - - if (options?.quoted) { - const m = options?.quoted; - - const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - quoted = msg; - this.logger.verbose('Quoted message'); - } - - let mentions: string[]; - if (isJidGroup(sender)) { - try { - const groupMetadata = await this.client.groupMetadata(sender); - - if (!groupMetadata) { - throw new NotFoundException('Group not found'); - } - - if (options?.mentions) { - this.logger.verbose('Mentions defined'); - - if (options.mentions?.everyOne) { - this.logger.verbose('Mentions everyone'); - - this.logger.verbose('Getting group metadata'); - mentions = groupMetadata.participants.map((participant) => participant.id); - this.logger.verbose('Getting group metadata for mentions'); - } else if (options.mentions?.mentioned?.length) { - this.logger.verbose('Mentions manually defined'); - mentions = options.mentions.mentioned.map((mention) => { - const jid = this.createJid(mention); - if (isJidGroup(jid)) { - return null; - // throw new BadRequestException('Mentions must be a number'); - } - return jid; - }); - } - } - } catch (error) { - throw new NotFoundException('Group not found'); - } - } - - const messageSent = await (async () => { - const option = { - quoted, - }; - - if ( - !message['audio'] && - !message['poll'] && - !message['sticker'] && - !message['conversation'] && - sender !== 'status@broadcast' - ) { - if (!message['audio']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - forward: { - key: { remoteJid: this.instance.wuid, fromMe: true }, - message, - }, - mentions, - }, - option as unknown as MiscMessageGenerationOptions, - ); - } - } - - if (message['conversation']) { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - { - text: message['conversation'], - mentions, - linkPreview: linkPreview, - } as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - } - - if (sender === 'status@broadcast') { - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message['status'].content as unknown as AnyMessageContent, - { - backgroundColor: message['status'].option.backgroundColor, - font: message['status'].option.font, - statusJidList: message['status'].option.statusJidList, - } as unknown as MiscMessageGenerationOptions, - ); - } - - this.logger.verbose('Sending message'); - return await this.client.sendMessage( - sender, - message as unknown as AnyMessageContent, - option as unknown as MiscMessageGenerationOptions, - ); - })(); - - const messageRaw: MessageRaw = { - key: messageSent.key, - pushName: messageSent.pushName, - message: { ...messageSent.message }, - messageType: getContentType(messageSent.message), - messageTimestamp: messageSent.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(messageSent.key.id), - }; - - this.logger.log(messageRaw); - - this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); - await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - - // if (this.localChatwoot.enabled) { - // this.chatwootService.eventWhatsapp( - // Events.SEND_MESSAGE, - // { instanceName: this.instance.name }, - // messageRaw, - // ); - // } - - this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, - ); - - return messageSent; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - // Instance Controller - public get connectionStatus() { - this.logger.verbose('Getting connection status'); - return this.stateConnection; - } - - // Send Message Controller - public async textMessage(data: SendTextDto) { - this.logger.verbose('Sending text message'); - return await this.sendMessageWithTyping( - data.number, - { - conversation: data.textMessage.text, - }, - data?.options, + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + message as unknown as AnyMessageContent, + option as unknown as MiscMessageGenerationOptions, ); + })(); + + const messageRaw: MessageRaw = { + key: messageSent.key, + pushName: messageSent.pushName, + message: { ...messageSent.message }, + messageType: getContentType(messageSent.message), + messageTimestamp: messageSent.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(messageSent.key.id), + }; + + this.logger.log(messageRaw); + + this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); + await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); + + // if (this.localChatwoot.enabled) { + // this.chatwootService.eventWhatsapp( + // Events.SEND_MESSAGE, + // { instanceName: this.instance.name }, + // messageRaw, + // ); + // } + + this.logger.verbose('Inserting message in database'); + await this.repository.message.insert( + [messageRaw], + this.instance.name, + this.configService.get('DATABASE').SAVE_DATA.NEW_MESSAGE, + ); + + return messageSent; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + // Instance Controller + public get connectionStatus() { + this.logger.verbose('Getting connection status'); + return this.stateConnection; + } + + // Send Message Controller + public async textMessage(data: SendTextDto) { + this.logger.verbose('Sending text message'); + return await this.sendMessageWithTyping( + data.number, + { + conversation: data.textMessage.text, + }, + data?.options, + ); + } + + public async pollMessage(data: SendPollDto) { + this.logger.verbose('Sending poll message'); + return await this.sendMessageWithTyping( + data.number, + { + poll: { + name: data.pollMessage.name, + selectableCount: data.pollMessage.selectableCount, + values: data.pollMessage.values, + }, + }, + data?.options, + ); + } + + private async formatStatusMessage(status: StatusMessage) { + this.logger.verbose('Formatting status message'); + + if (!status.type) { + throw new BadRequestException('Type is required'); } - public async pollMessage(data: SendPollDto) { - this.logger.verbose('Sending poll message'); - return await this.sendMessageWithTyping( - data.number, - { - poll: { - name: data.pollMessage.name, - selectableCount: data.pollMessage.selectableCount, - values: data.pollMessage.values, - }, - }, - data?.options, + if (!status.content) { + throw new BadRequestException('Content is required'); + } + + if (status.allContacts) { + this.logger.verbose('All contacts defined as true'); + + this.logger.verbose('Getting contacts from database'); + const contacts = await this.repository.contact.find({ + where: { owner: this.instance.name }, + }); + + if (!contacts.length) { + throw new BadRequestException('Contacts not found'); + } + + this.logger.verbose('Getting contacts with push name'); + status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); + + this.logger.verbose(status.statusJidList); + } + + if (!status.statusJidList?.length && !status.allContacts) { + throw new BadRequestException('StatusJidList is required'); + } + + if (status.type === 'text') { + this.logger.verbose('Type defined as text'); + + if (!status.backgroundColor) { + throw new BadRequestException('Background color is required'); + } + + if (!status.font) { + throw new BadRequestException('Font is required'); + } + + return { + content: { + text: status.content, + }, + option: { + backgroundColor: status.backgroundColor, + font: status.font, + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'image') { + this.logger.verbose('Type defined as image'); + + return { + content: { + image: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'video') { + this.logger.verbose('Type defined as video'); + + return { + content: { + video: { + url: status.content, + }, + caption: status.caption, + }, + option: { + statusJidList: status.statusJidList, + }, + }; + } + if (status.type === 'audio') { + this.logger.verbose('Type defined as audio'); + + this.logger.verbose('Processing audio'); + const convert = await this.processAudio(status.content, 'status@broadcast'); + if (typeof convert === 'string') { + this.logger.verbose('Audio processed'); + const audio = fs.readFileSync(convert).toString('base64'); + + const result = { + content: { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + option: { + statusJidList: status.statusJidList, + }, + }; + + fs.unlinkSync(convert); + + return result; + } else { + throw new InternalServerErrorException(convert); + } + } + + throw new BadRequestException('Type not found'); + } + + public async statusMessage(data: SendStatusDto) { + this.logger.verbose('Sending status message'); + const status = await this.formatStatusMessage(data.statusMessage); + + return await this.sendMessageWithTyping('status@broadcast', { + status, + }); + } + + private async prepareMediaMessage(mediaMessage: MediaMessage) { + try { + this.logger.verbose('Preparing media message'); + const prepareMedia = await prepareWAMessageMedia( + { + [mediaMessage.mediatype]: isURL(mediaMessage.media) + ? { url: mediaMessage.media } + : Buffer.from(mediaMessage.media, 'base64'), + } as any, + { upload: this.client.waUploadToServer }, + ); + + const mediaType = mediaMessage.mediatype + 'Message'; + this.logger.verbose('Media type: ' + mediaType); + + if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { + this.logger.verbose('If media type is document and file name is not defined then'); + const regex = new RegExp(/.*\/(.+?)\./); + const arrayMatch = regex.exec(mediaMessage.media); + mediaMessage.fileName = arrayMatch[1]; + this.logger.verbose('File name: ' + mediaMessage.fileName); + } + + let mimetype: string; + + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + } else { + mimetype = getMIMEType(mediaMessage.fileName); + } + + this.logger.verbose('Mimetype: ' + mimetype); + + prepareMedia[mediaType].caption = mediaMessage?.caption; + prepareMedia[mediaType].mimetype = mimetype; + prepareMedia[mediaType].fileName = mediaMessage.fileName; + + if (mediaMessage.mediatype === 'video') { + this.logger.verbose('Is media type video then set gif playback as false'); + prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( + readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), ); + prepareMedia[mediaType].gifPlayback = false; + } + + this.logger.verbose('Generating wa message from content'); + return generateWAMessageFromContent( + '', + { [mediaType]: { ...prepareMedia[mediaType] } }, + { userJid: this.instance.wuid }, + ); + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException(error?.toString() || error); + } + } + + private async convertToWebP(image: string, number: string) { + try { + this.logger.verbose('Converting image to WebP to sticker'); + + let imagePath: string; + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to image name: ' + hash); + + const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; + this.logger.verbose('Output path: ' + outputPath); + + if (isBase64(image)) { + this.logger.verbose('Image is base64'); + + const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); + const imageBuffer = Buffer.from(base64Data, 'base64'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } else { + this.logger.verbose('Image is url'); + + const timestamp = new Date().getTime(); + const url = `${image}?timestamp=${timestamp}`; + this.logger.verbose('including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting image from url'); + + const imageBuffer = Buffer.from(response.data, 'binary'); + imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; + this.logger.verbose('Image path: ' + imagePath); + + await sharp(imageBuffer).toFile(imagePath); + this.logger.verbose('Image created'); + } + + await sharp(imagePath).webp().toFile(outputPath); + this.logger.verbose('Image converted to WebP'); + + fs.unlinkSync(imagePath); + this.logger.verbose('Temp image deleted'); + + return outputPath; + } catch (error) { + console.error('Erro ao converter a imagem para WebP:', error); + } + } + + public async mediaSticker(data: SendStickerDto) { + this.logger.verbose('Sending media sticker'); + const convert = await this.convertToWebP(data.stickerMessage.image, data.number); + const result = await this.sendMessageWithTyping( + data.number, + { + sticker: { url: convert }, + }, + data?.options, + ); + + fs.unlinkSync(convert); + this.logger.verbose('Converted image deleted'); + + return result; + } + + public async mediaMessage(data: SendMediaDto) { + this.logger.verbose('Sending media message'); + const generate = await this.prepareMediaMessage(data.mediaMessage); + + return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); + } + + private async processAudio(audio: string, number: string) { + this.logger.verbose('Processing audio'); + let tempAudioPath: string; + let outputAudio: string; + + const hash = `${number}-${new Date().getTime()}`; + this.logger.verbose('Hash to audio name: ' + hash); + + if (isURL(audio)) { + this.logger.verbose('Audio is url'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const timestamp = new Date().getTime(); + const url = `${audio}?timestamp=${timestamp}`; + + this.logger.verbose('Including timestamp in url: ' + url); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + this.logger.verbose('Getting audio from url'); + + fs.writeFileSync(tempAudioPath, response.data); + } else { + this.logger.verbose('Audio is base64'); + + outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; + tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + + this.logger.verbose('Output audio path: ' + outputAudio); + this.logger.verbose('Temp audio path: ' + tempAudioPath); + + const audioBuffer = Buffer.from(audio, 'base64'); + fs.writeFileSync(tempAudioPath, audioBuffer); + this.logger.verbose('Temp audio created'); } - private async formatStatusMessage(status: StatusMessage) { - this.logger.verbose('Formatting status message'); + this.logger.verbose('Converting audio to mp4'); + return new Promise((resolve, reject) => { + exec(`${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, (error) => { + fs.unlinkSync(tempAudioPath); + this.logger.verbose('Temp audio deleted'); - if (!status.type) { - throw new BadRequestException('Type is required'); - } + if (error) reject(error); - if (!status.content) { - throw new BadRequestException('Content is required'); - } + this.logger.verbose('Audio converted to mp4'); + resolve(outputAudio); + }); + }); + } - if (status.allContacts) { - this.logger.verbose('All contacts defined as true'); + public async audioWhatsapp(data: SendAudioDto) { + this.logger.verbose('Sending audio whatsapp'); - this.logger.verbose('Getting contacts from database'); - const contacts = await this.repository.contact.find({ - where: { owner: this.instance.name }, - }); - - if (!contacts.length) { - throw new BadRequestException('Contacts not found'); - } - - this.logger.verbose('Getting contacts with push name'); - status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); - - this.logger.verbose(status.statusJidList); - } - - if (!status.statusJidList?.length && !status.allContacts) { - throw new BadRequestException('StatusJidList is required'); - } - - if (status.type === 'text') { - this.logger.verbose('Type defined as text'); - - if (!status.backgroundColor) { - throw new BadRequestException('Background color is required'); - } - - if (!status.font) { - throw new BadRequestException('Font is required'); - } - - return { - content: { - text: status.content, - }, - option: { - backgroundColor: status.backgroundColor, - font: status.font, - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'image') { - this.logger.verbose('Type defined as image'); - - return { - content: { - image: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'video') { - this.logger.verbose('Type defined as video'); - - return { - content: { - video: { - url: status.content, - }, - caption: status.caption, - }, - option: { - statusJidList: status.statusJidList, - }, - }; - } - if (status.type === 'audio') { - this.logger.verbose('Type defined as audio'); - - this.logger.verbose('Processing audio'); - const convert = await this.processAudio(status.content, 'status@broadcast'); - if (typeof convert === 'string') { - this.logger.verbose('Audio processed'); - const audio = fs.readFileSync(convert).toString('base64'); - - const result = { - content: { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - option: { - statusJidList: status.statusJidList, - }, - }; - - fs.unlinkSync(convert); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - throw new BadRequestException('Type not found'); + if (!data.options?.encoding && data.options?.encoding !== false) { + data.options.encoding = true; } - public async statusMessage(data: SendStatusDto) { - this.logger.verbose('Sending status message'); - const status = await this.formatStatusMessage(data.statusMessage); - - return await this.sendMessageWithTyping('status@broadcast', { - status, - }); - } - - private async prepareMediaMessage(mediaMessage: MediaMessage) { - try { - this.logger.verbose('Preparing media message'); - const prepareMedia = await prepareWAMessageMedia( - { - [mediaMessage.mediatype]: isURL(mediaMessage.media) - ? { url: mediaMessage.media } - : Buffer.from(mediaMessage.media, 'base64'), - } as any, - { upload: this.client.waUploadToServer }, - ); - - const mediaType = mediaMessage.mediatype + 'Message'; - this.logger.verbose('Media type: ' + mediaType); - - if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { - this.logger.verbose('If media type is document and file name is not defined then'); - const regex = new RegExp(/.*\/(.+?)\./); - const arrayMatch = regex.exec(mediaMessage.media); - mediaMessage.fileName = arrayMatch[1]; - this.logger.verbose('File name: ' + mediaMessage.fileName); - } - - let mimetype: string; - - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); - } else { - mimetype = getMIMEType(mediaMessage.fileName); - } - - this.logger.verbose('Mimetype: ' + mimetype); - - prepareMedia[mediaType].caption = mediaMessage?.caption; - prepareMedia[mediaType].mimetype = mimetype; - prepareMedia[mediaType].fileName = mediaMessage.fileName; - - if (mediaMessage.mediatype === 'video') { - this.logger.verbose('Is media type video then set gif playback as false'); - prepareMedia[mediaType].jpegThumbnail = Uint8Array.from( - readFileSync(join(process.cwd(), 'public', 'images', 'video-cover.png')), - ); - prepareMedia[mediaType].gifPlayback = false; - } - - this.logger.verbose('Generating wa message from content'); - return generateWAMessageFromContent( - '', - { [mediaType]: { ...prepareMedia[mediaType] } }, - { userJid: this.instance.wuid }, - ); - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException(error?.toString() || error); - } - } - - private async convertToWebP(image: string, number: string) { - try { - this.logger.verbose('Converting image to WebP to sticker'); - - let imagePath: string; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to image name: ' + hash); - - const outputPath = `${join(this.storePath, 'temp', `${hash}.webp`)}`; - this.logger.verbose('Output path: ' + outputPath); - - if (isBase64(image)) { - this.logger.verbose('Image is base64'); - - const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); - const imageBuffer = Buffer.from(base64Data, 'base64'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } else { - this.logger.verbose('Image is url'); - - const timestamp = new Date().getTime(); - const url = `${image}?timestamp=${timestamp}`; - this.logger.verbose('including timestamp in url: ' + url); - - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting image from url'); - - const imageBuffer = Buffer.from(response.data, 'binary'); - imagePath = `${join(this.storePath, 'temp', `temp-${hash}.png`)}`; - this.logger.verbose('Image path: ' + imagePath); - - await sharp(imageBuffer).toFile(imagePath); - this.logger.verbose('Image created'); - } - - await sharp(imagePath).webp().toFile(outputPath); - this.logger.verbose('Image converted to WebP'); - - fs.unlinkSync(imagePath); - this.logger.verbose('Temp image deleted'); - - return outputPath; - } catch (error) { - console.error('Erro ao converter a imagem para WebP:', error); - } - } - - public async mediaSticker(data: SendStickerDto) { - this.logger.verbose('Sending media sticker'); - const convert = await this.convertToWebP(data.stickerMessage.image, data.number); - const result = await this.sendMessageWithTyping( - data.number, - { - sticker: { url: convert }, - }, - data?.options, + if (data.options?.encoding) { + const convert = await this.processAudio(data.audioMessage.audio, data.number); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + const result = this.sendMessageWithTyping( + data.number, + { + audio: Buffer.from(audio, 'base64'), + ptt: true, + mimetype: 'audio/mp4', + }, + { presence: 'recording', delay: data?.options?.delay }, ); fs.unlinkSync(convert); - this.logger.verbose('Converted image deleted'); + this.logger.verbose('Converted audio deleted'); return result; + } else { + throw new InternalServerErrorException(convert); + } } - public async mediaMessage(data: SendMediaDto) { - this.logger.verbose('Sending media message'); - const generate = await this.prepareMediaMessage(data.mediaMessage); + return await this.sendMessageWithTyping( + data.number, + { + audio: isURL(data.audioMessage.audio) + ? { url: data.audioMessage.audio } + : Buffer.from(data.audioMessage.audio, 'base64'), + ptt: true, + mimetype: 'audio/ogg; codecs=opus', + }, + { presence: 'recording', delay: data?.options?.delay }, + ); + } - return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); + public async buttonMessage(data: SendButtonDto) { + this.logger.verbose('Sending button message'); + const embeddedMedia: any = {}; + let mediatype = 'TEXT'; + + if (data.buttonMessage?.mediaMessage) { + mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; + embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; + const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); + embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; + embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; } - private async processAudio(audio: string, number: string) { - this.logger.verbose('Processing audio'); - let tempAudioPath: string; - let outputAudio: string; + const btnItems = { + text: data.buttonMessage.buttons.map((btn) => btn.buttonText), + ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + }; - const hash = `${number}-${new Date().getTime()}`; - this.logger.verbose('Hash to audio name: ' + hash); + if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { + throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); + } - if (isURL(audio)) { - this.logger.verbose('Audio is url'); + return await this.sendMessageWithTyping( + data.number, + { + buttonsMessage: { + text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, + contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, + footerText: data.buttonMessage?.footerText, + buttons: data.buttonMessage.buttons.map((button) => { + return { + buttonText: { + displayText: button.buttonText, + }, + buttonId: button.buttonId, + type: 1, + }; + }), + headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], + [embeddedMedia?.mediaKey]: embeddedMedia?.message, + }, + }, + data?.options, + ); + } - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; + public async locationMessage(data: SendLocationDto) { + this.logger.verbose('Sending location message'); + return await this.sendMessageWithTyping( + data.number, + { + locationMessage: { + degreesLatitude: data.locationMessage.latitude, + degreesLongitude: data.locationMessage.longitude, + name: data.locationMessage?.name, + address: data.locationMessage?.address, + }, + }, + data?.options, + ); + } - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); + public async listMessage(data: SendListDto) { + this.logger.verbose('Sending list message'); + return await this.sendMessageWithTyping( + data.number, + { + listMessage: { + title: data.listMessage.title, + description: data.listMessage.description, + buttonText: data.listMessage?.buttonText, + footerText: data.listMessage?.footerText, + sections: data.listMessage.sections, + listType: 1, + }, + }, + data?.options, + ); + } - const timestamp = new Date().getTime(); - const url = `${audio}?timestamp=${timestamp}`; + public async contactMessage(data: SendContactDto) { + this.logger.verbose('Sending contact message'); + const message: proto.IMessage = {}; - this.logger.verbose('Including timestamp in url: ' + url); + const vcard = (contact: ContactMessage) => { + this.logger.verbose('Creating vcard'); + let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; - const response = await axios.get(url, { responseType: 'arraybuffer' }); - this.logger.verbose('Getting audio from url'); + if (contact.organization) { + this.logger.verbose('Organization defined'); + result += `ORG:${contact.organization};\n`; + } - fs.writeFileSync(tempAudioPath, response.data); + if (contact.email) { + this.logger.verbose('Email defined'); + result += `EMAIL:${contact.email}\n`; + } + + if (contact.url) { + this.logger.verbose('Url defined'); + result += `URL:${contact.url}\n`; + } + + if (!contact.wuid) { + this.logger.verbose('Wuid defined'); + contact.wuid = this.createJid(contact.phoneNumber); + } + + result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; + + this.logger.verbose('Vcard created'); + return result; + }; + + if (data.contactMessage.length === 1) { + message.contactMessage = { + displayName: data.contactMessage[0].fullName, + vcard: vcard(data.contactMessage[0]), + }; + } else { + message.contactsArrayMessage = { + displayName: `${data.contactMessage.length} contacts`, + contacts: data.contactMessage.map((contact) => { + return { + displayName: contact.fullName, + vcard: vcard(contact), + }; + }), + }; + } + + return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + } + + public async reactionMessage(data: SendReactionDto) { + this.logger.verbose('Sending reaction message'); + return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { + reactionMessage: { + key: data.reactionMessage.key, + text: data.reactionMessage.reaction, + }, + }); + } + + // Chat Controller + public async whatsappNumber(data: WhatsAppNumberDto) { + this.logger.verbose('Getting whatsapp number'); + + const onWhatsapp: OnWhatsAppDto[] = []; + for await (const number of data.numbers) { + let jid = this.createJid(number); + + if (isJidGroup(jid)) { + const group = await this.findGroup({ groupJid: jid }, 'inner'); + + if (!group) throw new BadRequestException('Group not found'); + + onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); + } else { + jid = !jid.startsWith('+') ? `+${jid}` : jid; + const verify = await this.client.onWhatsApp(jid); + + const result = verify[0]; + + if (!result) { + onWhatsapp.push(new OnWhatsAppDto(jid, false)); } else { - this.logger.verbose('Audio is base64'); - - outputAudio = `${join(this.storePath, 'temp', `${hash}.mp4`)}`; - tempAudioPath = `${join(this.storePath, 'temp', `temp-${hash}.mp3`)}`; - - this.logger.verbose('Output audio path: ' + outputAudio); - this.logger.verbose('Temp audio path: ' + tempAudioPath); - - const audioBuffer = Buffer.from(audio, 'base64'); - fs.writeFileSync(tempAudioPath, audioBuffer); - this.logger.verbose('Temp audio created'); + onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); } + } + } + return onWhatsapp; + } + + public async markMessageAsRead(data: ReadMessageDto) { + this.logger.verbose('Marking message as read'); + try { + const keys: proto.IMessageKey[] = []; + data.read_messages.forEach((read) => { + if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { + keys.push({ + remoteJid: read.remoteJid, + fromMe: read.fromMe, + id: read.id, + }); + } + }); + await this.client.readMessages(keys); + return { message: 'Read messages', read: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Read messages fail', error.toString()); + } + } + + public async archiveChat(data: ArchiveChatDto) { + this.logger.verbose('Archiving chat'); + try { + data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); + await this.client.chatModify( + { + archive: data.archive, + lastMessages: [data.lastMessage], + }, + data.lastMessage.key.remoteJid, + ); + + return { + chatId: data.lastMessage.key.remoteJid, + archived: true, + }; + } catch (error) { + throw new InternalServerErrorException({ + archived: false, + message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], + }); + } + } + + public async deleteMessage(del: DeleteMessage) { + this.logger.verbose('Deleting message'); + try { + return await this.client.sendMessage(del.remoteJid, { delete: del }); + } catch (error) { + throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); + } + } + + public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { + this.logger.verbose('Getting base64 from media message'); + try { + const m = data?.message; + const convertToMp4 = data?.convertToMp4 ?? false; + + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + for (const subtype of MessageSubtype) { + if (msg.message[subtype]) { + msg.message = msg.message[subtype].message; + } + } + + let mediaMessage: any; + let mediaType: string; + + for (const type of TypeMediaMessage) { + mediaMessage = msg.message[type]; + if (mediaMessage) { + mediaType = type; + break; + } + } + + if (!mediaMessage) { + throw 'The message is not of the media type'; + } + + if (typeof mediaMessage['mediaKey'] === 'object') { + msg.message = JSON.parse(JSON.stringify(msg.message)); + } + + this.logger.verbose('Downloading media message'); + const buffer = await downloadMediaMessage( + { key: msg?.key, message: msg?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }), + reuploadRequest: this.client.updateMediaMessage, + }, + ); + const typeMessage = getContentType(msg.message); + + if (convertToMp4 && typeMessage === 'audioMessage') { this.logger.verbose('Converting audio to mp4'); - return new Promise((resolve, reject) => { - exec(`${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, (error) => { - fs.unlinkSync(tempAudioPath); - this.logger.verbose('Temp audio deleted'); + const number = msg.key.remoteJid.split('@')[0]; + const convert = await this.processAudio(buffer.toString('base64'), number); - if (error) reject(error); + if (typeof convert === 'string') { + const audio = fs.readFileSync(convert).toString('base64'); + this.logger.verbose('Audio converted to mp4'); - this.logger.verbose('Audio converted to mp4'); - resolve(outputAudio); - }); - }); - } - - public async audioWhatsapp(data: SendAudioDto) { - this.logger.verbose('Sending audio whatsapp'); - - if (!data.options?.encoding && data.options?.encoding !== false) { - data.options.encoding = true; - } - - if (data.options?.encoding) { - const convert = await this.processAudio(data.audioMessage.audio, data.number); - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - const result = this.sendMessageWithTyping( - data.number, - { - audio: Buffer.from(audio, 'base64'), - ptt: true, - mimetype: 'audio/mp4', - }, - { presence: 'recording', delay: data?.options?.delay }, - ); - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - return result; - } else { - throw new InternalServerErrorException(convert); - } - } - - return await this.sendMessageWithTyping( - data.number, - { - audio: isURL(data.audioMessage.audio) - ? { url: data.audioMessage.audio } - : Buffer.from(data.audioMessage.audio, 'base64'), - ptt: true, - mimetype: 'audio/ogg; codecs=opus', + const result = { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], }, - { presence: 'recording', delay: data?.options?.delay }, - ); - } + mimetype: 'audio/mp4', + base64: Buffer.from(audio, 'base64').toString('base64'), + }; - public async buttonMessage(data: SendButtonDto) { - this.logger.verbose('Sending button message'); - const embeddedMedia: any = {}; - let mediatype = 'TEXT'; + fs.unlinkSync(convert); + this.logger.verbose('Converted audio deleted'); - if (data.buttonMessage?.mediaMessage) { - mediatype = data.buttonMessage.mediaMessage?.mediatype.toUpperCase() ?? 'TEXT'; - embeddedMedia.mediaKey = mediatype.toLowerCase() + 'Message'; - const generate = await this.prepareMediaMessage(data.buttonMessage.mediaMessage); - embeddedMedia.message = generate.message[embeddedMedia.mediaKey]; - embeddedMedia.contentText = `*${data.buttonMessage.title}*\n\n${data.buttonMessage.description}`; + this.logger.verbose('Media message downloaded'); + return result; } + } - const btnItems = { - text: data.buttonMessage.buttons.map((btn) => btn.buttonText), - ids: data.buttonMessage.buttons.map((btn) => btn.buttonId), + this.logger.verbose('Media message downloaded'); + return { + mediaType, + fileName: mediaMessage['fileName'], + caption: mediaMessage['caption'], + size: { + fileLength: mediaMessage['fileLength'], + height: mediaMessage['height'], + width: mediaMessage['width'], + }, + mimetype: mediaMessage['mimetype'], + base64: buffer.toString('base64'), + }; + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + + public async fetchContacts(query: ContactQuery) { + this.logger.verbose('Fetching contacts'); + if (query?.where) { + query.where.owner = this.instance.name; + if (query.where?.id) { + query.where.id = this.createJid(query.where.id); + } + } else { + query = { + where: { + owner: this.instance.name, + }, + }; + } + return await this.repository.contact.find(query); + } + + public async fetchMessages(query: MessageQuery) { + this.logger.verbose('Fetching messages'); + if (query?.where) { + if (query.where?.key?.remoteJid) { + query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.message.find(query); + } + + public async fetchStatusMessage(query: MessageUpQuery) { + this.logger.verbose('Fetching status messages'); + if (query?.where) { + if (query.where?.remoteJid) { + query.where.remoteJid = this.createJid(query.where.remoteJid); + } + query.where.owner = this.instance.name; + } else { + query = { + where: { + owner: this.instance.name, + }, + limit: query?.limit, + }; + } + return await this.repository.messageUpdate.find(query); + } + + public async fetchChats() { + this.logger.verbose('Fetching chats'); + return await this.repository.chat.find({ where: { owner: this.instance.name } }); + } + + public async fetchPrivacySettings() { + this.logger.verbose('Fetching privacy settings'); + return await this.client.fetchPrivacySettings(); + } + + public async updatePrivacySettings(settings: PrivacySettingDto) { + this.logger.verbose('Updating privacy settings'); + try { + await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); + this.logger.verbose('Read receipts privacy updated'); + + await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); + this.logger.verbose('Profile picture privacy updated'); + + await this.client.updateStatusPrivacy(settings.privacySettings.status); + this.logger.verbose('Status privacy updated'); + + await this.client.updateOnlinePrivacy(settings.privacySettings.online); + this.logger.verbose('Online privacy updated'); + + await this.client.updateLastSeenPrivacy(settings.privacySettings.last); + this.logger.verbose('Last seen privacy updated'); + + await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); + this.logger.verbose('Groups add privacy updated'); + + this.client?.ws?.close(); + + return { + update: 'success', + data: { + readreceipts: settings.privacySettings.readreceipts, + profile: settings.privacySettings.profile, + status: settings.privacySettings.status, + online: settings.privacySettings.online, + last: settings.privacySettings.last, + groupadd: settings.privacySettings.groupadd, + }, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating privacy settings', error.toString()); + } + } + + public async fetchBusinessProfile(number: string): Promise { + this.logger.verbose('Fetching business profile'); + try { + const jid = number ? this.createJid(number) : this.instance.wuid; + + const profile = await this.client.getBusinessProfile(jid); + this.logger.verbose('Trying to get business profile'); + + if (!profile) { + const info = await this.whatsappNumber({ numbers: [jid] }); + + return { + isBusiness: false, + message: 'Not is business profile', + ...info?.shift(), + }; + } + + this.logger.verbose('Business profile fetched'); + return { + isBusiness: true, + ...profile, + }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileName(name: string) { + this.logger.verbose('Updating profile name to ' + name); + try { + await this.client.updateProfileName(name); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile name', error.toString()); + } + } + + public async updateProfileStatus(status: string) { + this.logger.verbose('Updating profile status to: ' + status); + try { + await this.client.updateProfileStatus(status); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile status', error.toString()); + } + } + + public async updateProfilePicture(picture: string) { + this.logger.verbose('Updating profile picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(this.instance.wuid, pic); + this.logger.verbose('Profile picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating profile picture', error.toString()); + } + } + + public async removeProfilePicture() { + this.logger.verbose('Removing profile picture'); + try { + await this.client.removeProfilePicture(this.instance.wuid); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error removing profile picture', error.toString()); + } + } + + // Group + public async createGroup(create: CreateGroupDto) { + this.logger.verbose('Creating group: ' + create.subject); + try { + const participants = create.participants.map((p) => this.createJid(p)); + const { id } = await this.client.groupCreate(create.subject, participants); + this.logger.verbose('Group created: ' + id); + + if (create?.description) { + this.logger.verbose('Updating group description: ' + create.description); + await this.client.groupUpdateDescription(id, create.description); + } + + if (create?.promoteParticipants) { + this.logger.verbose('Prometing group participants: ' + create.description); + await this.updateGParticipant({ + groupJid: id, + action: 'promote', + participants: participants, + }); + } + + const group = await this.client.groupMetadata(id); + this.logger.verbose('Getting group metadata'); + + return group; + } catch (error) { + this.logger.error(error); + throw new InternalServerErrorException('Error creating group', error.toString()); + } + } + + public async updateGroupPicture(picture: GroupPictureDto) { + this.logger.verbose('Updating group picture'); + try { + let pic: WAMediaUpload; + if (isURL(picture.image)) { + this.logger.verbose('Picture is url'); + + const timestamp = new Date().getTime(); + const url = `${picture.image}?timestamp=${timestamp}`; + this.logger.verbose('Including timestamp in url: ' + url); + + pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; + this.logger.verbose('Getting picture from url'); + } else if (isBase64(picture.image)) { + this.logger.verbose('Picture is base64'); + pic = Buffer.from(picture.image, 'base64'); + this.logger.verbose('Getting picture from base64'); + } else { + throw new BadRequestException('"profilePicture" must be a url or a base64'); + } + await this.client.updateProfilePicture(picture.groupJid, pic); + this.logger.verbose('Group picture updated'); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error update group picture', error.toString()); + } + } + + public async updateGroupSubject(data: GroupSubjectDto) { + this.logger.verbose('Updating group subject to: ' + data.subject); + try { + await this.client.groupUpdateSubject(data.groupJid, data.subject); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group subject', error.toString()); + } + } + + public async updateGroupDescription(data: GroupDescriptionDto) { + this.logger.verbose('Updating group description to: ' + data.description); + try { + await this.client.groupUpdateDescription(data.groupJid, data.description); + + return { update: 'success' }; + } catch (error) { + throw new InternalServerErrorException('Error updating group description', error.toString()); + } + } + + public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { + this.logger.verbose('Fetching group'); + try { + return await this.client.groupMetadata(id.groupJid); + } catch (error) { + if (reply === 'inner') { + return; + } + throw new NotFoundException('Error fetching group', error.toString()); + } + } + + public async fetchAllGroups(getParticipants: GetParticipant) { + this.logger.verbose('Fetching all groups'); + try { + const fetch = Object.values(await this.client.groupFetchAllParticipating()); + + const groups = fetch.map((group) => { + const result = { + id: group.id, + subject: group.subject, + subjectOwner: group.subjectOwner, + subjectTime: group.subjectTime, + size: group.size, + creation: group.creation, + owner: group.owner, + desc: group.desc, + descId: group.descId, + restrict: group.restrict, + announce: group.announce, }; - if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { - throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); + if (getParticipants.getParticipants == 'true') { + result['participants'] = group.participants; } - return await this.sendMessageWithTyping( - data.number, - { - buttonsMessage: { - text: !embeddedMedia?.mediaKey ? data.buttonMessage.title : undefined, - contentText: embeddedMedia?.contentText ?? data.buttonMessage.description, - footerText: data.buttonMessage?.footerText, - buttons: data.buttonMessage.buttons.map((button) => { - return { - buttonText: { - displayText: button.buttonText, - }, - buttonId: button.buttonId, - type: 1, - }; - }), - headerType: proto.Message.ButtonsMessage.HeaderType[mediatype], - [embeddedMedia?.mediaKey]: embeddedMedia?.message, - }, - }, - data?.options, - ); + return result; + }); + + return groups; + } catch (error) { + throw new NotFoundException('Error fetching group', error.toString()); } + } - public async locationMessage(data: SendLocationDto) { - this.logger.verbose('Sending location message'); - return await this.sendMessageWithTyping( - data.number, - { - locationMessage: { - degreesLatitude: data.locationMessage.latitude, - degreesLongitude: data.locationMessage.longitude, - name: data.locationMessage?.name, - address: data.locationMessage?.address, - }, - }, - data?.options, - ); + public async inviteCode(id: GroupJid) { + this.logger.verbose('Fetching invite code for group: ' + id.groupJid); + try { + const code = await this.client.groupInviteCode(id.groupJid); + return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; + } catch (error) { + throw new NotFoundException('No invite code', error.toString()); } + } - public async listMessage(data: SendListDto) { - this.logger.verbose('Sending list message'); - return await this.sendMessageWithTyping( - data.number, - { - listMessage: { - title: data.listMessage.title, - description: data.listMessage.description, - buttonText: data.listMessage?.buttonText, - footerText: data.listMessage?.footerText, - sections: data.listMessage.sections, - listType: 1, - }, - }, - data?.options, - ); + public async inviteInfo(id: GroupInvite) { + this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); + try { + return await this.client.groupGetInviteInfo(id.inviteCode); + } catch (error) { + throw new NotFoundException('No invite info', id.inviteCode); } + } - public async contactMessage(data: SendContactDto) { - this.logger.verbose('Sending contact message'); - const message: proto.IMessage = {}; + public async sendInvite(id: GroupSendInvite) { + this.logger.verbose('Sending invite for group: ' + id.groupJid); + try { + const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); + this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); - const vcard = (contact: ContactMessage) => { - this.logger.verbose('Creating vcard'); - let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; + const inviteUrl = inviteCode.inviteUrl; + this.logger.verbose('Invite url: ' + inviteUrl); - if (contact.organization) { - this.logger.verbose('Organization defined'); - result += `ORG:${contact.organization};\n`; - } + const numbers = id.numbers.map((number) => this.createJid(number)); + const description = id.description ?? ''; - if (contact.email) { - this.logger.verbose('Email defined'); - result += `EMAIL:${contact.email}\n`; - } + const msg = `${description}\n\n${inviteUrl}`; - if (contact.url) { - this.logger.verbose('Url defined'); - result += `URL:${contact.url}\n`; - } + const message = { + conversation: msg, + }; - if (!contact.wuid) { - this.logger.verbose('Wuid defined'); - contact.wuid = this.createJid(contact.phoneNumber); - } + for await (const number of numbers) { + await this.sendMessageWithTyping(number, message); + } - result += - `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; + this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - this.logger.verbose('Vcard created'); - return result; - }; - - if (data.contactMessage.length === 1) { - message.contactMessage = { - displayName: data.contactMessage[0].fullName, - vcard: vcard(data.contactMessage[0]), - }; - } else { - message.contactsArrayMessage = { - displayName: `${data.contactMessage.length} contacts`, - contacts: data.contactMessage.map((contact) => { - return { - displayName: contact.fullName, - vcard: vcard(contact), - }; - }), - }; - } - - return await this.sendMessageWithTyping(data.number, { ...message }, data?.options); + return { send: true, inviteUrl }; + } catch (error) { + throw new NotFoundException('No send invite'); } + } - public async reactionMessage(data: SendReactionDto) { - this.logger.verbose('Sending reaction message'); - return await this.sendMessageWithTyping(data.reactionMessage.key.remoteJid, { - reactionMessage: { - key: data.reactionMessage.key, - text: data.reactionMessage.reaction, - }, - }); + public async revokeInviteCode(id: GroupJid) { + this.logger.verbose('Revoking invite code for group: ' + id.groupJid); + try { + const inviteCode = await this.client.groupRevokeInvite(id.groupJid); + return { revoked: true, inviteCode }; + } catch (error) { + throw new NotFoundException('Revoke error', error.toString()); } + } - // Chat Controller - public async whatsappNumber(data: WhatsAppNumberDto) { - this.logger.verbose('Getting whatsapp number'); - - const onWhatsapp: OnWhatsAppDto[] = []; - for await (const number of data.numbers) { - let jid = this.createJid(number); - - if (isJidGroup(jid)) { - const group = await this.findGroup({ groupJid: jid }, 'inner'); - - if (!group) throw new BadRequestException('Group not found'); - - onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, group?.subject)); - } else { - jid = !jid.startsWith('+') ? `+${jid}` : jid; - const verify = await this.client.onWhatsApp(jid); - - const result = verify[0]; - - if (!result) { - onWhatsapp.push(new OnWhatsAppDto(jid, false)); - } else { - onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists)); - } - } - } - - return onWhatsapp; + public async findParticipants(id: GroupJid) { + this.logger.verbose('Fetching participants for group: ' + id.groupJid); + try { + const participants = (await this.client.groupMetadata(id.groupJid)).participants; + return { participants }; + } catch (error) { + throw new NotFoundException('No participants', error.toString()); } + } - public async markMessageAsRead(data: ReadMessageDto) { - this.logger.verbose('Marking message as read'); - try { - const keys: proto.IMessageKey[] = []; - data.read_messages.forEach((read) => { - if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { - keys.push({ - remoteJid: read.remoteJid, - fromMe: read.fromMe, - id: read.id, - }); - } - }); - await this.client.readMessages(keys); - return { message: 'Read messages', read: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Read messages fail', error.toString()); - } + public async updateGParticipant(update: GroupUpdateParticipantDto) { + this.logger.verbose('Updating participants'); + try { + const participants = update.participants.map((p) => this.createJid(p)); + const updateParticipants = await this.client.groupParticipantsUpdate( + update.groupJid, + participants, + update.action, + ); + return { updateParticipants: updateParticipants }; + } catch (error) { + throw new BadRequestException('Error updating participants', error.toString()); } + } - public async archiveChat(data: ArchiveChatDto) { - this.logger.verbose('Archiving chat'); - try { - data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); - await this.client.chatModify( - { - archive: data.archive, - lastMessages: [data.lastMessage], - }, - data.lastMessage.key.remoteJid, - ); - - return { - chatId: data.lastMessage.key.remoteJid, - archived: true, - }; - } catch (error) { - throw new InternalServerErrorException({ - archived: false, - message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], - }); - } + public async updateGSetting(update: GroupUpdateSettingDto) { + this.logger.verbose('Updating setting for group: ' + update.groupJid); + try { + const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); + return { updateSetting: updateSetting }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); } + } - public async deleteMessage(del: DeleteMessage) { - this.logger.verbose('Deleting message'); - try { - return await this.client.sendMessage(del.remoteJid, { delete: del }); - } catch (error) { - throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); - } + public async toggleEphemeral(update: GroupToggleEphemeralDto) { + this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); + try { + await this.client.groupToggleEphemeral(update.groupJid, update.expiration); + return { success: true }; + } catch (error) { + throw new BadRequestException('Error updating setting', error.toString()); } + } - public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto) { - this.logger.verbose('Getting base64 from media message'); - try { - const m = data?.message; - const convertToMp4 = data?.convertToMp4 ?? false; - - const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); - - if (!msg) { - throw 'Message not found'; - } - - for (const subtype of MessageSubtype) { - if (msg.message[subtype]) { - msg.message = msg.message[subtype].message; - } - } - - let mediaMessage: any; - let mediaType: string; - - for (const type of TypeMediaMessage) { - mediaMessage = msg.message[type]; - if (mediaMessage) { - mediaType = type; - break; - } - } - - if (!mediaMessage) { - throw 'The message is not of the media type'; - } - - if (typeof mediaMessage['mediaKey'] === 'object') { - msg.message = JSON.parse(JSON.stringify(msg.message)); - } - - this.logger.verbose('Downloading media message'); - const buffer = await downloadMediaMessage( - { key: msg?.key, message: msg?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }), - reuploadRequest: this.client.updateMediaMessage, - }, - ); - const typeMessage = getContentType(msg.message); - - if (convertToMp4 && typeMessage === 'audioMessage') { - this.logger.verbose('Converting audio to mp4'); - const number = msg.key.remoteJid.split('@')[0]; - const convert = await this.processAudio(buffer.toString('base64'), number); - - if (typeof convert === 'string') { - const audio = fs.readFileSync(convert).toString('base64'); - this.logger.verbose('Audio converted to mp4'); - - const result = { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: 'audio/mp4', - base64: Buffer.from(audio, 'base64').toString('base64'), - }; - - fs.unlinkSync(convert); - this.logger.verbose('Converted audio deleted'); - - this.logger.verbose('Media message downloaded'); - return result; - } - } - - this.logger.verbose('Media message downloaded'); - return { - mediaType, - fileName: mediaMessage['fileName'], - caption: mediaMessage['caption'], - size: { - fileLength: mediaMessage['fileLength'], - height: mediaMessage['height'], - width: mediaMessage['width'], - }, - mimetype: mediaMessage['mimetype'], - base64: buffer.toString('base64'), - }; - } catch (error) { - this.logger.error(error); - throw new BadRequestException(error.toString()); - } - } - - public async fetchContacts(query: ContactQuery) { - this.logger.verbose('Fetching contacts'); - if (query?.where) { - query.where.owner = this.instance.name; - if (query.where?.id) { - query.where.id = this.createJid(query.where.id); - } - } else { - query = { - where: { - owner: this.instance.name, - }, - }; - } - return await this.repository.contact.find(query); - } - - public async fetchMessages(query: MessageQuery) { - this.logger.verbose('Fetching messages'); - if (query?.where) { - if (query.where?.key?.remoteJid) { - query.where.key.remoteJid = this.createJid(query.where.key.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.message.find(query); - } - - public async fetchStatusMessage(query: MessageUpQuery) { - this.logger.verbose('Fetching status messages'); - if (query?.where) { - if (query.where?.remoteJid) { - query.where.remoteJid = this.createJid(query.where.remoteJid); - } - query.where.owner = this.instance.name; - } else { - query = { - where: { - owner: this.instance.name, - }, - limit: query?.limit, - }; - } - return await this.repository.messageUpdate.find(query); - } - - public async fetchChats() { - this.logger.verbose('Fetching chats'); - return await this.repository.chat.find({ where: { owner: this.instance.name } }); - } - - public async fetchPrivacySettings() { - this.logger.verbose('Fetching privacy settings'); - return await this.client.fetchPrivacySettings(); - } - - public async updatePrivacySettings(settings: PrivacySettingDto) { - this.logger.verbose('Updating privacy settings'); - try { - await this.client.updateReadReceiptsPrivacy(settings.privacySettings.readreceipts); - this.logger.verbose('Read receipts privacy updated'); - - await this.client.updateProfilePicturePrivacy(settings.privacySettings.profile); - this.logger.verbose('Profile picture privacy updated'); - - await this.client.updateStatusPrivacy(settings.privacySettings.status); - this.logger.verbose('Status privacy updated'); - - await this.client.updateOnlinePrivacy(settings.privacySettings.online); - this.logger.verbose('Online privacy updated'); - - await this.client.updateLastSeenPrivacy(settings.privacySettings.last); - this.logger.verbose('Last seen privacy updated'); - - await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); - this.logger.verbose('Groups add privacy updated'); - - this.client?.ws?.close(); - - return { - update: 'success', - data: { - readreceipts: settings.privacySettings.readreceipts, - profile: settings.privacySettings.profile, - status: settings.privacySettings.status, - online: settings.privacySettings.online, - last: settings.privacySettings.last, - groupadd: settings.privacySettings.groupadd, - }, - }; - } catch (error) { - throw new InternalServerErrorException('Error updating privacy settings', error.toString()); - } - } - - public async fetchBusinessProfile(number: string): Promise { - this.logger.verbose('Fetching business profile'); - try { - const jid = number ? this.createJid(number) : this.instance.wuid; - - const profile = await this.client.getBusinessProfile(jid); - this.logger.verbose('Trying to get business profile'); - - if (!profile) { - const info = await this.whatsappNumber({ numbers: [jid] }); - - return { - isBusiness: false, - message: 'Not is business profile', - ...info?.shift(), - }; - } - - this.logger.verbose('Business profile fetched'); - return { - isBusiness: true, - ...profile, - }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile name', error.toString()); - } - } - - public async updateProfileName(name: string) { - this.logger.verbose('Updating profile name to ' + name); - try { - await this.client.updateProfileName(name); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile name', error.toString()); - } - } - - public async updateProfileStatus(status: string) { - this.logger.verbose('Updating profile status to: ' + status); - try { - await this.client.updateProfileStatus(status); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile status', error.toString()); - } - } - - public async updateProfilePicture(picture: string) { - this.logger.verbose('Updating profile picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(this.instance.wuid, pic); - this.logger.verbose('Profile picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating profile picture', error.toString()); - } - } - - public async removeProfilePicture() { - this.logger.verbose('Removing profile picture'); - try { - await this.client.removeProfilePicture(this.instance.wuid); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error removing profile picture', error.toString()); - } - } - - // Group - public async createGroup(create: CreateGroupDto) { - this.logger.verbose('Creating group: ' + create.subject); - try { - const participants = create.participants.map((p) => this.createJid(p)); - const { id } = await this.client.groupCreate(create.subject, participants); - this.logger.verbose('Group created: ' + id); - - if (create?.description) { - this.logger.verbose('Updating group description: ' + create.description); - await this.client.groupUpdateDescription(id, create.description); - } - - if (create?.promoteParticipants) { - this.logger.verbose('Prometing group participants: ' + create.description); - await this.updateGParticipant({ - groupJid: id, - action: 'promote', - participants: participants, - }); - } - - const group = await this.client.groupMetadata(id); - this.logger.verbose('Getting group metadata'); - - return group; - } catch (error) { - this.logger.error(error); - throw new InternalServerErrorException('Error creating group', error.toString()); - } - } - - public async updateGroupPicture(picture: GroupPictureDto) { - this.logger.verbose('Updating group picture'); - try { - let pic: WAMediaUpload; - if (isURL(picture.image)) { - this.logger.verbose('Picture is url'); - - const timestamp = new Date().getTime(); - const url = `${picture.image}?timestamp=${timestamp}`; - this.logger.verbose('Including timestamp in url: ' + url); - - pic = (await axios.get(url, { responseType: 'arraybuffer' })).data; - this.logger.verbose('Getting picture from url'); - } else if (isBase64(picture.image)) { - this.logger.verbose('Picture is base64'); - pic = Buffer.from(picture.image, 'base64'); - this.logger.verbose('Getting picture from base64'); - } else { - throw new BadRequestException('"profilePicture" must be a url or a base64'); - } - await this.client.updateProfilePicture(picture.groupJid, pic); - this.logger.verbose('Group picture updated'); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error update group picture', error.toString()); - } - } - - public async updateGroupSubject(data: GroupSubjectDto) { - this.logger.verbose('Updating group subject to: ' + data.subject); - try { - await this.client.groupUpdateSubject(data.groupJid, data.subject); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating group subject', error.toString()); - } - } - - public async updateGroupDescription(data: GroupDescriptionDto) { - this.logger.verbose('Updating group description to: ' + data.description); - try { - await this.client.groupUpdateDescription(data.groupJid, data.description); - - return { update: 'success' }; - } catch (error) { - throw new InternalServerErrorException('Error updating group description', error.toString()); - } - } - - public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { - this.logger.verbose('Fetching group'); - try { - return await this.client.groupMetadata(id.groupJid); - } catch (error) { - if (reply === 'inner') { - return; - } - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async fetchAllGroups(getParticipants: GetParticipant) { - this.logger.verbose('Fetching all groups'); - try { - const fetch = Object.values(await this.client.groupFetchAllParticipating()); - - const groups = fetch.map((group) => { - const result = { - id: group.id, - subject: group.subject, - subjectOwner: group.subjectOwner, - subjectTime: group.subjectTime, - size: group.size, - creation: group.creation, - owner: group.owner, - desc: group.desc, - descId: group.descId, - restrict: group.restrict, - announce: group.announce, - }; - - if (getParticipants.getParticipants == 'true') { - result['participants'] = group.participants; - } - - return result; - }); - - return groups; - } catch (error) { - throw new NotFoundException('Error fetching group', error.toString()); - } - } - - public async inviteCode(id: GroupJid) { - this.logger.verbose('Fetching invite code for group: ' + id.groupJid); - try { - const code = await this.client.groupInviteCode(id.groupJid); - return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code }; - } catch (error) { - throw new NotFoundException('No invite code', error.toString()); - } - } - - public async inviteInfo(id: GroupInvite) { - this.logger.verbose('Fetching invite info for code: ' + id.inviteCode); - try { - return await this.client.groupGetInviteInfo(id.inviteCode); - } catch (error) { - throw new NotFoundException('No invite info', id.inviteCode); - } - } - - public async sendInvite(id: GroupSendInvite) { - this.logger.verbose('Sending invite for group: ' + id.groupJid); - try { - const inviteCode = await this.inviteCode({ groupJid: id.groupJid }); - this.logger.verbose('Getting invite code: ' + inviteCode.inviteCode); - - const inviteUrl = inviteCode.inviteUrl; - this.logger.verbose('Invite url: ' + inviteUrl); - - const numbers = id.numbers.map((number) => this.createJid(number)); - const description = id.description ?? ''; - - const msg = `${description}\n\n${inviteUrl}`; - - const message = { - conversation: msg, - }; - - for await (const number of numbers) { - await this.sendMessageWithTyping(number, message); - } - - this.logger.verbose('Invite sent for numbers: ' + numbers.join(', ')); - - return { send: true, inviteUrl }; - } catch (error) { - throw new NotFoundException('No send invite'); - } - } - - public async revokeInviteCode(id: GroupJid) { - this.logger.verbose('Revoking invite code for group: ' + id.groupJid); - try { - const inviteCode = await this.client.groupRevokeInvite(id.groupJid); - return { revoked: true, inviteCode }; - } catch (error) { - throw new NotFoundException('Revoke error', error.toString()); - } - } - - public async findParticipants(id: GroupJid) { - this.logger.verbose('Fetching participants for group: ' + id.groupJid); - try { - const participants = (await this.client.groupMetadata(id.groupJid)).participants; - return { participants }; - } catch (error) { - throw new NotFoundException('No participants', error.toString()); - } - } - - public async updateGParticipant(update: GroupUpdateParticipantDto) { - this.logger.verbose('Updating participants'); - try { - const participants = update.participants.map((p) => this.createJid(p)); - const updateParticipants = await this.client.groupParticipantsUpdate( - update.groupJid, - participants, - update.action, - ); - return { updateParticipants: updateParticipants }; - } catch (error) { - throw new BadRequestException('Error updating participants', error.toString()); - } - } - - public async updateGSetting(update: GroupUpdateSettingDto) { - this.logger.verbose('Updating setting for group: ' + update.groupJid); - try { - const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); - return { updateSetting: updateSetting }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } - - public async toggleEphemeral(update: GroupToggleEphemeralDto) { - this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); - try { - await this.client.groupToggleEphemeral(update.groupJid, update.expiration); - return { success: true }; - } catch (error) { - throw new BadRequestException('Error updating setting', error.toString()); - } - } - - public async leaveGroup(id: GroupJid) { - this.logger.verbose('Leaving group: ' + id.groupJid); - try { - await this.client.groupLeave(id.groupJid); - return { groupJid: id.groupJid, leave: true }; - } catch (error) { - throw new BadRequestException('Unable to leave the group', error.toString()); - } + public async leaveGroup(id: GroupJid) { + this.logger.verbose('Leaving group: ' + id.groupJid); + try { + await this.client.groupLeave(id.groupJid); + return { groupJid: id.groupJid, leave: true }; + } catch (error) { + throw new BadRequestException('Unable to leave the group', error.toString()); } + } } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 59e9d012..d4769a49 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -2,88 +2,88 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys'; export enum Events { - APPLICATION_STARTUP = 'application.startup', - QRCODE_UPDATED = 'qrcode.updated', - CONNECTION_UPDATE = 'connection.update', - STATUS_INSTANCE = 'status.instance', - MESSAGES_SET = 'messages.set', - MESSAGES_UPSERT = 'messages.upsert', - MESSAGES_UPDATE = 'messages.update', - MESSAGES_DELETE = 'messages.delete', - SEND_MESSAGE = 'send.message', - CONTACTS_SET = 'contacts.set', - CONTACTS_UPSERT = 'contacts.upsert', - CONTACTS_UPDATE = 'contacts.update', - PRESENCE_UPDATE = 'presence.update', - CHATS_SET = 'chats.set', - CHATS_UPDATE = 'chats.update', - CHATS_UPSERT = 'chats.upsert', - CHATS_DELETE = 'chats.delete', - GROUPS_UPSERT = 'groups.upsert', - GROUPS_UPDATE = 'groups.update', - GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', - CALL = 'call', + APPLICATION_STARTUP = 'application.startup', + QRCODE_UPDATED = 'qrcode.updated', + CONNECTION_UPDATE = 'connection.update', + STATUS_INSTANCE = 'status.instance', + MESSAGES_SET = 'messages.set', + MESSAGES_UPSERT = 'messages.upsert', + MESSAGES_UPDATE = 'messages.update', + MESSAGES_DELETE = 'messages.delete', + SEND_MESSAGE = 'send.message', + CONTACTS_SET = 'contacts.set', + CONTACTS_UPSERT = 'contacts.upsert', + CONTACTS_UPDATE = 'contacts.update', + PRESENCE_UPDATE = 'presence.update', + CHATS_SET = 'chats.set', + CHATS_UPDATE = 'chats.update', + CHATS_UPSERT = 'chats.upsert', + CHATS_DELETE = 'chats.delete', + GROUPS_UPSERT = 'groups.upsert', + GROUPS_UPDATE = 'groups.update', + GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { - export type QrCode = { - count?: number; - pairingCode?: string; - base64?: string; - code?: string; - }; - export type Instance = { - qrcode?: QrCode; - pairingCode?: string; - authState?: { state: AuthenticationState; saveCreds: () => void }; - name?: string; - wuid?: string; - profileName?: string; - profilePictureUrl?: string; - }; + export type QrCode = { + count?: number; + pairingCode?: string; + base64?: string; + code?: string; + }; + export type Instance = { + qrcode?: QrCode; + pairingCode?: string; + authState?: { state: AuthenticationState; saveCreds: () => void }; + name?: string; + wuid?: string; + profileName?: string; + profilePictureUrl?: string; + }; - export type LocalWebHook = { - enabled?: boolean; - url?: string; - events?: string[]; - webhook_by_events?: boolean; - }; + export type LocalWebHook = { + enabled?: boolean; + url?: string; + events?: string[]; + webhook_by_events?: boolean; + }; - export type LocalChatwoot = { - enabled?: boolean; - account_id?: string; - token?: string; - url?: string; - name_inbox?: string; - sign_msg?: boolean; - number?: string; - reopen_conversation?: boolean; - conversation_pending?: boolean; - }; + export type LocalChatwoot = { + enabled?: boolean; + account_id?: string; + token?: string; + url?: string; + name_inbox?: string; + sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; + }; - export type LocalSettings = { - reject_call?: boolean; - msg_call?: string; - groups_ignore?: boolean; - always_online?: boolean; - read_messages?: boolean; - read_status?: boolean; - }; + export type LocalSettings = { + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; + }; - export type StateConnection = { - instance?: string; - state?: WAConnectionState | 'refused'; - statusReason?: number; - }; + export type StateConnection = { + instance?: string; + state?: WAConnectionState | 'refused'; + statusReason?: number; + }; - export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; + export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; } export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage']; export const MessageSubtype = [ - 'ephemeralMessage', - 'documentWithCaptionMessage', - 'viewOnceMessage', - 'viewOnceMessageV2', + 'ephemeralMessage', + 'documentWithCaptionMessage', + 'viewOnceMessage', + 'viewOnceMessageV2', ]; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index f9a9456e..b742afa9 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -12,14 +12,14 @@ import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; import { WebhookController } from './controllers/webhook.controller'; import { - AuthModel, - ChatModel, - ChatwootModel, - ContactModel, - MessageModel, - MessageUpModel, - SettingsModel, - WebhookModel, + AuthModel, + ChatModel, + ChatwootModel, + ContactModel, + MessageModel, + MessageUpModel, + SettingsModel, + WebhookModel, } from './models'; import { AuthRepository } from './repository/auth.repository'; import { ChatRepository } from './repository/chat.repository'; @@ -48,16 +48,16 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); export const repository = new RepositoryBroker( - messageRepository, - chatRepository, - contactRepository, - messageUpdateRepository, - webhookRepository, - chatwootRepository, - settingsRepository, - authRepository, - configService, - dbserver?.getClient(), + messageRepository, + chatRepository, + contactRepository, + messageUpdateRepository, + webhookRepository, + chatwootRepository, + settingsRepository, + authRepository, + configService, + dbserver?.getClient(), ); export const cache = new RedisCache(); @@ -79,15 +79,15 @@ const settingsService = new SettingsService(waMonitor); export const settingsController = new SettingsController(settingsService); export const instanceController = new InstanceController( - waMonitor, - configService, - repository, - eventEmitter, - authService, - webhookService, - chatwootService, - settingsService, - cache, + waMonitor, + configService, + repository, + eventEmitter, + authService, + webhookService, + chatwootService, + settingsService, + cache, ); export const viewsController = new ViewsController(waMonitor, configService); export const sendMessageController = new SendMessageController(waMonitor); From 85ca0683ed8924a5b714fabcc86a3cefa5891324 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:15:09 -0300 Subject: [PATCH 072/177] fix: fixed bug of creating new inbox by chatwoot --- CHANGELOG.md | 4 ++++ src/whatsapp/services/chatwoot.service.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5498ca..8ea22ae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.4.6 (homolog) + +* Fixed bug of creating new inbox by chatwoot + # 1.4.5 (2023-07-26 09:32) ### Fixed diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 5e846019..f4d8477c 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -998,6 +998,8 @@ export class ChatwootService { chatwoot_token: this.provider.token, chatwoot_url: this.provider.url, chatwoot_sign_msg: this.provider.sign_msg, + chatwoot_reopen_conversation: this.provider.reopen_conversation, + chatwoot_conversation_pending: this.provider.conversation_pending, }; if (command.split(':')[2]) { @@ -1530,7 +1532,7 @@ export class ChatwootService { } // eslint-disable-next-line - const config = { + const config = { method: 'post', maxBodyLength: Infinity, url: `${urlServer}/instance/create`, From e7ed66603794a2542a3d38eb0f3631da6fb912d2 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 17:27:25 -0300 Subject: [PATCH 073/177] Update abstract.router.ts --- src/whatsapp/abstract/abstract.router.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index cb224cd6..c44c6880 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -98,22 +98,24 @@ export abstract class RouterBroker { public async groupValidate(args: DataValidate) { const { request, ClassRef, schema, execute } = args; - - const groupJid = request.query as unknown as GroupJid; - - if (!groupJid?.groupJid) { - throw new BadRequestException( - 'The group id needs to be informed in the query', - 'ex: "groupJid=120362@g.us"', - ); - } - const instance = request.params as unknown as InstanceDto; const body = request.body; + if (!body?.groupJid) { + if (request.query.groupJid) { + Object.assign(body, { + groupJid: request.query.groupJid + }); + } else { + throw new BadRequestException( + 'The group id needs to be informed in the query', + 'ex: "groupJid=120362@g.us"', + ); + } + } + const ref = new ClassRef(); - Object.assign(body, groupJid); Object.assign(ref, body); const v = validate(ref, schema); From 1b93aac8c55cef36800e73600381484327bd343a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:33:31 -0300 Subject: [PATCH 074/177] fix: When conversation reopens is pending when conversation pending is true --- CHANGELOG.md | 1 + package.json | 2 +- src/whatsapp/services/chatwoot.service.ts | 10 ++++++++++ src/whatsapp/services/whatsapp.service.ts | 4 ++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ea22ae2..a4642d97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.4.6 (homolog) * Fixed bug of creating new inbox by chatwoot +* When conversation reopens is pending when conversation pending is true # 1.4.5 (2023-07-26 09:32) diff --git a/package.json b/package.json index ac392703..f717738c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.5", + "version": "1.4.6", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index f4d8477c..0f2f46c8 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -507,6 +507,16 @@ export class ChatwootService { let conversation: any; if (this.provider.reopen_conversation) { conversation = contactConversations.payload.find((conversation) => conversation.inbox_id == filterInbox.id); + + if (this.provider.conversation_pending) { + await client.conversations.toggleStatus({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + status: 'pending', + }, + }); + } } else { conversation = contactConversations.payload.find( (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 59245103..6de7d847 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -695,7 +695,7 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); this.sendDataWebhook(Events.STATUS_INSTANCE, { instance: this.instance.name, - status: 'removed', + status: 'closed', }); if (this.localChatwoot.enabled) { @@ -704,7 +704,7 @@ export class WAStartupService { { instanceName: this.instance.name }, { instance: this.instance.name, - status: 'removed', + status: 'closed', }, ); } From e4548f696151d6cdb610ba2dfe4afc856f237385 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:39:32 -0300 Subject: [PATCH 075/177] fix: Added docker-compose file with dockerhub image --- docker-compose.yaml.example.dockerhub | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docker-compose.yaml.example.dockerhub diff --git a/docker-compose.yaml.example.dockerhub b/docker-compose.yaml.example.dockerhub new file mode 100644 index 00000000..6136997d --- /dev/null +++ b/docker-compose.yaml.example.dockerhub @@ -0,0 +1,28 @@ +version: '3.3' + +services: + api: + container_name: evolution_api + image: davidsongomes/evolution-api:latest + restart: always + ports: + - 8080:8080 + volumes: + - evolution_instances:/evolution/instances + - evolution_store:/evolution/store + networks: + - evolution-net + env_file: + - ./Docker/.env + command: ['node', './dist/src/main.js'] + expose: + - 8080 + +volumes: + evolution_instances: + evolution_store: + +networks: + evolution-net: + external: true + \ No newline at end of file From 312ee249b6b259a544ff3f41db10f8b9b4c9245a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:39:59 -0300 Subject: [PATCH 076/177] version: 1.4.6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4642d97..4f6766a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Fixed bug of creating new inbox by chatwoot * When conversation reopens is pending when conversation pending is true +* Added docker-compose file with dockerhub image # 1.4.5 (2023-07-26 09:32) From 73e92f9ef5311802accb57a30bcd404d4faa6255 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:41:06 -0300 Subject: [PATCH 077/177] version: 1.4.6 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f6766a9..ed0b7517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # 1.4.6 (homolog) +### Fixed + * Fixed bug of creating new inbox by chatwoot * When conversation reopens is pending when conversation pending is true * Added docker-compose file with dockerhub image From af5746bb39054bb1c75b5dacf2238efc245aa239 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:45:28 -0300 Subject: [PATCH 078/177] Revert "GroupJid por Query ou por Body" --- src/whatsapp/abstract/abstract.router.ts | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index d18cf36d..3c19e6bb 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -101,24 +101,18 @@ export abstract class RouterBroker { public async groupValidate(args: DataValidate) { const { request, ClassRef, schema, execute } = args; + const groupJid = request.query as unknown as GroupJid; + + if (!groupJid?.groupJid) { + throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"'); + } + const instance = request.params as unknown as InstanceDto; const body = request.body; - if (!body?.groupJid) { - if (request.query.groupJid) { - Object.assign(body, { - groupJid: request.query.groupJid - }); - } else { - throw new BadRequestException( - 'The group id needs to be informed in the query', - 'ex: "groupJid=120362@g.us"', - ); - } - } - const ref = new ClassRef(); + Object.assign(body, groupJid); Object.assign(ref, body); const v = validate(ref, schema); From 457dbe583198f34c4da7d423bd1abe9c0bc27ea9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:46:45 -0300 Subject: [PATCH 079/177] version: 1.4.6 --- src/whatsapp/abstract/abstract.router.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index 3c19e6bb..bf1eee1b 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -101,18 +101,21 @@ export abstract class RouterBroker { public async groupValidate(args: DataValidate) { const { request, ClassRef, schema, execute } = args; - const groupJid = request.query as unknown as GroupJid; - - if (!groupJid?.groupJid) { - throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"'); - } - const instance = request.params as unknown as InstanceDto; const body = request.body; + if (!body?.groupJid) { + if (request.query.groupJid) { + Object.assign(body, { + groupJid: request.query.groupJid, + }); + } else { + throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"'); + } + } + const ref = new ClassRef(); - Object.assign(body, groupJid); Object.assign(ref, body); const v = validate(ref, schema); From 1bf2278f31a038ed8af36ee4647f16d401701274 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 17:54:29 -0300 Subject: [PATCH 080/177] version: 1.4.6 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed0b7517..2a5235d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.6 (homolog) +# 1.4.6 (2023-07-26 17:54) ### Fixed From 28a7d9c62b90eeac30143a03ac077e246478ba71 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 18:02:45 -0300 Subject: [PATCH 081/177] fix: Adjusts in instance name --- src/whatsapp/controllers/instance.controller.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e45644fe..64867a2d 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -55,19 +55,12 @@ export class InstanceController { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException('The instance name must be lowercase and without special characters'); - } - this.logger.verbose('checking duplicate token'); await this.authService.checkDuplicateToken(token); this.logger.verbose('creating instance'); const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); + instance.instanceName = instanceName; this.logger.verbose('instance: ' + instance.instanceName + ' created'); From 9bdbfc6f4f403cf6c5deffcb02f2872bb4f55968 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 26 Jul 2023 18:28:18 -0300 Subject: [PATCH 082/177] wip --- src/whatsapp/abstract/abstract.router.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index d18cf36d..230c49af 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -104,11 +104,11 @@ export abstract class RouterBroker { const instance = request.params as unknown as InstanceDto; const body = request.body; - if (!body?.groupJid) { - if (request.query.groupJid) { - Object.assign(body, { - groupJid: request.query.groupJid - }); + let groupJid = body?.groupJid; + + if (!groupJid) { + if (request.query?.groupJid) { + groupJid = request.query.groupJid; } else { throw new BadRequestException( 'The group id needs to be informed in the query', @@ -117,6 +117,14 @@ export abstract class RouterBroker { } } + if (!groupJid.endsWith('@g.us')) { + groupJid = groupJid + '@g.us'; + } + + Object.assign(body, { + groupJid: groupJid + }); + const ref = new ClassRef(); Object.assign(ref, body); From 80e3116cd8e879db47bf1c429d4c270e8dc08813 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 21:45:23 -0300 Subject: [PATCH 083/177] text: Fix problem No Session --- .DS_Store | Bin 6148 -> 6148 bytes package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.DS_Store b/.DS_Store index 11ffa2bd7bc24f00311a501886899f63ac042d9d..f07b5fd410a708405b4339fdbe299d449393688a 100644 GIT binary patch delta 32 ocmZoMXfc@J&&aVcU^gQp$7UWTX2#7+nUh#17EIgB&heKY0HA9M0ssI2 delta 172 zcmZoMXfc@J&&azmU^gQp?`9q*X2yCJh7yKUhFpe%oOHwB Date: Wed, 26 Jul 2023 21:45:49 -0300 Subject: [PATCH 084/177] text: Fix problem No Session --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 465c7324..db23ce9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.6", + "version": "1.4.7", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 127d5b97c405c67c5f66deb32c902e2c529ff859 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:36:18 -0300 Subject: [PATCH 085/177] fix: fixed error return bug --- CHANGELOG.md | 6 +++ src/exceptions/400.exception.ts | 1 + src/main.ts | 43 +++---------------- src/whatsapp/abstract/abstract.router.ts | 12 +++--- .../controllers/settings.controller.ts | 1 - src/whatsapp/repository/repository.manager.ts | 1 - 6 files changed, 20 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5235d4..5013ceaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.7 (2023-07-26 17:54) + +### Fixed + +* Fixed error return bug + # 1.4.6 (2023-07-26 17:54) ### Fixed diff --git a/src/exceptions/400.exception.ts b/src/exceptions/400.exception.ts index 833295c1..a9256bcb 100644 --- a/src/exceptions/400.exception.ts +++ b/src/exceptions/400.exception.ts @@ -2,6 +2,7 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class BadRequestException { constructor(...objectError: any[]) { + console.log('BadRequestException', objectError); throw { status: HttpStatus.BAD_REQUEST, error: 'Bad Request', diff --git a/src/main.ts b/src/main.ts index b0d2e03e..6e15f84d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,18 +1,15 @@ -import 'express-async-errors'; - -// import * as Sentry from '@sentry/node'; import compression from 'compression'; +import { configService, Cors, HttpServer } from './config/env.config'; import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; - -import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; -import { ServerUP } from './utils/server-up'; -import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; +import { HttpStatus, router } from './whatsapp/routers/index.router'; +import 'express-async-errors'; +import { ServerUP } from './utils/server-up'; function initWA() { waMonitor.loadInstance(); @@ -22,27 +19,6 @@ function bootstrap() { const logger = new Logger('SERVER'); const app = express(); - // Sentry.init({ - // dsn: '', - // integrations: [ - // // enable HTTP calls tracing - // new Sentry.Integrations.Http({ tracing: true }), - // // enable Express.js middleware tracing - // new Sentry.Integrations.Express({ app }), - // // Automatically instrument Node.js libraries and frameworks - // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), - // ], - - // // Set tracesSampleRate to 1.0 to capture 100% - // // of transactions for performance monitoring. - // // We recommend adjusting this value in production - // tracesSampleRate: 1.0, - // }); - - // app.use(Sentry.Handlers.requestHandler()); - - // app.use(Sentry.Handlers.tracingHandler()); - app.use( cors({ origin(requestOrigin, callback) { @@ -67,18 +43,13 @@ function bootstrap() { app.use('/', router); - // app.use(Sentry.Handlers.errorHandler()); - - // app.use(function onError(err, req, res, next) { - // res.statusCode = 500; - // res.end(res.sentry + '\n'); - // }); - app.use( - (err: Error, req: Request, res: Response) => { + (err: Error, req: Request, res: Response, next: NextFunction) => { if (err) { return res.status(err['status'] || 500).json(err); } + + next(); }, (req: Request, res: Response, next: NextFunction) => { const { method, url } = req; diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index 136b946a..170b06fb 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -6,7 +6,7 @@ import { validate } from 'jsonschema'; import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; -import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto'; +import { GetParticipant, GroupInvite } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; type DataValidate = { @@ -105,7 +105,7 @@ export abstract class RouterBroker { const body = request.body; let groupJid = body?.groupJid; - + if (!groupJid) { if (request.query?.groupJid) { groupJid = request.query.groupJid; @@ -113,15 +113,15 @@ export abstract class RouterBroker { throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"'); } } - + if (!groupJid.endsWith('@g.us')) { groupJid = groupJid + '@g.us'; } - + Object.assign(body, { - groupJid: groupJid + groupJid: groupJid, }); - + const ref = new ClassRef(); Object.assign(ref, body); diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 32713b1f..1a8baafc 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -12,7 +12,6 @@ export class SettingsController { constructor(private readonly settingsService: SettingsService) {} public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); return this.settingsService.create(instance, data); diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index ae02849f..e1292329 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -109,7 +109,6 @@ export class RepositoryBroker { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); } - } catch (error) { this.logger.error(error); } From 14f3f3d2ac930757a5b7d962df16d09809c8b55e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:36:37 -0300 Subject: [PATCH 086/177] fix: fixed error return bug --- src/main.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main.ts b/src/main.ts index 6e15f84d..a5b7fe8c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,15 +1,17 @@ +import 'express-async-errors'; + import compression from 'compression'; -import { configService, Cors, HttpServer } from './config/env.config'; import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; + +import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; -import { waMonitor } from './whatsapp/whatsapp.module'; -import { HttpStatus, router } from './whatsapp/routers/index.router'; -import 'express-async-errors'; import { ServerUP } from './utils/server-up'; +import { HttpStatus, router } from './whatsapp/routers/index.router'; +import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { waMonitor.loadInstance(); From d3fce5fc89b648b3774ca9846bb137462138f23c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:45:02 -0300 Subject: [PATCH 087/177] fix: Fixed problem of getting message when deleting message in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5013ceaf..97ea5c42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Fixed error return bug +* Fixed problem of getting message when deleting message in chatwoot # 1.4.6 (2023-07-26 17:54) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 0f2f46c8..283a4198 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -930,6 +930,7 @@ export class ChatwootService { } public async receiveWebhook(instance: InstanceDto, body: any) { + console.log(body); try { this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); const client = await this.clientCw(instance); @@ -940,7 +941,7 @@ export class ChatwootService { } this.logger.verbose('check if is bot'); - if (!body?.conversation || body.private) return { message: 'bot' }; + if (!body?.conversation || body.private || body.event === 'message_updated') return { message: 'bot' }; this.logger.verbose('check if is group'); const chatId = From f74a7e87bdf4502c872311a43476537614fc0a88 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:48:03 -0300 Subject: [PATCH 088/177] version: 1.4.7 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97ea5c42..85974fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.7 (2023-07-26 17:54) +# 1.4.7 (2023-07-27 08:47) ### Fixed From f95d938fb677e0b5936903f57a392043d0eb16b9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:51:58 -0300 Subject: [PATCH 089/177] fix: Adjusts in return errors --- src/exceptions/400.exception.ts | 1 - src/main.ts | 103 ++++++++++++---------- src/whatsapp/services/chatwoot.service.ts | 1 - 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/exceptions/400.exception.ts b/src/exceptions/400.exception.ts index a9256bcb..833295c1 100644 --- a/src/exceptions/400.exception.ts +++ b/src/exceptions/400.exception.ts @@ -2,7 +2,6 @@ import { HttpStatus } from '../whatsapp/routers/index.router'; export class BadRequestException { constructor(...objectError: any[]) { - console.log('BadRequestException', objectError); throw { status: HttpStatus.BAD_REQUEST, error: 'Bad Request', diff --git a/src/main.ts b/src/main.ts index a5b7fe8c..8a14f746 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,68 +14,77 @@ import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { - waMonitor.loadInstance(); + waMonitor.loadInstance(); } function bootstrap() { - const logger = new Logger('SERVER'); - const app = express(); + const logger = new Logger('SERVER'); + const app = express(); - app.use( - cors({ - origin(requestOrigin, callback) { - const { ORIGIN } = configService.get('CORS'); - !requestOrigin ? (requestOrigin = '*') : undefined; - if (ORIGIN.indexOf(requestOrigin) !== -1) { - return callback(null, true); - } - return callback(new Error('Not allowed by CORS')); - }, - methods: [...configService.get('CORS').METHODS], - credentials: configService.get('CORS').CREDENTIALS, - }), - urlencoded({ extended: true, limit: '136mb' }), - json({ limit: '136mb' }), - compression(), - ); + app.use( + cors({ + origin(requestOrigin, callback) { + const { ORIGIN } = configService.get('CORS'); + !requestOrigin ? (requestOrigin = '*') : undefined; + if (ORIGIN.indexOf(requestOrigin) !== -1) { + return callback(null, true); + } + return callback(new Error('Not allowed by CORS')); + }, + methods: [...configService.get('CORS').METHODS], + credentials: configService.get('CORS').CREDENTIALS, + }), + urlencoded({ extended: true, limit: '136mb' }), + json({ limit: '136mb' }), + compression(), + ); - app.set('view engine', 'hbs'); - app.set('views', join(ROOT_DIR, 'views')); - app.use(express.static(join(ROOT_DIR, 'public'))); + app.set('view engine', 'hbs'); + app.set('views', join(ROOT_DIR, 'views')); + app.use(express.static(join(ROOT_DIR, 'public'))); - app.use('/', router); + app.use('/', router); - app.use( - (err: Error, req: Request, res: Response, next: NextFunction) => { - if (err) { - return res.status(err['status'] || 500).json(err); - } + app.use( + (err: Error, req: Request, res: Response, next: NextFunction) => { + if (err) { + return res.status(err['status'] || 500).json({ + status: 'ERROR', + error: err['error'] || 'Internal Server Error', + response: { + message: err['message'] || 'Internal Server Error', + }, + } + ); + } - next(); - }, - (req: Request, res: Response, next: NextFunction) => { - const { method, url } = req; + next(); + }, + (req: Request, res: Response, next: NextFunction) => { + const { method, url } = req; - res.status(HttpStatus.NOT_FOUND).json({ - status: HttpStatus.NOT_FOUND, - message: `Cannot ${method.toUpperCase()} ${url}`, - error: 'Not Found', - }); + res.status(HttpStatus.NOT_FOUND).json({ + status: HttpStatus.NOT_FOUND, + error: 'Not Found', + response: { + message: `Cannot ${method.toUpperCase()} ${url}`, + }, + }); - next(); - }, - ); + next(); + }, + ); - const httpServer = configService.get('SERVER'); + const httpServer = configService.get('SERVER'); - ServerUP.app = app; - const server = ServerUP[httpServer.TYPE]; + ServerUP.app = app; + const server = ServerUP[httpServer.TYPE]; - server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); + server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); - initWA(); + initWA(); - onUnexpectedError(); + onUnexpectedError(); } bootstrap(); diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 283a4198..23efc66f 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -930,7 +930,6 @@ export class ChatwootService { } public async receiveWebhook(instance: InstanceDto, body: any) { - console.log(body); try { this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); const client = await this.clientCw(instance); From 9af7f679300ac0d62fb65a6d03b1abad235291aa Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 08:52:45 -0300 Subject: [PATCH 090/177] version: 1.4.7 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85974fac..358e9ccc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixed error return bug * Fixed problem of getting message when deleting message in chatwoot +* Change in error return pattern # 1.4.6 (2023-07-26 17:54) From 52533d4b38cc39561e51bbd3ffb47f00de9a5cf1 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Thu, 27 Jul 2023 09:23:44 -0300 Subject: [PATCH 091/177] =?UTF-8?q?Adi=C3=A7=C3=A3o=20de=20Get=20Last=20Me?= =?UTF-8?q?ssage=20e=20Archive=20por=20Chat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/validate/validate.schema.ts | 3 +- src/whatsapp/dto/chat.dto.ts | 5 +- src/whatsapp/services/whatsapp.service.ts | 62 +++++++++++++++++++---- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 8c1a4667..feb5da59 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -508,6 +508,7 @@ export const archiveChatSchema: JSONSchema7 = { $id: v4(), type: 'object', properties: { + chat: { type: 'string' }, lastMessage: { type: 'object', properties: { @@ -528,7 +529,7 @@ export const archiveChatSchema: JSONSchema7 = { }, archive: { type: 'boolean', enum: [true, false] }, }, - required: ['lastMessage', 'archive'], + required: ['archive'], }; export const deleteMessageSchema: JSONSchema7 = { diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index f2f9b1cc..f8a5da5f 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -53,13 +53,14 @@ export class ReadMessageDto { read_messages: Key[]; } -class LastMessage { +export class LastMessage { key: Key; messageTimestamp?: number; } export class ArchiveChatDto { - lastMessage: LastMessage; + lastMessage?: LastMessage; + chat?: string; archive: boolean; } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6de7d847..9729ceed 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -74,6 +74,7 @@ import { getBase64FromMediaMessageDto, NumberBusiness, OnWhatsAppDto, + LastMessage, PrivacySettingDto, ReadMessageDto, WhatsAppNumberDto, @@ -2345,23 +2346,62 @@ export class WAStartupService { throw new InternalServerErrorException('Read messages fail', error.toString()); } } + + public async getLastMessage(number: string) { + const messages = await this.fetchMessages({ + where: { + key: { + remoteJid: number + }, + owner: this.instance.name + } + }); + + let lastMessage = messages.pop(); + + for (const message of messages) { + if ( + message.messageTimestamp?.low >= lastMessage.messageTimestamp?.low + || message.messageTimestamp >= lastMessage.messageTimestamp + ) { + lastMessage = message; + } + } + + return lastMessage as unknown as LastMessage; + } public async archiveChat(data: ArchiveChatDto) { this.logger.verbose('Archiving chat'); try { - data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); + let last_message = data.lastMessage; + let number = data.chat; + + if(!last_message && number) { + last_message = await this.getLastMessage(number); + } else { + last_message = data.lastMessage; + last_message.messageTimestamp = last_message?.messageTimestamp ?? Date.now(); + number = last_message?.key?.remoteJid; + } + + if (!last_message || Object.keys(last_message).length === 0) { + throw new NotFoundException("Last message not found"); + } + console.log(last_message); + await this.client.chatModify( { - archive: data.archive, - lastMessages: [data.lastMessage], - }, - data.lastMessage.key.remoteJid, - ); - - return { - chatId: data.lastMessage.key.remoteJid, - archived: true, - }; + archive: data.archive, + lastMessages: [last_message] + }, + this.createJid(number) + ); + + return { + chatId: number, + archived: true, + }; } catch (error) { throw new InternalServerErrorException({ archived: false, From 3ae694430796a68112d049023cf98fe1bcf11eaa Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Thu, 27 Jul 2023 09:24:38 -0300 Subject: [PATCH 092/177] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 60 +++++++++++------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 9729ceed..eea9ede1 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -72,9 +72,9 @@ import { ArchiveChatDto, DeleteMessage, getBase64FromMediaMessageDto, + LastMessage, NumberBusiness, OnWhatsAppDto, - LastMessage, PrivacySettingDto, ReadMessageDto, WhatsAppNumberDto, @@ -2346,28 +2346,28 @@ export class WAStartupService { throw new InternalServerErrorException('Read messages fail', error.toString()); } } - + public async getLastMessage(number: string) { const messages = await this.fetchMessages({ - where: { - key: { - remoteJid: number - }, - owner: this.instance.name - } - }); - + where: { + key: { + remoteJid: number, + }, + owner: this.instance.name, + }, + }); + let lastMessage = messages.pop(); - + for (const message of messages) { if ( - message.messageTimestamp?.low >= lastMessage.messageTimestamp?.low - || message.messageTimestamp >= lastMessage.messageTimestamp + message.messageTimestamp?.low >= lastMessage.messageTimestamp?.low || + message.messageTimestamp >= lastMessage.messageTimestamp ) { lastMessage = message; } } - + return lastMessage as unknown as LastMessage; } @@ -2376,32 +2376,32 @@ export class WAStartupService { try { let last_message = data.lastMessage; let number = data.chat; - - if(!last_message && number) { - last_message = await this.getLastMessage(number); + + if (!last_message && number) { + last_message = await this.getLastMessage(number); } else { last_message = data.lastMessage; last_message.messageTimestamp = last_message?.messageTimestamp ?? Date.now(); number = last_message?.key?.remoteJid; } - + if (!last_message || Object.keys(last_message).length === 0) { - throw new NotFoundException("Last message not found"); + throw new NotFoundException('Last message not found'); } console.log(last_message); - + await this.client.chatModify( { - archive: data.archive, - lastMessages: [last_message] - }, - this.createJid(number) - ); - - return { - chatId: number, - archived: true, - }; + archive: data.archive, + lastMessages: [last_message], + }, + this.createJid(number), + ); + + return { + chatId: number, + archived: true, + }; } catch (error) { throw new InternalServerErrorException({ archived: false, From 1ce30f8431254406ca7234a633140dc1ccddfa47 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Thu, 27 Jul 2023 10:20:18 -0300 Subject: [PATCH 093/177] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index eea9ede1..b596525b 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2360,10 +2360,7 @@ export class WAStartupService { let lastMessage = messages.pop(); for (const message of messages) { - if ( - message.messageTimestamp?.low >= lastMessage.messageTimestamp?.low || - message.messageTimestamp >= lastMessage.messageTimestamp - ) { + if (message.messageTimestamp >= lastMessage.messageTimestamp) { lastMessage = message; } } From 332ec69ee8935b0a786e0ca407721afff6b6c6f2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 10:27:41 -0300 Subject: [PATCH 094/177] fix: Adjusts in return errors --- src/exceptions/401.exception.ts | 2 +- src/main.ts | 111 +++++++++--------- src/whatsapp/abstract/abstract.router.ts | 15 +-- .../controllers/instance.controller.ts | 12 +- src/whatsapp/routers/instance.router.ts | 4 +- 5 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/exceptions/401.exception.ts b/src/exceptions/401.exception.ts index 72734d4e..d5424c71 100644 --- a/src/exceptions/401.exception.ts +++ b/src/exceptions/401.exception.ts @@ -5,7 +5,7 @@ export class UnauthorizedException { throw { status: HttpStatus.UNAUTHORIZED, error: 'Unauthorized', - message: objectError.length > 0 ? objectError : undefined, + message: objectError.length > 0 ? objectError : 'Unauthorized', }; } } diff --git a/src/main.ts b/src/main.ts index 8a14f746..1077d64d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,77 +14,76 @@ import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { - waMonitor.loadInstance(); + waMonitor.loadInstance(); } function bootstrap() { - const logger = new Logger('SERVER'); - const app = express(); + const logger = new Logger('SERVER'); + const app = express(); - app.use( - cors({ - origin(requestOrigin, callback) { - const { ORIGIN } = configService.get('CORS'); - !requestOrigin ? (requestOrigin = '*') : undefined; - if (ORIGIN.indexOf(requestOrigin) !== -1) { - return callback(null, true); - } - return callback(new Error('Not allowed by CORS')); - }, - methods: [...configService.get('CORS').METHODS], - credentials: configService.get('CORS').CREDENTIALS, - }), - urlencoded({ extended: true, limit: '136mb' }), - json({ limit: '136mb' }), - compression(), - ); + app.use( + cors({ + origin(requestOrigin, callback) { + const { ORIGIN } = configService.get('CORS'); + !requestOrigin ? (requestOrigin = '*') : undefined; + if (ORIGIN.indexOf(requestOrigin) !== -1) { + return callback(null, true); + } + return callback(new Error('Not allowed by CORS')); + }, + methods: [...configService.get('CORS').METHODS], + credentials: configService.get('CORS').CREDENTIALS, + }), + urlencoded({ extended: true, limit: '136mb' }), + json({ limit: '136mb' }), + compression(), + ); - app.set('view engine', 'hbs'); - app.set('views', join(ROOT_DIR, 'views')); - app.use(express.static(join(ROOT_DIR, 'public'))); + app.set('view engine', 'hbs'); + app.set('views', join(ROOT_DIR, 'views')); + app.use(express.static(join(ROOT_DIR, 'public'))); - app.use('/', router); + app.use('/', router); - app.use( - (err: Error, req: Request, res: Response, next: NextFunction) => { - if (err) { - return res.status(err['status'] || 500).json({ - status: 'ERROR', - error: err['error'] || 'Internal Server Error', - response: { - message: err['message'] || 'Internal Server Error', - }, - } - ); - } + app.use( + (err: Error, req: Request, res: Response, next: NextFunction) => { + if (err) { + return res.status(err['status'] || 500).json({ + status: err['status'] || 500, + error: err['error'] || 'Internal Server Error', + response: { + message: err['message'] || 'Internal Server Error', + }, + }); + } - next(); + next(); + }, + (req: Request, res: Response, next: NextFunction) => { + const { method, url } = req; + + res.status(HttpStatus.NOT_FOUND).json({ + status: HttpStatus.NOT_FOUND, + error: 'Not Found', + response: { + message: [`Cannot ${method.toUpperCase()} ${url}`], }, - (req: Request, res: Response, next: NextFunction) => { - const { method, url } = req; + }); - res.status(HttpStatus.NOT_FOUND).json({ - status: HttpStatus.NOT_FOUND, - error: 'Not Found', - response: { - message: `Cannot ${method.toUpperCase()} ${url}`, - }, - }); + next(); + }, + ); - next(); - }, - ); + const httpServer = configService.get('SERVER'); - const httpServer = configService.get('SERVER'); + ServerUP.app = app; + const server = ServerUP[httpServer.TYPE]; - ServerUP.app = app; - const server = ServerUP[httpServer.TYPE]; + server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); - server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); + initWA(); - initWA(); - - onUnexpectedError(); + onUnexpectedError(); } bootstrap(); diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index 170b06fb..7c603880 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -48,20 +48,21 @@ export abstract class RouterBroker { const v = schema ? validate(ref, schema) : { valid: true, errors: [] }; if (!v.valid) { - const message: any[] = v.errors.map(({ property, stack, schema }) => { + const message: any[] = v.errors.map(({ stack, schema }) => { let message: string; if (schema['description']) { message = schema['description']; } else { message = stack.replace('instance.', ''); } - return { - property: property.replace('instance.', ''), - message, - }; + return message; + // return { + // property: property.replace('instance.', ''), + // message, + // }; }); - logger.error([...message]); - throw new BadRequestException(...message); + logger.error(message); + throw new BadRequestException(message); } return await execute(instance, ref); diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 64867a2d..2b62af23 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -220,8 +220,8 @@ export class InstanceController { }, }; } catch (error) { - console.log(error); - return { error: true, message: error.toString() }; + this.logger.error(error.message[0]); + throw new BadRequestException(error.message[0]); } } @@ -269,7 +269,7 @@ export class InstanceController { this.logger.verbose('logging out instance: ' + instanceName); this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - return { error: false, message: 'Instance restarted' }; + return { status: 'SUCCESS', error: false, response: { message: 'Instance restarted' } }; } catch (error) { this.logger.error(error); } @@ -310,7 +310,7 @@ export class InstanceController { this.logger.verbose('close connection instance: ' + instanceName); this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); - return { error: false, message: 'Instance logged out' }; + return { status: 'SUCCESS', error: false, response: { message: 'Instance logged out' } }; } catch (error) { throw new InternalServerErrorException(error.toString()); } @@ -329,13 +329,13 @@ export class InstanceController { await this.logout({ instanceName }); delete this.waMonitor.waInstances[instanceName]; - return { error: false, message: 'Instance deleted' }; + return { status: 'SUCCESS', error: false, response: { message: 'Instance deleted' } }; } else { this.logger.verbose('deleting instance: ' + instanceName); delete this.waMonitor.waInstances[instanceName]; this.eventEmitter.emit('remove.instance', instanceName, 'inner'); - return { error: false, message: 'Instance deleted' }; + return { status: 'SUCCESS', error: false, response: { message: 'Instance deleted' } }; } } catch (error) { throw new BadRequestException(error.toString()); diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index ae6d4066..20aa434c 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -161,7 +161,9 @@ export class InstanceRouter extends RouterBroker { if (db.ENABLED) { try { await dbserver.dropDatabase(); - return res.status(HttpStatus.CREATED).json({ error: false, message: 'Database deleted' }); + return res + .status(HttpStatus.CREATED) + .json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } }); } catch (error) { return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message }); } From 65e2ecf88ed186eb9c6283c6741ec59f16a42035 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 27 Jul 2023 10:28:26 -0300 Subject: [PATCH 095/177] version: 1.4.8 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 358e9ccc..552a7d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.8 (2023-07-27 10:27) + +### Fixed + +* Fixed error return bug + # 1.4.7 (2023-07-27 08:47) ### Fixed diff --git a/package.json b/package.json index db23ce9f..54511a9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.7", + "version": "1.4.8", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 3d02fabef423ac62177135a8c8376d6a1a8389b4 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Thu, 27 Jul 2023 10:47:26 -0300 Subject: [PATCH 096/177] Update Dockerfile --- Dockerfile | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b3ac950..01f24799 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,17 @@ FROM node:16.18-alpine -LABEL version="1.1.3" description="Api to control whatsapp features through http requests." +LABEL version="1.4.7" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" RUN apk update && apk upgrade && \ - apk add --no-cache git + apk add --no-cache git tzdata ffmpeg wget curl WORKDIR /evolution COPY ./package.json . +ENV TZ=America/Sao_Paulo ENV DOCKER_ENV=true ENV SERVER_URL=http://localhost:8080 @@ -40,17 +41,17 @@ ENV DATABASE_ENABLED=false ENV DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true ENV DATABASE_CONNECTION_DB_PREFIX_NAME=evolution -ENV DATABASE_SAVE_DATA_INSTANCE=false -ENV DATABASE_SAVE_DATA_NEW_MESSAGE=false -ENV DATABASE_SAVE_MESSAGE_UPDATE=false -ENV DATABASE_SAVE_DATA_CONTACTS=false -ENV DATABASE_SAVE_DATA_CHATS=false +ENV DATABASE_SAVE_DATA_INSTANCE=true +ENV DATABASE_SAVE_DATA_NEW_MESSAGE=true +ENV DATABASE_SAVE_MESSAGE_UPDATE=true +ENV DATABASE_SAVE_DATA_CONTACTS=true +ENV DATABASE_SAVE_DATA_CHATS=true ENV REDIS_ENABLED=false ENV REDIS_URI=redis://redis:6379 ENV REDIS_PREFIX_KEY=evolution -ENV WEBHOOK_GLOBAL_URL= +ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false @@ -91,18 +92,13 @@ ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true ENV AUTHENTICATION_JWT_EXPIRIN_IN=0 ENV AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`' -ENV AUTHENTICATION_INSTANCE_MODE=server - -ENV AUTHENTICATION_INSTANCE_NAME=evolution -ENV AUTHENTICATION_INSTANCE_WEBHOOK_URL= -ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 -ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 -ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL= - RUN npm install COPY . . RUN npm run build +HEALTHCHECK --interval=1m --retries=250 --start-period=2m \ + CMD curl --fail http://$SERVER_URL/ || exit 1 + CMD [ "node", "./dist/src/main.js" ] From fe2b9774d8a1f8b9558c8e8571b0531babba5931 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 29 Jul 2023 11:09:56 -0300 Subject: [PATCH 097/177] fix: Solved problem when disconnecting from the instance the instance was deleted --- CHANGELOG.md | 10 +++ package.json | 2 +- .../controllers/chatwoot.controller.ts | 6 -- .../controllers/instance.controller.ts | 6 +- src/whatsapp/services/chatwoot.service.ts | 85 +------------------ src/whatsapp/services/monitor.service.ts | 11 ++- src/whatsapp/services/whatsapp.service.ts | 5 +- 7 files changed, 29 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 552a7d0d..1dc24749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 1.5.0 (homolog) + +### Fixed + +* Solved problem when disconnecting from the instance the instance was deleted + +### Integrations + +- Chatwoot: v2.18.0 - v3.0.0 + # 1.4.8 (2023-07-27 10:27) ### Fixed diff --git a/package.json b/package.json index 54511a9c..4d6b2389 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.8", + "version": "1.5.0", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index ab291c43..9dc493dc 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -90,10 +90,4 @@ export class ChatwootController { return chatwootService.receiveWebhook(instance, data); } - - public async newInstance(data: any) { - const chatwootService = new ChatwootService(waMonitor, this.configService); - - return chatwootService.newInstance(data); - } } diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 2b62af23..096e6c2c 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -187,7 +187,7 @@ export class InstanceController { this.chatwootService.initInstanceChatwoot( instance, - instance.instanceName, + instance.instanceName.split('-cwId-')[0], `${urlServer}/chatwoot/webhook/${instance.instanceName}`, qrcode, number, @@ -234,6 +234,10 @@ export class InstanceController { this.logger.verbose('state: ' + state); + if (!state) { + throw new BadRequestException('The "' + instanceName + '" instance does not exist'); + } + if (state == 'open') { return await this.connectionState({ instanceName }); } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 23efc66f..f78f1c36 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -5,7 +5,7 @@ import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import mimeTypes from 'mime-types'; import path from 'path'; -import { ConfigService, HttpServer } from '../../config/env.config'; +import { ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { ROOT_DIR } from '../../config/path.config'; import { ChatwootDto } from '../dto/chatwoot.dto'; @@ -578,7 +578,7 @@ export class ChatwootService { } this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); + const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName.split('-cwId-')[0]); if (!findByName) { this.logger.warn('inbox not found'); @@ -996,39 +996,6 @@ export class ChatwootService { await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); await waInstance?.client?.ws?.close(); } - - if (command.includes('new_instance')) { - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const data = { - instanceName: command.split(':')[1], - qrcode: true, - chatwoot_account_id: this.provider.account_id, - chatwoot_token: this.provider.token, - chatwoot_url: this.provider.url, - chatwoot_sign_msg: this.provider.sign_msg, - chatwoot_reopen_conversation: this.provider.reopen_conversation, - chatwoot_conversation_pending: this.provider.conversation_pending, - }; - - if (command.split(':')[2]) { - data['number'] = command.split(':')[2]; - } - - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: data, - }; - - await axios.request(config); - } } if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { @@ -1342,7 +1309,7 @@ export class ChatwootService { if (!body.key.fromMe) { this.logger.verbose('message is not from me'); - content = `**${participantName}**\n\n${bodyMessage}`; + content = `**${participantName}:**\n\n${bodyMessage}`; } else { this.logger.verbose('message is from me'); content = `${bodyMessage}`; @@ -1515,50 +1482,4 @@ export class ChatwootService { this.logger.error(error); } } - - public async newInstance(data: any) { - try { - const instanceName = data.instanceName; - const qrcode = true; - const number = data.number; - const accountId = data.accountId; - const chatwootToken = data.token; - const chatwootUrl = data.url; - const signMsg = true; - const urlServer = this.configService.get('SERVER').URL; - const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - - const requestData = { - instanceName, - qrcode, - chatwoot_account_id: accountId, - chatwoot_token: chatwootToken, - chatwoot_url: chatwootUrl, - chatwoot_sign_msg: signMsg, - }; - - if (number) { - requestData['number'] = number; - } - - // eslint-disable-next-line - const config = { - method: 'post', - maxBodyLength: Infinity, - url: `${urlServer}/instance/create`, - headers: { - 'Content-Type': 'application/json', - apikey: apiKey, - }, - data: requestData, - }; - - // await axios.request(config); - - return true; - } catch (error) { - this.logger.error(error); - return null; - } - } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 50f671d9..c0b9b610 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -335,11 +335,14 @@ export class WAMonitoringService { this.logger.verbose('checking instances without connection'); this.eventEmitter.on('no.connection', async (instanceName) => { try { - this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); - this.waInstances[instanceName] = undefined; + this.logger.verbose('logging out instance: ' + instanceName); + await this.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); - this.logger.verbose('request cleaning up instance: ' + instanceName); - this.cleaningUp(instanceName); + this.logger.verbose('close connection instance: ' + instanceName); + this.waInstances[instanceName]?.client?.ws?.close(); + + this.waInstances[instanceName].instance.qrcode = { count: 0 }; + this.waInstances[instanceName].stateConnection.state = 'close'; } catch (error) { this.logger.error({ localError: 'noConnection', diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6de7d847..46b909a0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -135,12 +135,12 @@ export class WAStartupService { } private readonly logger = new Logger(WAStartupService.name); - private readonly instance: wa.Instance = {}; + public readonly instance: wa.Instance = {}; public client: WASocket; private readonly localWebhook: wa.LocalWebHook = {}; private readonly localChatwoot: wa.LocalChatwoot = {}; private readonly localSettings: wa.LocalSettings = {}; - private stateConnection: wa.StateConnection = { state: 'close' }; + public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); private readonly userDevicesCache: CacheStore = new NodeCache(); @@ -558,6 +558,7 @@ export class WAStartupService { this.logger.verbose('Connection update'); if (qr) { this.logger.verbose('QR code found'); + console.log('this.instance.qrcode', this.instance.qrcode); if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { this.logger.verbose('QR code limit reached'); From cffcca9722dc9d2236c07df44a9f103bd7dcdd3c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 29 Jul 2023 11:30:37 -0300 Subject: [PATCH 098/177] fix: adjust in instance name in chatwoot --- src/whatsapp/controllers/instance.controller.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 096e6c2c..1434d5da 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -179,7 +179,7 @@ export class InstanceController { token: chatwoot_token, url: chatwoot_url, sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, + name_inbox: instance.instanceName.split('-cwId-')[0], number, reopen_conversation: chatwoot_reopen_conversation || false, conversation_pending: chatwoot_conversation_pending || false, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 46b909a0..8d1ca865 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -586,23 +586,6 @@ export class WAStartupService { statusReason: DisconnectReason.connectionClosed, }); - this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); - this.sendDataWebhook(Events.STATUS_INSTANCE, { - instance: this.instance.name, - status: 'removed', - }); - - if (this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp( - Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, - { - instance: this.instance.name, - status: 'removed', - }, - ); - } - this.logger.verbose('endSession defined as true'); this.endSession = true; From 66d06afaf718784ea7b699c1217ab35f2a332741 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 30 Jul 2023 11:03:12 -0300 Subject: [PATCH 099/177] feat: New instance manager in /manager route --- CHANGELOG.md | 4 + src/whatsapp/controllers/views.controller.ts | 15 +--- src/whatsapp/routers/index.router.ts | 3 +- src/whatsapp/routers/view.router.ts | 8 +- views/manager.hbs | 30 +++++++ views/qrcode.hbs | 82 -------------------- 6 files changed, 43 insertions(+), 99 deletions(-) create mode 100644 views/manager.hbs delete mode 100644 views/qrcode.hbs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dc24749..1a37833f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # 1.5.0 (homolog) +### Feature + +* New instance manager in /manager route + ### Fixed * Solved problem when disconnecting from the instance the instance was deleted diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index 5f4060ac..e775b960 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -1,24 +1,15 @@ import { Request, Response } from 'express'; -import { Auth, ConfigService } from '../../config/env.config'; -import { BadRequestException } from '../../exceptions'; -import { InstanceDto } from '../dto/instance.dto'; +import { ConfigService } from '../../config/env.config'; import { HttpStatus } from '../routers/index.router'; import { WAMonitoringService } from '../services/monitor.service'; export class ViewsController { constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} - public async qrcode(request: Request, response: Response) { + public async manager(request: Request, response: Response) { try { - const param = request.params as unknown as InstanceDto; - const instance = this.waMonit.waInstances[param.instanceName]; - if (instance.connectionStatus.state === 'open') { - throw new BadRequestException('The instance is already connected'); - } - const type = this.configService.get('AUTHENTICATION').TYPE; - - return response.status(HttpStatus.OK).render('qrcode', { type, ...param }); + return response.status(HttpStatus.OK).render('manager'); } catch (error) { console.log('ERROR: ', error); } diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index db082799..3de9b71d 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -37,7 +37,8 @@ router version: packageJson.version, }); }) - .use('/instance', new InstanceRouter(configService, ...guards).router, new ViewsRouter(instanceExistsGuard).router) + .use('/instance', new InstanceRouter(configService, ...guards).router) + .use('/manager', new ViewsRouter().router) .use('/message', new MessageRouter(...guards).router) .use('/chat', new ChatRouter(...guards).router) .use('/group', new GroupRouter(...guards).router) diff --git a/src/whatsapp/routers/view.router.ts b/src/whatsapp/routers/view.router.ts index c5e18129..11002777 100644 --- a/src/whatsapp/routers/view.router.ts +++ b/src/whatsapp/routers/view.router.ts @@ -1,14 +1,14 @@ -import { RequestHandler, Router } from 'express'; +import { Router } from 'express'; import { RouterBroker } from '../abstract/abstract.router'; import { viewsController } from '../whatsapp.module'; export class ViewsRouter extends RouterBroker { - constructor(...guards: RequestHandler[]) { + constructor() { super(); - this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => { - return viewsController.qrcode(req, res); + this.router.get('/', (req, res) => { + return viewsController.manager(req, res); }); } diff --git a/views/manager.hbs b/views/manager.hbs new file mode 100644 index 00000000..0c81dcc8 --- /dev/null +++ b/views/manager.hbs @@ -0,0 +1,30 @@ + + + + + + + + + + + + Instance Manager + + + + + + + + + \ No newline at end of file diff --git a/views/qrcode.hbs b/views/qrcode.hbs deleted file mode 100644 index 54f39251..00000000 --- a/views/qrcode.hbs +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - Generate QRCode - - - - -
- -
-

Connect to whatsapp

-
- - - -
-
-
- -
- -
- - - - - - \ No newline at end of file From 9ea1eaf3edfbdf09c1da2b9809a6ca02667e491b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 10:55:24 -0300 Subject: [PATCH 100/177] fix: Encoded spaces in chatwoot webhook --- CHANGELOG.md | 1 + src/whatsapp/controllers/instance.controller.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a37833f..ecd9d9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Fixed * Solved problem when disconnecting from the instance the instance was deleted +* Encoded spaces in chatwoot webhook ### Integrations diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 1434d5da..04f45a4a 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -188,7 +188,7 @@ export class InstanceController { this.chatwootService.initInstanceChatwoot( instance, instance.instanceName.split('-cwId-')[0], - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`, qrcode, number, ); @@ -216,7 +216,7 @@ export class InstanceController { conversation_pending: chatwoot_conversation_pending || false, number, name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`, }, }; } catch (error) { From 8afcfde0782fb577784cb2215ee79ef384c6c86c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 12:26:50 -0300 Subject: [PATCH 101/177] add: Added extra files for chatwoot and appsmith --- CHANGELOG.md | 1 + Extras/appsmith/manager.json | 12287 ++++++++++++++++ .../_Evolution__Configurar_Admin.json | 233 + .../_Evolution__Criador_de_Empresas.json | 444 + .../_Evolution__Criador_de_Inbox.json | 364 + views/manager.hbs | 7 - 6 files changed, 13329 insertions(+), 7 deletions(-) create mode 100644 Extras/appsmith/manager.json create mode 100644 Extras/chatwoot/_Evolution__Configurar_Admin.json create mode 100644 Extras/chatwoot/_Evolution__Criador_de_Empresas.json create mode 100644 Extras/chatwoot/_Evolution__Criador_de_Inbox.json diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd9d9c8..640d0f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Feature * New instance manager in /manager route +* Added extra files for chatwoot and appsmith ### Fixed diff --git a/Extras/appsmith/manager.json b/Extras/appsmith/manager.json new file mode 100644 index 00000000..8cd958c2 --- /dev/null +++ b/Extras/appsmith/manager.json @@ -0,0 +1,12287 @@ +{ + "clientSchemaVersion": 1.0, + "serverSchemaVersion": 6.0, + "exportedApplication": { + "name": "EvolutionAPI", + "isPublic": true, + "pages": [{ "id": "Page1", "isDefault": true }], + "publishedPages": [{ "id": "Page1", "isDefault": true }], + "viewMode": false, + "appIsExample": false, + "unreadCommentThreads": 0.0, + "color": "#F5D1D1", + "icon": "bar-graph", + "slug": "evolutionapi", + "unpublishedAppLayout": { "type": "DESKTOP" }, + "publishedAppLayout": { "type": "DESKTOP" }, + "unpublishedCustomJSLibs": [], + "publishedCustomJSLibs": [], + "evaluationVersion": 2.0, + "applicationVersion": 2.0, + "collapseInvisibleWidgets": true, + "isManualUpdate": false, + "deleted": false + }, + "datasourceList": [], + "customJSLibList": [], + "pageList": [ + { + "unpublishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "viewMode": false, + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 4896.0, + "snapColumns": 64.0, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0.0, + "bottomRow": 420.0, + "containerStyle": "none", + "snapRows": 124.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 80.0, + "minHeight": 1292.0, + "dynamicTriggerPathList": [], + "parentColumnSpace": 1.0, + "dynamicBindingPathList": [], + "leftColumn": 0.0, + "children": [ + { + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "borderColor": "#E0DEDE", + "isVisibleDownload": true, + "iconSVG": "https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg", + "topRow": 6.0, + "isSortable": true, + "type": "TABLE_WIDGET_V2", + "inlineEditingSaveOption": "ROW_LEVEL", + "animateLoading": true, + "dynamicBindingPathList": [ + { "key": "tableData" }, + { "key": "primaryColumns.customColumn9.boxShadow" }, + { "key": "primaryColumns.customColumn9.borderRadius" }, + { "key": "primaryColumns.customColumn9.menuColor" }, + { "key": "primaryColumns.customColumn8.computedValue" }, + { "key": "primaryColumns.customColumn7.computedValue" }, + { "key": "primaryColumns.customColumn6.computedValue" }, + { "key": "primaryColumns.customColumn5.computedValue" }, + { "key": "primaryColumns.customColumn2.computedValue" }, + { "key": "primaryColumns.customColumn1.textColor" }, + { "key": "primaryColumns.customColumn1.cellBackground" }, + { "key": "primaryColumns.customColumn1.computedValue" }, + { "key": "primaryColumns.instance.computedValue" }, + { "key": "isVisible" }, + { "key": "accentColor" }, + { "key": "borderRadius" }, + { "key": "boxShadow" } + ], + "needsHeightForContent": true, + "leftColumn": 14.0, + "delimiter": ",", + "defaultSelectedRowIndex": 0.0, + "showInlineEditingOptionDropdown": true, + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isVisibleFilters": true, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "enableClientSideSearch": true, + "version": 2.0, + "totalRecordsCount": 0.0, + "isLoading": false, + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "columnUpdatedAt": 1.690746223636e12, + "defaultSelectedRowIndices": [0.0], + "mobileBottomRow": 32.0, + "widgetName": "TableInstances", + "defaultPageSize": 0.0, + "columnOrder": [ + "instance", + "customColumn5", + "customColumn1", + "customColumn2", + "customColumn6", + "customColumn7", + "customColumn8", + "customColumn9" + ], + "dynamicPropertyPathList": [ + { "key": "primaryColumns.customColumn1.cellBackground" }, + { "key": "isVisible" } + ], + "displayName": "Table", + "bottomRow": 42.0, + "columnWidthMap": { + "customColumn3": 92.0, + "customColumn2": 340.0, + "customColumn5": 254.0, + "customColumn9": 97.0 + }, + "parentRowSpace": 10.0, + "hideCard": false, + "mobileRightColumn": 36.0, + "parentColumnSpace": 20.078125, + "dynamicTriggerPathList": [ + { + "key": "primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick" + }, + { + "key": "primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick" + }, + { + "key": "primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick" + } + ], + "borderWidth": "1", + "primaryColumns": { + "instance": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 0.0, + "width": 150.0, + "originalId": "instance", + "id": "instance", + "alias": "instance", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "Instance", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}", + "sticky": "", + "validation": {} + }, + "customColumn1": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 1.0, + "width": 150.0, + "originalId": "customColumn1", + "id": "customColumn1", + "alias": "Status", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF", + "cellBackground": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}", + "textColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}" + }, + "customColumn2": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 2.0, + "width": 150.0, + "originalId": "customColumn2", + "id": "customColumn2", + "alias": "Apikey", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Apikey", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn5": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 5.0, + "width": 150.0, + "originalId": "customColumn5", + "id": "customColumn5", + "alias": "Owner", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Owner", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn6": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 6.0, + "width": 150.0, + "originalId": "customColumn6", + "id": "customColumn6", + "alias": "profilePictureUrl", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profilePictureUrl", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn7": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 7.0, + "width": 150.0, + "originalId": "customColumn7", + "id": "customColumn7", + "alias": "profileName", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profileName", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn8": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 8.0, + "width": 150.0, + "originalId": "customColumn8", + "id": "customColumn8", + "alias": "profileStatus", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profileStatus", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn9": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 9.0, + "width": 150.0, + "originalId": "customColumn9", + "id": "customColumn9", + "alias": "Actions", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "menuButton", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Actions", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF", + "menuColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}", + "borderRadius": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}", + "boxShadow": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}", + "customAlias": "", + "menuItemsSource": "STATIC", + "menuButtonLabel": " ", + "menuButtoniconName": "chevron-down", + "menuItems": { + "menuItemjfzsd8g6yr": { + "id": "menuItemjfzsd8g6yr", + "index": 0.0, + "label": "Webhook", + "widgetId": "vygcejtdun", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Webhook.run();\nshowModal('ModalWebhook');}}" + }, + "menuItem4sqork5nmt": { + "id": "menuItem4sqork5nmt", + "index": 1.0, + "label": "Settings", + "widgetId": "0hw8oqpwcj", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Settings.run();\nshowModal('ModalSettings');}}" + }, + "menuItemig6ua4ixjx": { + "id": "menuItemig6ua4ixjx", + "index": 2.0, + "label": "Chatwoot", + "widgetId": "fuq5dtgbqc", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}" + } + } + } + }, + "key": "e3yxhhyeel", + "canFreezeColumn": true, + "isDeprecated": false, + "rightColumn": 63.0, + "textSize": "0.875rem", + "widgetId": "uupm7enu8u", + "minWidth": 450.0, + "tableData": "{{fetch_Instances.data}}", + "label": "Data", + "searchKey": "", + "parentId": "0", + "renderMode": "CANVAS", + "mobileTopRow": 4.0, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "isVisiblePagination": true, + "verticalAlignment": "CENTER" + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "BtnNewInstance", + "onClick": "{{showModal('ModalInstance');}}", + "buttonColor": "rgb(3, 179, 101)", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 8.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 7.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "text": "New Instance", + "isDisabled": false, + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 19.0, + "isDefaultClickDisabled": true, + "iconName": "add", + "widgetId": "84ei9q1ugm", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 74.0, + "widgetName": "ModalQrcode", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 50.0, + "bottomRow": 500.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 45.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "leftColumn": 21.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 450.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 52.0, + "widgetName": "ImageQrcode", + "displayName": "Image", + "iconSVG": "https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", + "topRow": 6.0, + "bottomRow": 43.0, + "parentRowSpace": 10.0, + "type": "IMAGE_WIDGET", + "hideCard": false, + "mobileRightColumn": 55.0, + "animateLoading": true, + "parentColumnSpace": 20.078125, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "image" }, + { "key": "borderRadius" } + ], + "defaultImage": "https://evolution-api.com/files/evolution-api-favicon.png", + "key": "4chlj9l432", + "image": "{{Connect.data.base64}}", + "isDeprecated": false, + "rightColumn": 61.0, + "objectFit": "contain", + "widgetId": "27dpgapd7q", + "isVisible": true, + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 40.0, + "maxZoomLevel": 1.0, + "enableDownload": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 43.0, + "enableRotation": false + }, + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton1", + "onClick": "{{closeModal('ModalQrcode');\nfetch_Instances.run()}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 58.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "iconSize": 24.0, + "isDisabled": false, + "key": "pezy0hb491", + "isDeprecated": false, + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "i1dw369dch", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 58.0, + "buttonVariant": "TERTIARY" + }, + { + "mobileBottomRow": 5.0, + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 41.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "fontFamily" }], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "Qrcode", + "key": "9s8f10sepn", + "isDeprecated": false, + "rightColumn": 41.0, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "mg2cqsi9fn", + "minWidth": 450.0, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "we6j3r2byy", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "ljwryrjhy7", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "g8xx6ocuvi", + "height": 450.0, + "isDeprecated": false, + "rightColumn": 45.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "ljwryrjhy7", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 50.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 21.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "BtnConfig", + "onClick": "{{showModal('ModalConfig');}}", + "buttonColor": "#2563eb", + "dynamicPropertyPathList": [], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 30.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "text": "Access", + "isDisabled": false, + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 7.0, + "isDefaultClickDisabled": true, + "iconName": "user", + "widgetId": "uegjpy37i6", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 14.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 73.0, + "widgetName": "ModalConfig", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 49.0, + "bottomRow": 30.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 25.0, + "minHeight": 300.0, + "animateLoading": true, + "parentColumnSpace": 11.75, + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas2", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 300.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 300.0, + "mobileRightColumn": 282.0, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 84.0, + "borderColor": "#E0DEDE", + "widgetName": "FormConfig", + "isCanvas": true, + "displayName": "Form", + "iconSVG": "/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg", + "searchTags": ["group"], + "topRow": 0.0, + "bottomRow": 28.0, + "parentRowSpace": 10.0, + "type": "FORM_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 25.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [], + "children": [ + { + "mobileBottomRow": 400.0, + "widgetName": "Canvas2Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 280.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "minHeight": 400.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "mobileBottomRow": 5.0, + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 25.5, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "dynamicTriggerPathList": [], + "leftColumn": 1.5, + "dynamicBindingPathList": [ + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "Access Credentials", + "key": "9s8f10sepn", + "isDeprecated": false, + "rightColumn": 25.5, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "tps5rw2lk9", + "minWidth": 450.0, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.5, + "maxDynamicHeight": 9000.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + }, + { + "resetFormOnClick": true, + "boxShadow": "none", + "mobileBottomRow": 37.0, + "widgetName": "Button1", + "onClick": "{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "dynamicPropertyPathList": [ + { "key": "isDisabled" } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 22.0, + "bottomRow": 26.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 62.0, + "animateLoading": true, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 51.0, + "dynamicBindingPathList": [ + { "key": "isDisabled" }, + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "text": "Login", + "isDisabled": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "iconName": "log-in", + "widgetId": "gzxvnsxk0y", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 33.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 46.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "resetFormOnClick": true, + "boxShadow": "none", + "mobileBottomRow": 37.0, + "widgetName": "Button1Copy", + "onClick": "{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}", + "buttonColor": "#dc2626", + "dynamicPropertyPathList": [ + { "key": "isDisabled" } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 21.0, + "bottomRow": 25.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 62.0, + "animateLoading": true, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "isDisabled" }, + { "key": "borderRadius" } + ], + "text": "Logout", + "isDisabled": "{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}", + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 14.0, + "isDefaultClickDisabled": true, + "iconName": "log-out", + "widgetId": "f2i8tsbgx1", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 33.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 46.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", + "topRow": 6.0, + "labelWidth": 5.0, + "type": "INPUT_WIDGET_V2", + "animateLoading": true, + "resetOnSubmit": true, + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "defaultText" }, + { "key": "accentColor" }, + { "key": "borderRadius" } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "", + "isDisabled": false, + "isRequired": true, + "dynamicHeight": "FIXED", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "showStepArrows": false, + "isVisible": true, + "version": 2.0, + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileBottomRow": 13.0, + "widgetName": "InputApiUrl", + "displayName": "Input", + "searchTags": [ + "form", + "text input", + "number", + "textarea" + ], + "bottomRow": 13.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "hideCard": false, + "mobileRightColumn": 22.0, + "parentColumnSpace": 5.047119140625, + "dynamicTriggerPathList": [], + "labelPosition": "Top", + "key": "r1hfat3ouf", + "labelTextSize": "0.875rem", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "spgryrb5ao", + "minWidth": 450.0, + "label": "API URL", + "parentId": "lrtvcpswru", + "labelAlignment": "left", + "renderMode": "CANVAS", + "mobileTopRow": 6.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "maxDynamicHeight": 9000.0, + "isSpellCheck": false, + "iconAlign": "left", + "defaultText": "{{appsmith.store.api_url || ''}}", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", + "topRow": 14.0, + "labelWidth": 5.0, + "type": "INPUT_WIDGET_V2", + "animateLoading": true, + "resetOnSubmit": true, + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "defaultText" }, + { "key": "accentColor" }, + { "key": "borderRadius" } + ], + "labelStyle": "", + "inputType": "PASSWORD", + "isDisabled": false, + "isRequired": true, + "dynamicHeight": "FIXED", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "showStepArrows": false, + "isVisible": true, + "version": 2.0, + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileBottomRow": 13.0, + "widgetName": "InputGlobalApiKey", + "displayName": "Input", + "searchTags": [ + "form", + "text input", + "number", + "textarea" + ], + "bottomRow": 21.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "hideCard": false, + "mobileRightColumn": 22.0, + "parentColumnSpace": 5.047119140625, + "dynamicTriggerPathList": [], + "labelPosition": "Top", + "key": "r1hfat3ouf", + "labelTextSize": "0.875rem", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "v2vedr13py", + "minWidth": 450.0, + "label": "GLOBAL API KEY", + "parentId": "lrtvcpswru", + "labelAlignment": "left", + "renderMode": "CANVAS", + "mobileTopRow": 6.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "maxDynamicHeight": 9000.0, + "shouldAllowAutofill": true, + "iconAlign": "left", + "defaultText": "{{appsmith.store.api_key || ''}}", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton2", + "onClick": "{{closeModal('ModalConfig');}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "parentColumnSpace": 9.072265625, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 60.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "isDisabled": false, + "key": "pezy0hb491", + "isDeprecated": false, + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "oaouelmhi1", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 60.0, + "buttonVariant": "TERTIARY" + } + ], + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "lrtvcpswru", + "containerStyle": "none", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "h97rbttd5c", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "borderWidth": "0", + "positioning": "fixed", + "key": "dtzd07zsya", + "backgroundColor": "#FFFFFF", + "isDeprecated": false, + "rightColumn": 63.0, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "h97rbttd5c", + "minWidth": 450.0, + "isVisible": true, + "parentId": "es5gsctogb", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 44.0, + "responsiveBehavior": "fill", + "originalTopRow": 0.0, + "borderRadius": "0.375rem", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 28.0, + "minDynamicHeight": 10.0 + } + ], + "isDisabled": false, + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 282.0, + "detachFromLayout": true, + "widgetId": "es5gsctogb", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "gneh33z88k", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "g8xx6ocuvi", + "height": 300.0, + "isDeprecated": false, + "rightColumn": 25.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "gneh33z88k", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 49.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "width": 632.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 66.0, + "widgetName": "ModalInstance", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 42.0, + "bottomRow": 149.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 37.0, + "minHeight": 1490.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "leftColumn": 13.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas3", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 1490.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 1140.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton3Copy", + "onClick": "{{closeModal('ModalInstance');}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 57.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "iconSize": 24.0, + "isDisabled": false, + "key": "mr6bto7c8j", + "isDeprecated": false, + "rightColumn": 63.0, + "iconName": "cross", + "widgetId": "xofakp4har", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "esgwuzqcwt", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 58.0, + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}", + "topRow": 4.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "resetButtonStyles.buttonColor" }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.children.webhook.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.borderRadius" + }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.borderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.borderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.borderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.borderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.accentColor" + } + ], + "showReset": true, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY", + "iconAlign": "left" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Create", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 147.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "webhook": { + "children": { + "webhook": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "webhook", + "identifier": "webhook", + "position": 0.0, + "originalIdentifier": "webhook", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook" + }, + "events": { + "children": {}, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Multiselect", + "sourceData": [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN" + ], + "isCustomField": false, + "accessor": "events", + "identifier": "events", + "position": 2.0, + "originalIdentifier": "events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Events", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]" + }, + "webhook_by_events": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "webhook_by_events", + "identifier": "webhook_by_events", + "position": 2.0, + "originalIdentifier": "webhook_by_events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook By Events" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "webhook", + "identifier": "webhook", + "position": 1.0, + "originalIdentifier": "webhook", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Webhook", + "labelStyle": "BOLD" + }, + "instance": { + "children": { + "instanceName": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "instanceName", + "identifier": "instanceName", + "position": 0.0, + "originalIdentifier": "instanceName", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Instance Name" + }, + "token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "token", + "identifier": "token", + "position": 1.0, + "originalIdentifier": "token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Token" + }, + "qrcode": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "qrcode", + "identifier": "qrcode", + "position": 2.0, + "originalIdentifier": "qrcode", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Qrcode" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "instance", + "identifier": "instance", + "position": 0.0, + "originalIdentifier": "instance", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Instance", + "labelStyle": "BOLD" + }, + "settings": { + "children": { + "reject_call": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "reject_call", + "identifier": "reject_call", + "position": 0.0, + "originalIdentifier": "reject_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reject Call" + }, + "msg_call": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "msg_call", + "identifier": "msg_call", + "position": 1.0, + "originalIdentifier": "msg_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Msg Call" + }, + "groups_ignore": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "groups_ignore", + "identifier": "groups_ignore", + "position": 2.0, + "originalIdentifier": "groups_ignore", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Groups Ignore" + }, + "always_online": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "always_online", + "identifier": "always_online", + "position": 3.0, + "originalIdentifier": "always_online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Always Online" + }, + "read_messages": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_messages", + "identifier": "read_messages", + "position": 4.0, + "originalIdentifier": "read_messages", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Messages" + }, + "read_status": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_status", + "identifier": "read_status", + "position": 5.0, + "originalIdentifier": "read_status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Status" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "settings", + "identifier": "settings", + "position": 2.0, + "originalIdentifier": "settings", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Settings", + "labelStyle": "BOLD" + }, + "chatwoot": { + "children": { + "chatwoot_account_id": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_account_id", + "identifier": "chatwoot_account_id", + "position": 0.0, + "originalIdentifier": "chatwoot_account_id", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Account Id" + }, + "chatwoot_token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Password Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_token", + "identifier": "chatwoot_token", + "position": 1.0, + "originalIdentifier": "chatwoot_token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Token", + "shouldAllowAutofill": true + }, + "chatwoot_url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_url", + "identifier": "chatwoot_url", + "position": 2.0, + "originalIdentifier": "chatwoot_url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Url" + }, + "chatwoot_sign_msg": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_sign_msg", + "identifier": "chatwoot_sign_msg", + "position": 3.0, + "originalIdentifier": "chatwoot_sign_msg", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Sign Msg" + }, + "chatwoot_reopen_conversation": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_reopen_conversation", + "identifier": "chatwoot_reopen_conversation", + "position": 4.0, + "originalIdentifier": "chatwoot_reopen_conversation", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Reopen Conversation" + }, + "chatwoot_conversation_pending": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_conversation_pending", + "identifier": "chatwoot_conversation_pending", + "position": 5.0, + "originalIdentifier": "chatwoot_conversation_pending", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Conversation Pending" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "chatwoot", + "identifier": "chatwoot", + "position": 3.0, + "originalIdentifier": "chatwoot", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Chatwoot", + "labelStyle": "BOLD" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "instanceName": "", + "token": "", + "webhook": "", + "webhook_by_events": false, + "events": [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN" + ], + "reject_call": false, + "msg_call": "", + "groups_ignore": false, + "always_online": false, + "read_messages": false, + "read_status": false, + "chatwoot_account_id": "", + "chatwoot_token": "", + "chatwoot_url": "", + "chatwoot_sign_msg": false, + "chatwoot_reopen_conversation": false, + "chatwoot_conversation_pending": false + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 85.0, + "widgetName": "FormInstance", + "submitButtonStyles": { + "buttonColor": "rgb(3, 179, 101)", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 147.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "New Instance", + "hideCard": false, + "mobileRightColumn": 22.0, + "shouldScrollContents": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "o0v8ypwnya", + "minWidth": 450.0, + "parentId": "esgwuzqcwt", + "renderMode": "CANVAS", + "mobileTopRow": 44.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 4.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "w17ra2a85u", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "esgwuzqcwt", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "rnttu90jzr", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "bkvkzj4d20", + "height": 1490.0, + "isDeprecated": false, + "rightColumn": 37.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "rnttu90jzr", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 42.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 13.0, + "maxDynamicHeight": 9000.0, + "width": 628.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "ButtonRefreshData", + "onClick": "{{fetch_Instances.run()}}", + "buttonColor": "#60a5fa", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 35.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 19.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "text": "", + "isDisabled": false, + "key": "k10nyfsas3", + "isDeprecated": false, + "rightColumn": 24.0, + "isDefaultClickDisabled": true, + "iconName": "refresh", + "widgetId": "dn1ehe3gvu", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 19.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "ButtonGroup1", + "isCanvas": false, + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button Group", + "iconSVG": "/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "groupButtons": { + "groupButton1": { + "label": "Connect", + "iconName": "camera", + "id": "groupButton1", + "widgetId": "", + "buttonType": "SIMPLE", + "placement": "CENTER", + "isVisible": true, + "isDisabled": false, + "index": 0.0, + "menuItems": {}, + "buttonColor": "#16a34a", + "onClick": "{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}" + }, + "groupButton2": { + "label": "Restart", + "iconName": "reset", + "id": "groupButton2", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 1.0, + "menuItems": {}, + "buttonColor": "#2563eb", + "onClick": "{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}" + }, + "groupButton3": { + "label": "Logout", + "iconName": "log-in", + "id": "groupButton3", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 2.0, + "menuItems": { + "menuItem1": { + "label": "First Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem1", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 0.0 + }, + "menuItem2": { + "label": "Second Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem2", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 1.0 + }, + "menuItem3": { + "label": "Delete", + "iconName": "trash", + "iconColor": "#FFFFFF", + "iconAlign": "right", + "textColor": "#FFFFFF", + "backgroundColor": "#DD4B34", + "id": "menuItem3", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 2.0 + } + }, + "buttonColor": "#a16207", + "onClick": "{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}" + }, + "groupButtonmghcs8rd4g": { + "id": "groupButtonmghcs8rd4g", + "index": 3.0, + "label": "Delete", + "menuItems": {}, + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "v0qkg2pjo2", + "isDisabled": false, + "isVisible": true, + "buttonColor": "#ef4444", + "iconName": "cross", + "onClick": "{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}" + } + }, + "type": "BUTTON_GROUP_WIDGET", + "hideCard": false, + "mobileRightColumn": 51.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [ + { "key": "groupButtons.groupButton1.onClick" }, + { "key": "groupButtons.groupButton2.onClick" }, + { "key": "groupButtons.groupButton3.onClick" }, + { "key": "groupButtons.groupButtonmghcs8rd4g.onClick" } + ], + "leftColumn": 27.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "isDisabled": false, + "key": "za8m3k8x7w", + "orientation": "horizontal", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "2s6fqi483g", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 27.0, + "buttonVariant": "PRIMARY" + }, + { + "boxShadow": "none", + "mobileBottomRow": 18.0, + "widgetName": "ProfilePicture", + "dynamicPropertyPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "displayName": "Image", + "iconSVG": "/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", + "topRow": 6.0, + "bottomRow": 28.0, + "parentRowSpace": 10.0, + "type": "IMAGE_WIDGET", + "hideCard": false, + "mobileRightColumn": 13.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "image" }, + { "key": "isVisible" } + ], + "defaultImage": "https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1", + "key": "bl30j21wwb", + "image": "{{TableInstances.selectedRow.profilePictureUrl}}", + "isDeprecated": false, + "rightColumn": 13.0, + "objectFit": "contain", + "widgetId": "1sjznr31jo", + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 6.0, + "maxZoomLevel": 1.0, + "enableDownload": false, + "borderRadius": "0.335rem", + "mobileLeftColumn": 1.0, + "enableRotation": false + }, + { + "mobileBottomRow": 22.0, + "widgetName": "Text4", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 36.0, + "bottomRow": 42.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 11.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "text" }, + { "key": "isVisible" }, + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}", + "key": "gqt8t28m33", + "isDeprecated": false, + "rightColumn": 13.0, + "textAlign": "CENTER", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "0c356c66hp", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 18.0, + "responsiveBehavior": "fill", + "originalTopRow": 36.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 41.0, + "fontSize": "0.875rem", + "minDynamicHeight": 4.0 + }, + { + "mobileBottomRow": 41.0, + "widgetName": "Text5", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 32.0, + "bottomRow": 36.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 9.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 11.75, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "text" }, + { "key": "isVisible" }, + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{TableInstances.selectedRow.instance || ''}}", + "key": "gqt8t28m33", + "isDeprecated": false, + "rightColumn": 13.0, + "textAlign": "CENTER", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "5qg2iscn1l", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 37.0, + "responsiveBehavior": "fill", + "originalTopRow": 32.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 38.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalWebhook", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 46.0, + "bottomRow": 476.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 430.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 430.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.events.borderRadius" + }, + { + "key": "schema.__root_schema__.children.events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.accentColor" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_by_events.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" + }, + { "key": "borderRadius" }, + { + "key": "schema.__root_schema__.children.events.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.borderRadius" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 41.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "webhook_by_events": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "webhook_by_events", + "identifier": "webhook_by_events", + "position": 3.0, + "originalIdentifier": "webhook_by_events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook By Events" + }, + "enabled": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "enabled", + "identifier": "enabled", + "position": 0.0, + "originalIdentifier": "enabled", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Enabled" + }, + "url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c", + "isCustomField": false, + "accessor": "url", + "identifier": "url", + "position": 1.0, + "originalIdentifier": "url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Url" + }, + "events": { + "children": {}, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Multiselect", + "sourceData": [], + "isCustomField": false, + "accessor": "events", + "identifier": "events", + "position": 2.0, + "originalIdentifier": "events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Events", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": [ + { "label": "Blue", "value": "BLUE" }, + { "label": "Green", "value": "GREEN" }, + { "label": "Red", "value": "RED" } + ] + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormWebhook", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 41.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Webhook", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "tb1ekur7fx", + "minWidth": 450.0, + "parentId": "mv02ta6pzr", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "mv02ta6pzr", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "0g8ql5hukz", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 430.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "0g8ql5hukz", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalSettings", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 46.0, + "bottomRow": 516.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 470.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 470.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.read_status.accentColor" + }, + { + "key": "schema.__root_schema__.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_messages.accentColor" + }, + { + "key": "schema.__root_schema__.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.always_online.accentColor" + }, + { + "key": "schema.__root_schema__.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.accentColor" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.msg_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.msg_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reject_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.reject_call.defaultValue" + }, + { "key": "borderRadius" }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.msg_call.borderRadius" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 45.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "reject_call": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "reject_call", + "identifier": "reject_call", + "position": 0.0, + "originalIdentifier": "reject_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reject Call" + }, + "msg_call": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Não aceitamos chamadas!", + "isCustomField": false, + "accessor": "msg_call", + "identifier": "msg_call", + "position": 1.0, + "originalIdentifier": "msg_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Msg Call" + }, + "groups_ignore": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "groups_ignore", + "identifier": "groups_ignore", + "position": 2.0, + "originalIdentifier": "groups_ignore", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Groups Ignore" + }, + "always_online": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "always_online", + "identifier": "always_online", + "position": 3.0, + "originalIdentifier": "always_online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Always Online" + }, + "read_messages": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "read_messages", + "identifier": "read_messages", + "position": 4.0, + "originalIdentifier": "read_messages", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Messages" + }, + "read_status": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_status", + "identifier": "read_status", + "position": 5.0, + "originalIdentifier": "read_status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Status" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormSettings", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.msg_call.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 45.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Settings", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 64.0, + "widgetId": "3wajdobhry", + "minWidth": 450.0, + "parentId": "bj66ktxeor", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "bj66ktxeor", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "9pvl5efylb", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 470.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "9pvl5efylb", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalChatwoot", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 50.0, + "bottomRow": 780.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 730.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4CopyCopy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 730.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 730.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.conversation_pending.accentColor" + }, + { + "key": "schema.__root_schema__.children.conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.accentColor" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.sign_msg.accentColor" + }, + { + "key": "schema.__root_schema__.children.sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.borderRadius" + }, + { + "key": "schema.__root_schema__.children.url.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.token.accentColor" + }, + { + "key": "schema.__root_schema__.children.token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.account_id.accentColor" + }, + { + "key": "schema.__root_schema__.children.account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.accentColor" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { "key": "borderRadius" }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.account_id.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook_url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_url.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook_url.borderRadius" + }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.name_inbox.defaultValue" + }, + { + "key": "schema.__root_schema__.children.name_inbox.borderRadius" + }, + { + "key": "schema.__root_schema__.children.name_inbox.accentColor" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 71.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "enabled": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "enabled", + "identifier": "enabled", + "position": 0.0, + "originalIdentifier": "enabled", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Enabled" + }, + "account_id": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "4", + "isCustomField": false, + "accessor": "account_id", + "identifier": "account_id", + "position": 1.0, + "originalIdentifier": "account_id", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Account Id" + }, + "token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Password Input", + "sourceData": "uHquVJgCdkee8JPJm9YBkdH6", + "isCustomField": false, + "accessor": "token", + "identifier": "token", + "position": 2.0, + "originalIdentifier": "token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Token", + "shouldAllowAutofill": true + }, + "url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://chatwoot.evolution.dgcode.com.br", + "isCustomField": false, + "accessor": "url", + "identifier": "url", + "position": 3.0, + "originalIdentifier": "url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Url" + }, + "sign_msg": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "sign_msg", + "identifier": "sign_msg", + "position": 4.0, + "originalIdentifier": "sign_msg", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Sign Msg" + }, + "reopen_conversation": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "reopen_conversation", + "identifier": "reopen_conversation", + "position": 5.0, + "originalIdentifier": "reopen_conversation", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reopen Conversation" + }, + "conversation_pending": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "conversation_pending", + "identifier": "conversation_pending", + "position": 6.0, + "originalIdentifier": "conversation_pending", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Conversation Pending" + }, + "webhook_url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4", + "isCustomField": false, + "accessor": "webhook_url", + "identifier": "webhook_url", + "position": 8.0, + "originalIdentifier": "webhook_url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": true, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook Url" + }, + "name_inbox": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "evolution-cwId-4", + "isCustomField": false, + "accessor": "name_inbox", + "identifier": "name_inbox", + "position": 7.0, + "originalIdentifier": "name_inbox", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": true, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Name Inbox" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormChatwoot", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_url.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 71.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Chatwoot", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "c5v1lwuyrk", + "minWidth": 450.0, + "parentId": "wqoo05rt9h", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "wqoo05rt9h", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "kekx3o71p4", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 730.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "kekx3o71p4", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 692.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 50.0, + "widgetName": "Button2", + "onClick": "{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}", + "buttonColor": "#2770fc", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 28.0, + "bottomRow": 32.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 21.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "isVisible" } + ], + "text": "Edit Profile", + "isDisabled": false, + "key": "zhd9fobc1z", + "isDeprecated": false, + "rightColumn": 13.0, + "isDefaultClickDisabled": true, + "iconName": "edit", + "widgetId": "uh6430ysqy", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "responsiveBehavior": "hug", + "originalTopRow": 51.0, + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 5.0, + "originalBottomRow": 55.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 59.0, + "widgetName": "ModalProfile", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 35.0, + "bottomRow": 975.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 940.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas5", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 940.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "submitButtonStyles.buttonColor" }, + { "key": "submitButtonStyles.borderRadius" }, + { "key": "resetButtonStyles.buttonColor" }, + { "key": "resetButtonStyles.borderRadius" }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.profileName.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profileName.accentColor" + }, + { + "key": "schema.__root_schema__.children.profileName.borderRadius" + }, + { + "key": "schema.__root_schema__.children.profileStatus.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profileStatus.accentColor" + }, + { + "key": "schema.__root_schema__.children.profileStatus.borderRadius" + }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.borderRadius" + }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.cellBorderRadius" + } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 92.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "profileName": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "profileName", + "identifier": "profileName", + "position": 1.0, + "originalIdentifier": "profileName", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Name" + }, + "profileStatus": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "profileStatus", + "identifier": "profileStatus", + "position": 2.0, + "originalIdentifier": "profileStatus", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Status" + }, + "profilePictureUrl": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E", + "isCustomField": false, + "accessor": "profilePictureUrl", + "identifier": "profilePictureUrl", + "position": 0.0, + "originalIdentifier": "profilePictureUrl", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Picture Url" + }, + "privacySettings": { + "children": { + "readreceipts": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "readreceipts", + "identifier": "readreceipts", + "position": 0.0, + "originalIdentifier": "readreceipts", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Readreceipts", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "profile": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "profile", + "identifier": "profile", + "position": 1.0, + "originalIdentifier": "profile", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Profile", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "status": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "contacts", + "isCustomField": false, + "accessor": "status", + "identifier": "status", + "position": 2.0, + "originalIdentifier": "status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Status", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "online": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "online", + "identifier": "online", + "position": 3.0, + "originalIdentifier": "online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Online", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]" + }, + "last": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "contacts", + "isCustomField": false, + "accessor": "last", + "identifier": "last", + "position": 4.0, + "originalIdentifier": "last", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Last", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "groupadd": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "groupadd", + "identifier": "groupadd", + "position": 5.0, + "originalIdentifier": "groupadd", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Groupadd", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "readreceipts": "all", + "profile": "all", + "status": "contacts", + "online": "all", + "last": "contacts", + "groupadd": "all" + }, + "isCustomField": false, + "accessor": "privacySettings", + "identifier": "privacySettings", + "position": 3.0, + "originalIdentifier": "privacySettings", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Privacy Settings", + "labelStyle": "BOLD" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormProfile", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [], + "displayName": "JSON Form", + "bottomRow": 92.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Edit Profile", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}", + "resetButtonLabel": "", + "key": "72nqor459k", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 64.0, + "widgetId": "hguxefink2", + "minWidth": 450.0, + "parentId": "basosxf5qt", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "mepf0qsn1e", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "basosxf5qt", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "ss96aihlej", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "4ktj7iym0b", + "height": 940.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "ss96aihlej", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 35.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Page1_Scripts.verifyConfig", + "name": "Scripts.verifyConfig", + "collectionId": "Page1_Scripts", + "clientSideExecution": true, + "confirmBeforeExecute": false, + "pluginType": "JS", + "jsonPathKeys": [ + "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" + ], + "timeoutInMillisecond": 10000.0 + } + ] + ], + "layoutOnLoadActionErrors": [], + "validOnPageLoadActions": true, + "id": "Page1", + "deleted": false, + "policies": [], + "userPermissions": [] + } + ], + "userPermissions": [], + "policies": [] + }, + "publishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "viewMode": false, + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 4896.0, + "snapColumns": 64.0, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0.0, + "bottomRow": 420.0, + "containerStyle": "none", + "snapRows": 124.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 80.0, + "minHeight": 1292.0, + "dynamicTriggerPathList": [], + "parentColumnSpace": 1.0, + "dynamicBindingPathList": [], + "leftColumn": 0.0, + "children": [ + { + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "borderColor": "#E0DEDE", + "isVisibleDownload": true, + "iconSVG": "https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg", + "topRow": 6.0, + "isSortable": true, + "type": "TABLE_WIDGET_V2", + "inlineEditingSaveOption": "ROW_LEVEL", + "animateLoading": true, + "dynamicBindingPathList": [ + { "key": "tableData" }, + { "key": "primaryColumns.customColumn9.boxShadow" }, + { "key": "primaryColumns.customColumn9.borderRadius" }, + { "key": "primaryColumns.customColumn9.menuColor" }, + { "key": "primaryColumns.customColumn8.computedValue" }, + { "key": "primaryColumns.customColumn7.computedValue" }, + { "key": "primaryColumns.customColumn6.computedValue" }, + { "key": "primaryColumns.customColumn5.computedValue" }, + { "key": "primaryColumns.customColumn2.computedValue" }, + { "key": "primaryColumns.customColumn1.textColor" }, + { "key": "primaryColumns.customColumn1.cellBackground" }, + { "key": "primaryColumns.customColumn1.computedValue" }, + { "key": "primaryColumns.instance.computedValue" }, + { "key": "isVisible" }, + { "key": "accentColor" }, + { "key": "borderRadius" }, + { "key": "boxShadow" } + ], + "needsHeightForContent": true, + "leftColumn": 14.0, + "delimiter": ",", + "defaultSelectedRowIndex": 0.0, + "showInlineEditingOptionDropdown": true, + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isVisibleFilters": true, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "enableClientSideSearch": true, + "version": 2.0, + "totalRecordsCount": 0.0, + "isLoading": false, + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "columnUpdatedAt": 1.690746223636e12, + "defaultSelectedRowIndices": [0.0], + "mobileBottomRow": 32.0, + "widgetName": "TableInstances", + "defaultPageSize": 0.0, + "columnOrder": [ + "instance", + "customColumn5", + "customColumn1", + "customColumn2", + "customColumn6", + "customColumn7", + "customColumn8", + "customColumn9" + ], + "dynamicPropertyPathList": [ + { "key": "primaryColumns.customColumn1.cellBackground" }, + { "key": "isVisible" } + ], + "displayName": "Table", + "bottomRow": 42.0, + "columnWidthMap": { + "customColumn3": 92.0, + "customColumn2": 340.0, + "customColumn5": 254.0, + "customColumn9": 97.0 + }, + "parentRowSpace": 10.0, + "hideCard": false, + "mobileRightColumn": 36.0, + "parentColumnSpace": 20.078125, + "dynamicTriggerPathList": [ + { + "key": "primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick" + }, + { + "key": "primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick" + }, + { + "key": "primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick" + } + ], + "borderWidth": "1", + "primaryColumns": { + "instance": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 0.0, + "width": 150.0, + "originalId": "instance", + "id": "instance", + "alias": "instance", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "Instance", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}", + "sticky": "", + "validation": {} + }, + "customColumn1": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 1.0, + "width": 150.0, + "originalId": "customColumn1", + "id": "customColumn1", + "alias": "Status", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Status", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF", + "cellBackground": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}", + "textColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}" + }, + "customColumn2": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 2.0, + "width": 150.0, + "originalId": "customColumn2", + "id": "customColumn2", + "alias": "Apikey", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Apikey", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn5": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 5.0, + "width": 150.0, + "originalId": "customColumn5", + "id": "customColumn5", + "alias": "Owner", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Owner", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn6": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 6.0, + "width": 150.0, + "originalId": "customColumn6", + "id": "customColumn6", + "alias": "profilePictureUrl", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profilePictureUrl", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn7": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 7.0, + "width": 150.0, + "originalId": "customColumn7", + "id": "customColumn7", + "alias": "profileName", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profileName", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn8": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 8.0, + "width": 150.0, + "originalId": "customColumn8", + "id": "customColumn8", + "alias": "profileStatus", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": false, + "isDerived": true, + "label": "profileStatus", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF" + }, + "customColumn9": { + "allowCellWrapping": false, + "allowSameOptionsInNewRow": true, + "index": 9.0, + "width": 150.0, + "originalId": "customColumn9", + "id": "customColumn9", + "alias": "Actions", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "menuButton", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Actions", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "", + "sticky": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "labelColor": "#FFFFFF", + "menuColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}", + "borderRadius": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}", + "boxShadow": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}", + "customAlias": "", + "menuItemsSource": "STATIC", + "menuButtonLabel": " ", + "menuButtoniconName": "chevron-down", + "menuItems": { + "menuItemjfzsd8g6yr": { + "id": "menuItemjfzsd8g6yr", + "index": 0.0, + "label": "Webhook", + "widgetId": "vygcejtdun", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Webhook.run();\nshowModal('ModalWebhook');}}" + }, + "menuItem4sqork5nmt": { + "id": "menuItem4sqork5nmt", + "index": 1.0, + "label": "Settings", + "widgetId": "0hw8oqpwcj", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Settings.run();\nshowModal('ModalSettings');}}" + }, + "menuItemig6ua4ixjx": { + "id": "menuItemig6ua4ixjx", + "index": 2.0, + "label": "Chatwoot", + "widgetId": "fuq5dtgbqc", + "isDisabled": false, + "isVisible": true, + "onClick": "{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}" + } + } + } + }, + "key": "e3yxhhyeel", + "canFreezeColumn": true, + "isDeprecated": false, + "rightColumn": 63.0, + "textSize": "0.875rem", + "widgetId": "uupm7enu8u", + "minWidth": 450.0, + "tableData": "{{fetch_Instances.data}}", + "label": "Data", + "searchKey": "", + "parentId": "0", + "renderMode": "CANVAS", + "mobileTopRow": 4.0, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "isVisiblePagination": true, + "verticalAlignment": "CENTER" + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "BtnNewInstance", + "onClick": "{{showModal('ModalInstance');}}", + "buttonColor": "rgb(3, 179, 101)", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 8.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 7.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "text": "New Instance", + "isDisabled": false, + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 19.0, + "isDefaultClickDisabled": true, + "iconName": "add", + "widgetId": "84ei9q1ugm", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 74.0, + "widgetName": "ModalQrcode", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 50.0, + "bottomRow": 500.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 45.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "leftColumn": 21.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 450.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 52.0, + "widgetName": "ImageQrcode", + "displayName": "Image", + "iconSVG": "https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", + "topRow": 6.0, + "bottomRow": 43.0, + "parentRowSpace": 10.0, + "type": "IMAGE_WIDGET", + "hideCard": false, + "mobileRightColumn": 55.0, + "animateLoading": true, + "parentColumnSpace": 20.078125, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "image" }, + { "key": "borderRadius" } + ], + "defaultImage": "https://evolution-api.com/files/evolution-api-favicon.png", + "key": "4chlj9l432", + "image": "{{Connect.data.base64}}", + "isDeprecated": false, + "rightColumn": 61.0, + "objectFit": "contain", + "widgetId": "27dpgapd7q", + "isVisible": true, + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 40.0, + "maxZoomLevel": 1.0, + "enableDownload": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 43.0, + "enableRotation": false + }, + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton1", + "onClick": "{{closeModal('ModalQrcode');\nfetch_Instances.run()}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 58.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "iconSize": 24.0, + "isDisabled": false, + "key": "pezy0hb491", + "isDeprecated": false, + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "i1dw369dch", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 58.0, + "buttonVariant": "TERTIARY" + }, + { + "mobileBottomRow": 5.0, + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 41.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "fontFamily" }], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "Qrcode", + "key": "9s8f10sepn", + "isDeprecated": false, + "rightColumn": 41.0, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "mg2cqsi9fn", + "minWidth": 450.0, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "we6j3r2byy", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "we6j3r2byy", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "ljwryrjhy7", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "g8xx6ocuvi", + "height": 450.0, + "isDeprecated": false, + "rightColumn": 45.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "ljwryrjhy7", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 50.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 21.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "BtnConfig", + "onClick": "{{showModal('ModalConfig');}}", + "buttonColor": "#2563eb", + "dynamicPropertyPathList": [], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 30.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "text": "Access", + "isDisabled": false, + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 7.0, + "isDefaultClickDisabled": true, + "iconName": "user", + "widgetId": "uegjpy37i6", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 14.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 73.0, + "widgetName": "ModalConfig", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 49.0, + "bottomRow": 30.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 25.0, + "minHeight": 300.0, + "animateLoading": true, + "parentColumnSpace": 11.75, + "leftColumn": 1.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas2", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 300.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 300.0, + "mobileRightColumn": 282.0, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 84.0, + "borderColor": "#E0DEDE", + "widgetName": "FormConfig", + "isCanvas": true, + "displayName": "Form", + "iconSVG": "/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg", + "searchTags": ["group"], + "topRow": 0.0, + "bottomRow": 28.0, + "parentRowSpace": 10.0, + "type": "FORM_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 25.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [], + "children": [ + { + "mobileBottomRow": 400.0, + "widgetName": "Canvas2Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 280.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "minHeight": 400.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "mobileBottomRow": 5.0, + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 1.0, + "bottomRow": 5.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 25.5, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "dynamicTriggerPathList": [], + "leftColumn": 1.5, + "dynamicBindingPathList": [ + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "Access Credentials", + "key": "9s8f10sepn", + "isDeprecated": false, + "rightColumn": 25.5, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "tps5rw2lk9", + "minWidth": 450.0, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.5, + "maxDynamicHeight": 9000.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + }, + { + "resetFormOnClick": true, + "boxShadow": "none", + "mobileBottomRow": 37.0, + "widgetName": "Button1", + "onClick": "{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "dynamicPropertyPathList": [ + { "key": "isDisabled" } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 22.0, + "bottomRow": 26.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 62.0, + "animateLoading": true, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 51.0, + "dynamicBindingPathList": [ + { "key": "isDisabled" }, + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "text": "Login", + "isDisabled": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 63.0, + "isDefaultClickDisabled": true, + "iconName": "log-in", + "widgetId": "gzxvnsxk0y", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 33.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 46.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "resetFormOnClick": true, + "boxShadow": "none", + "mobileBottomRow": 37.0, + "widgetName": "Button1Copy", + "onClick": "{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}", + "buttonColor": "#dc2626", + "dynamicPropertyPathList": [ + { "key": "isDisabled" } + ], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 21.0, + "bottomRow": 25.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 62.0, + "animateLoading": true, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "isDisabled" }, + { "key": "borderRadius" } + ], + "text": "Logout", + "isDisabled": "{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}", + "key": "crzwqv3pdr", + "isDeprecated": false, + "rightColumn": 14.0, + "isDefaultClickDisabled": true, + "iconName": "log-out", + "widgetId": "f2i8tsbgx1", + "minWidth": 120.0, + "isVisible": true, + "recaptchaType": "V3", + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 33.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 46.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", + "topRow": 6.0, + "labelWidth": 5.0, + "type": "INPUT_WIDGET_V2", + "animateLoading": true, + "resetOnSubmit": true, + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "defaultText" }, + { "key": "accentColor" }, + { "key": "borderRadius" } + ], + "labelStyle": "", + "inputType": "TEXT", + "placeholderText": "", + "isDisabled": false, + "isRequired": true, + "dynamicHeight": "FIXED", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "showStepArrows": false, + "isVisible": true, + "version": 2.0, + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileBottomRow": 13.0, + "widgetName": "InputApiUrl", + "displayName": "Input", + "searchTags": [ + "form", + "text input", + "number", + "textarea" + ], + "bottomRow": 13.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "hideCard": false, + "mobileRightColumn": 22.0, + "parentColumnSpace": 5.047119140625, + "dynamicTriggerPathList": [], + "labelPosition": "Top", + "key": "r1hfat3ouf", + "labelTextSize": "0.875rem", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "spgryrb5ao", + "minWidth": 450.0, + "label": "API URL", + "parentId": "lrtvcpswru", + "labelAlignment": "left", + "renderMode": "CANVAS", + "mobileTopRow": 6.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "maxDynamicHeight": 9000.0, + "isSpellCheck": false, + "iconAlign": "left", + "defaultText": "{{appsmith.store.api_url || ''}}", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", + "topRow": 14.0, + "labelWidth": 5.0, + "type": "INPUT_WIDGET_V2", + "animateLoading": true, + "resetOnSubmit": true, + "leftColumn": 2.0, + "dynamicBindingPathList": [ + { "key": "defaultText" }, + { "key": "accentColor" }, + { "key": "borderRadius" } + ], + "labelStyle": "", + "inputType": "PASSWORD", + "isDisabled": false, + "isRequired": true, + "dynamicHeight": "FIXED", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "showStepArrows": false, + "isVisible": true, + "version": 2.0, + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileBottomRow": 13.0, + "widgetName": "InputGlobalApiKey", + "displayName": "Input", + "searchTags": [ + "form", + "text input", + "number", + "textarea" + ], + "bottomRow": 21.0, + "parentRowSpace": 10.0, + "autoFocus": false, + "hideCard": false, + "mobileRightColumn": 22.0, + "parentColumnSpace": 5.047119140625, + "dynamicTriggerPathList": [], + "labelPosition": "Top", + "key": "r1hfat3ouf", + "labelTextSize": "0.875rem", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "v2vedr13py", + "minWidth": 450.0, + "label": "GLOBAL API KEY", + "parentId": "lrtvcpswru", + "labelAlignment": "left", + "renderMode": "CANVAS", + "mobileTopRow": 6.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 2.0, + "maxDynamicHeight": 9000.0, + "shouldAllowAutofill": true, + "iconAlign": "left", + "defaultText": "{{appsmith.store.api_key || ''}}", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton2", + "onClick": "{{closeModal('ModalConfig');}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "parentRowSpace": 10.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "parentColumnSpace": 9.072265625, + "dynamicTriggerPathList": [ + { "key": "onClick" } + ], + "leftColumn": 60.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "isDisabled": false, + "key": "pezy0hb491", + "isDeprecated": false, + "rightColumn": 64.0, + "iconName": "cross", + "widgetId": "oaouelmhi1", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "lrtvcpswru", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 60.0, + "buttonVariant": "TERTIARY" + } + ], + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "lrtvcpswru", + "containerStyle": "none", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "h97rbttd5c", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "borderWidth": "0", + "positioning": "fixed", + "key": "dtzd07zsya", + "backgroundColor": "#FFFFFF", + "isDeprecated": false, + "rightColumn": 63.0, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "h97rbttd5c", + "minWidth": 450.0, + "isVisible": true, + "parentId": "es5gsctogb", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 44.0, + "responsiveBehavior": "fill", + "originalTopRow": 0.0, + "borderRadius": "0.375rem", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 28.0, + "minDynamicHeight": 10.0 + } + ], + "isDisabled": false, + "key": "e8r23nd8j4", + "isDeprecated": false, + "rightColumn": 282.0, + "detachFromLayout": true, + "widgetId": "es5gsctogb", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "gneh33z88k", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "g8xx6ocuvi", + "height": 300.0, + "isDeprecated": false, + "rightColumn": 25.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "gneh33z88k", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 49.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 1.0, + "maxDynamicHeight": 9000.0, + "width": 632.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 66.0, + "widgetName": "ModalInstance", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 42.0, + "bottomRow": 149.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 37.0, + "minHeight": 1490.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "leftColumn": 13.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas3", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 1490.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 1140.0, + "mobileRightColumn": 283.875, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "mobileBottomRow": 4.0, + "widgetName": "IconButton3Copy", + "onClick": "{{closeModal('ModalInstance');}}", + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "displayName": "Icon button", + "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", + "searchTags": ["click", "submit"], + "topRow": 0.0, + "bottomRow": 4.0, + "type": "ICON_BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 64.0, + "animateLoading": true, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 57.0, + "dynamicBindingPathList": [ + { "key": "buttonColor" }, + { "key": "borderRadius" } + ], + "iconSize": 24.0, + "isDisabled": false, + "key": "mr6bto7c8j", + "isDeprecated": false, + "rightColumn": 63.0, + "iconName": "cross", + "widgetId": "xofakp4har", + "minWidth": 50.0, + "isVisible": true, + "version": 1.0, + "parentId": "esgwuzqcwt", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "hug", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 58.0, + "buttonVariant": "TERTIARY" + }, + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}", + "topRow": 4.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "resetButtonStyles.buttonColor" }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.children.webhook.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.borderRadius" + }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.borderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.instanceName.borderRadius" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook.children.events.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.borderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.msg_call.borderRadius" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.accentColor" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.accentColor" + } + ], + "showReset": true, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY", + "iconAlign": "left" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Create", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 143.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "webhook": { + "children": { + "webhook": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "webhook", + "identifier": "webhook", + "position": 0.0, + "originalIdentifier": "webhook", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook" + }, + "events": { + "children": {}, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Multiselect", + "sourceData": [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN" + ], + "isCustomField": false, + "accessor": "events", + "identifier": "events", + "position": 2.0, + "originalIdentifier": "events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Events", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]" + }, + "webhook_by_events": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "webhook_by_events", + "identifier": "webhook_by_events", + "position": 2.0, + "originalIdentifier": "webhook_by_events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook By Events" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "webhook", + "identifier": "webhook", + "position": 1.0, + "originalIdentifier": "webhook", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Webhook", + "labelStyle": "BOLD" + }, + "instance": { + "children": { + "instanceName": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "instanceName", + "identifier": "instanceName", + "position": 0.0, + "originalIdentifier": "instanceName", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Instance Name" + }, + "token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "token", + "identifier": "token", + "position": 1.0, + "originalIdentifier": "token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Token" + }, + "qrcode": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "qrcode", + "identifier": "qrcode", + "position": 2.0, + "originalIdentifier": "qrcode", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Qrcode" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "instance", + "identifier": "instance", + "position": 0.0, + "originalIdentifier": "instance", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Instance", + "labelStyle": "BOLD" + }, + "settings": { + "children": { + "reject_call": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "reject_call", + "identifier": "reject_call", + "position": 0.0, + "originalIdentifier": "reject_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reject Call" + }, + "msg_call": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "msg_call", + "identifier": "msg_call", + "position": 1.0, + "originalIdentifier": "msg_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Msg Call" + }, + "groups_ignore": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "groups_ignore", + "identifier": "groups_ignore", + "position": 2.0, + "originalIdentifier": "groups_ignore", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Groups Ignore" + }, + "always_online": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "always_online", + "identifier": "always_online", + "position": 3.0, + "originalIdentifier": "always_online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Always Online" + }, + "read_messages": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_messages", + "identifier": "read_messages", + "position": 4.0, + "originalIdentifier": "read_messages", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Messages" + }, + "read_status": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_status", + "identifier": "read_status", + "position": 5.0, + "originalIdentifier": "read_status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Status" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "settings", + "identifier": "settings", + "position": 2.0, + "originalIdentifier": "settings", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Settings", + "labelStyle": "BOLD" + }, + "chatwoot": { + "children": { + "chatwoot_account_id": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_account_id", + "identifier": "chatwoot_account_id", + "position": 0.0, + "originalIdentifier": "chatwoot_account_id", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Account Id" + }, + "chatwoot_token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Password Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_token", + "identifier": "chatwoot_token", + "position": 1.0, + "originalIdentifier": "chatwoot_token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Token", + "shouldAllowAutofill": true + }, + "chatwoot_url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "chatwoot_url", + "identifier": "chatwoot_url", + "position": 2.0, + "originalIdentifier": "chatwoot_url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Url" + }, + "chatwoot_sign_msg": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_sign_msg", + "identifier": "chatwoot_sign_msg", + "position": 3.0, + "originalIdentifier": "chatwoot_sign_msg", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Sign Msg" + }, + "chatwoot_reopen_conversation": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_reopen_conversation", + "identifier": "chatwoot_reopen_conversation", + "position": 4.0, + "originalIdentifier": "chatwoot_reopen_conversation", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Reopen Conversation" + }, + "chatwoot_conversation_pending": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "chatwoot_conversation_pending", + "identifier": "chatwoot_conversation_pending", + "position": 5.0, + "originalIdentifier": "chatwoot_conversation_pending", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Chatwoot Conversation Pending" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": {}, + "isCustomField": false, + "accessor": "chatwoot", + "identifier": "chatwoot", + "position": 3.0, + "originalIdentifier": "chatwoot", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Chatwoot", + "labelStyle": "BOLD" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "instanceName": "", + "token": "", + "webhook": "", + "webhook_by_events": false, + "events": [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN" + ], + "reject_call": false, + "msg_call": "", + "groups_ignore": false, + "always_online": false, + "read_messages": false, + "read_status": false, + "chatwoot_account_id": "", + "chatwoot_token": "", + "chatwoot_url": "", + "chatwoot_sign_msg": false, + "chatwoot_reopen_conversation": false, + "chatwoot_conversation_pending": false + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 85.0, + "widgetName": "FormInstance", + "submitButtonStyles": { + "buttonColor": "rgb(3, 179, 101)", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 147.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "New Instance", + "hideCard": false, + "mobileRightColumn": 22.0, + "shouldScrollContents": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "o0v8ypwnya", + "minWidth": 450.0, + "parentId": "esgwuzqcwt", + "renderMode": "CANVAS", + "mobileTopRow": 44.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 4.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "w17ra2a85u", + "isDeprecated": false, + "rightColumn": 283.875, + "detachFromLayout": true, + "widgetId": "esgwuzqcwt", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "rnttu90jzr", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "bkvkzj4d20", + "height": 1490.0, + "isDeprecated": false, + "rightColumn": 37.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "rnttu90jzr", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 42.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 13.0, + "maxDynamicHeight": 9000.0, + "width": 628.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "ButtonRefreshData", + "onClick": "{{fetch_Instances.run()}}", + "buttonColor": "#60a5fa", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 35.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 19.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "text": "", + "isDisabled": false, + "key": "k10nyfsas3", + "isDeprecated": false, + "rightColumn": 24.0, + "isDefaultClickDisabled": true, + "iconName": "refresh", + "widgetId": "dn1ehe3gvu", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "hug", + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 19.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 5.0, + "widgetName": "ButtonGroup1", + "isCanvas": false, + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button Group", + "iconSVG": "/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg", + "searchTags": ["click", "submit"], + "topRow": 1.0, + "bottomRow": 5.0, + "parentRowSpace": 10.0, + "groupButtons": { + "groupButton1": { + "label": "Connect", + "iconName": "camera", + "id": "groupButton1", + "widgetId": "", + "buttonType": "SIMPLE", + "placement": "CENTER", + "isVisible": true, + "isDisabled": false, + "index": 0.0, + "menuItems": {}, + "buttonColor": "#16a34a", + "onClick": "{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}" + }, + "groupButton2": { + "label": "Restart", + "iconName": "reset", + "id": "groupButton2", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 1.0, + "menuItems": {}, + "buttonColor": "#2563eb", + "onClick": "{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}" + }, + "groupButton3": { + "label": "Logout", + "iconName": "log-in", + "id": "groupButton3", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 2.0, + "menuItems": { + "menuItem1": { + "label": "First Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem1", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 0.0 + }, + "menuItem2": { + "label": "Second Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem2", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 1.0 + }, + "menuItem3": { + "label": "Delete", + "iconName": "trash", + "iconColor": "#FFFFFF", + "iconAlign": "right", + "textColor": "#FFFFFF", + "backgroundColor": "#DD4B34", + "id": "menuItem3", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 2.0 + } + }, + "buttonColor": "#a16207", + "onClick": "{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}" + }, + "groupButtonmghcs8rd4g": { + "id": "groupButtonmghcs8rd4g", + "index": 3.0, + "label": "Delete", + "menuItems": {}, + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "v0qkg2pjo2", + "isDisabled": false, + "isVisible": true, + "buttonColor": "#ef4444", + "iconName": "cross", + "onClick": "{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}" + } + }, + "type": "BUTTON_GROUP_WIDGET", + "hideCard": false, + "mobileRightColumn": 51.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [ + { "key": "groupButtons.groupButton1.onClick" }, + { "key": "groupButtons.groupButton2.onClick" }, + { "key": "groupButtons.groupButton3.onClick" }, + { "key": "groupButtons.groupButtonmghcs8rd4g.onClick" } + ], + "leftColumn": 27.0, + "dynamicBindingPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "isDisabled": false, + "key": "za8m3k8x7w", + "orientation": "horizontal", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "2s6fqi483g", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 1.0, + "responsiveBehavior": "fill", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 27.0, + "buttonVariant": "PRIMARY" + }, + { + "boxShadow": "none", + "mobileBottomRow": 18.0, + "widgetName": "ProfilePicture", + "dynamicPropertyPathList": [ + { "key": "isVisible" }, + { "key": "borderRadius" } + ], + "displayName": "Image", + "iconSVG": "/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", + "topRow": 6.0, + "bottomRow": 28.0, + "parentRowSpace": 10.0, + "type": "IMAGE_WIDGET", + "hideCard": false, + "mobileRightColumn": 13.0, + "animateLoading": true, + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "imageShape": "RECTANGLE", + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "image" }, + { "key": "isVisible" } + ], + "defaultImage": "https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1", + "key": "bl30j21wwb", + "image": "{{TableInstances.selectedRow.profilePictureUrl}}", + "isDeprecated": false, + "rightColumn": 13.0, + "objectFit": "contain", + "widgetId": "1sjznr31jo", + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 6.0, + "maxZoomLevel": 1.0, + "enableDownload": false, + "borderRadius": "0.335rem", + "mobileLeftColumn": 1.0, + "enableRotation": false + }, + { + "mobileBottomRow": 22.0, + "widgetName": "Text4", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 36.0, + "bottomRow": 41.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 11.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 11.828125, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "text" }, + { "key": "isVisible" }, + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}", + "key": "gqt8t28m33", + "isDeprecated": false, + "rightColumn": 13.0, + "textAlign": "CENTER", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "0c356c66hp", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 18.0, + "responsiveBehavior": "fill", + "originalTopRow": 36.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 42.0, + "fontSize": "0.875rem", + "minDynamicHeight": 4.0 + }, + { + "mobileBottomRow": 41.0, + "widgetName": "Text5", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Text", + "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", + "searchTags": ["typography", "paragraph", "label"], + "topRow": 32.0, + "bottomRow": 36.0, + "parentRowSpace": 10.0, + "type": "TEXT_WIDGET", + "hideCard": false, + "mobileRightColumn": 9.0, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 11.75, + "dynamicTriggerPathList": [], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "text" }, + { "key": "isVisible" }, + { "key": "fontFamily" } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{TableInstances.selectedRow.instance || ''}}", + "key": "gqt8t28m33", + "isDeprecated": false, + "rightColumn": 13.0, + "textAlign": "CENTER", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "5qg2iscn1l", + "minWidth": 450.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 37.0, + "responsiveBehavior": "fill", + "originalTopRow": 32.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "originalBottomRow": 38.0, + "fontSize": "1.25rem", + "minDynamicHeight": 4.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalWebhook", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 46.0, + "bottomRow": 43.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 430.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 430.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.events.borderRadius" + }, + { + "key": "schema.__root_schema__.children.events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.accentColor" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_by_events.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" + }, + { "key": "borderRadius" }, + { + "key": "schema.__root_schema__.children.events.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.borderRadius" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 41.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "webhook_by_events": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "webhook_by_events", + "identifier": "webhook_by_events", + "position": 3.0, + "originalIdentifier": "webhook_by_events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook By Events" + }, + "enabled": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "enabled", + "identifier": "enabled", + "position": 0.0, + "originalIdentifier": "enabled", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Enabled" + }, + "url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c", + "isCustomField": false, + "accessor": "url", + "identifier": "url", + "position": 1.0, + "originalIdentifier": "url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Url" + }, + "events": { + "children": {}, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Multiselect", + "sourceData": [], + "isCustomField": false, + "accessor": "events", + "identifier": "events", + "position": 2.0, + "originalIdentifier": "events", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Events", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": [ + { "label": "Blue", "value": "BLUE" }, + { "label": "Green", "value": "GREEN" }, + { "label": "Red", "value": "RED" } + ] + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormWebhook", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 41.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Webhook", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "tb1ekur7fx", + "minWidth": 450.0, + "parentId": "mv02ta6pzr", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "mv02ta6pzr", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "0g8ql5hukz", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 430.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "0g8ql5hukz", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalSettings", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 46.0, + "bottomRow": 47.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 470.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4Copy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 470.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.read_status.accentColor" + }, + { + "key": "schema.__root_schema__.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_messages.accentColor" + }, + { + "key": "schema.__root_schema__.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.always_online.accentColor" + }, + { + "key": "schema.__root_schema__.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.accentColor" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.msg_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.msg_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reject_call.accentColor" + }, + { + "key": "schema.__root_schema__.children.reject_call.defaultValue" + }, + { "key": "borderRadius" }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.msg_call.borderRadius" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 45.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "reject_call": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "reject_call", + "identifier": "reject_call", + "position": 0.0, + "originalIdentifier": "reject_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reject Call" + }, + "msg_call": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Não aceitamos chamadas!", + "isCustomField": false, + "accessor": "msg_call", + "identifier": "msg_call", + "position": 1.0, + "originalIdentifier": "msg_call", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Msg Call" + }, + "groups_ignore": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "groups_ignore", + "identifier": "groups_ignore", + "position": 2.0, + "originalIdentifier": "groups_ignore", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Groups Ignore" + }, + "always_online": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "always_online", + "identifier": "always_online", + "position": 3.0, + "originalIdentifier": "always_online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Always Online" + }, + "read_messages": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "read_messages", + "identifier": "read_messages", + "position": 4.0, + "originalIdentifier": "read_messages", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Messages" + }, + "read_status": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "read_status", + "identifier": "read_status", + "position": 5.0, + "originalIdentifier": "read_status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Read Status" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormSettings", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.reject_call.defaultValue" + }, + { + "key": "schema.__root_schema__.children.groups_ignore.defaultValue" + }, + { + "key": "schema.__root_schema__.children.always_online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_messages.defaultValue" + }, + { + "key": "schema.__root_schema__.children.read_status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.msg_call.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 45.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Settings", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 64.0, + "widgetId": "3wajdobhry", + "minWidth": 450.0, + "parentId": "bj66ktxeor", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "bj66ktxeor", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "9pvl5efylb", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 470.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "9pvl5efylb", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + }, + { + "boxShadow": "none", + "mobileBottomRow": 70.0, + "widgetName": "ModalChatwoot", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 50.0, + "bottomRow": 73.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 730.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas4CopyCopy", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 730.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 730.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.conversation_pending.accentColor" + }, + { + "key": "schema.__root_schema__.children.conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.accentColor" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.sign_msg.accentColor" + }, + { + "key": "schema.__root_schema__.children.sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.url.borderRadius" + }, + { + "key": "schema.__root_schema__.children.url.accentColor" + }, + { + "key": "schema.__root_schema__.children.url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.token.borderRadius" + }, + { + "key": "schema.__root_schema__.children.token.accentColor" + }, + { + "key": "schema.__root_schema__.children.token.defaultValue" + }, + { + "key": "schema.__root_schema__.children.account_id.accentColor" + }, + { + "key": "schema.__root_schema__.children.account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.enabled.accentColor" + }, + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { "key": "borderRadius" }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.account_id.borderRadius" + }, + { + "key": "schema.__root_schema__.children.webhook_url.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_url.accentColor" + }, + { + "key": "schema.__root_schema__.children.webhook_url.borderRadius" + }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.name_inbox.defaultValue" + }, + { + "key": "schema.__root_schema__.children.name_inbox.borderRadius" + }, + { + "key": "schema.__root_schema__.children.name_inbox.accentColor" + }, + { "key": "submitButtonStyles.buttonColor" } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 71.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "enabled": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "enabled", + "identifier": "enabled", + "position": 0.0, + "originalIdentifier": "enabled", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Enabled" + }, + "account_id": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "4", + "isCustomField": false, + "accessor": "account_id", + "identifier": "account_id", + "position": 1.0, + "originalIdentifier": "account_id", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Account Id" + }, + "token": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Password Input", + "sourceData": "uHquVJgCdkee8JPJm9YBkdH6", + "isCustomField": false, + "accessor": "token", + "identifier": "token", + "position": 2.0, + "originalIdentifier": "token", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Token", + "shouldAllowAutofill": true + }, + "url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://chatwoot.evolution.dgcode.com.br", + "isCustomField": false, + "accessor": "url", + "identifier": "url", + "position": 3.0, + "originalIdentifier": "url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Url" + }, + "sign_msg": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "sign_msg", + "identifier": "sign_msg", + "position": 4.0, + "originalIdentifier": "sign_msg", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Sign Msg" + }, + "reopen_conversation": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": true, + "isCustomField": false, + "accessor": "reopen_conversation", + "identifier": "reopen_conversation", + "position": 5.0, + "originalIdentifier": "reopen_conversation", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Reopen Conversation" + }, + "conversation_pending": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "conversation_pending", + "identifier": "conversation_pending", + "position": 6.0, + "originalIdentifier": "conversation_pending", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Conversation Pending" + }, + "webhook_url": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4", + "isCustomField": false, + "accessor": "webhook_url", + "identifier": "webhook_url", + "position": 8.0, + "originalIdentifier": "webhook_url", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": true, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Webhook Url" + }, + "name_inbox": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "evolution-cwId-4", + "isCustomField": false, + "accessor": "name_inbox", + "identifier": "name_inbox", + "position": 7.0, + "originalIdentifier": "name_inbox", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": true, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Name Inbox" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormChatwoot", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.enabled.defaultValue" + }, + { + "key": "schema.__root_schema__.children.sign_msg.defaultValue" + }, + { + "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" + }, + { + "key": "schema.__root_schema__.children.conversation_pending.defaultValue" + }, + { + "key": "schema.__root_schema__.children.account_id.defaultValue" + }, + { + "key": "schema.__root_schema__.children.webhook_url.defaultValue" + } + ], + "displayName": "JSON Form", + "bottomRow": 71.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Chatwoot", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}", + "resetButtonLabel": "Reset", + "key": "lgqqk5r1jk", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 63.0, + "widgetId": "c5v1lwuyrk", + "minWidth": 450.0, + "parentId": "wqoo05rt9h", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "svq68rvpdn", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "wqoo05rt9h", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "kekx3o71p4", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "6x3z5yow7u", + "height": 730.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "kekx3o71p4", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 692.0, + "minDynamicHeight": 24.0 + }, + { + "resetFormOnClick": false, + "boxShadow": "none", + "mobileBottomRow": 50.0, + "widgetName": "Button2", + "onClick": "{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}", + "buttonColor": "#2770fc", + "dynamicPropertyPathList": [{ "key": "isVisible" }], + "displayName": "Button", + "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", + "searchTags": ["click", "submit"], + "topRow": 28.0, + "bottomRow": 32.0, + "parentRowSpace": 10.0, + "type": "BUTTON_WIDGET", + "hideCard": false, + "mobileRightColumn": 21.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [{ "key": "onClick" }], + "leftColumn": 1.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "isVisible" } + ], + "text": "Edit Profile", + "isDisabled": false, + "key": "zhd9fobc1z", + "isDeprecated": false, + "rightColumn": 13.0, + "isDefaultClickDisabled": true, + "iconName": "edit", + "widgetId": "uh6430ysqy", + "minWidth": 120.0, + "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}", + "recaptchaType": "V3", + "version": 1.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 46.0, + "responsiveBehavior": "hug", + "originalTopRow": 51.0, + "disabledWhenInvalid": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 5.0, + "originalBottomRow": 55.0, + "buttonVariant": "PRIMARY", + "iconAlign": "left", + "placement": "CENTER" + }, + { + "boxShadow": "none", + "mobileBottomRow": 59.0, + "widgetName": "ModalProfile", + "isCanvas": true, + "displayName": "Modal", + "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", + "searchTags": ["dialog", "popup", "notification"], + "topRow": 35.0, + "bottomRow": 94.0, + "parentRowSpace": 10.0, + "type": "MODAL_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "mobileRightColumn": 35.0, + "minHeight": 940.0, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 11.0, + "dynamicBindingPathList": [{ "key": "borderRadius" }], + "children": [ + { + "mobileBottomRow": 240.0, + "widgetName": "Canvas5", + "displayName": "Canvas", + "topRow": 0.0, + "bottomRow": 940.0, + "parentRowSpace": 1.0, + "type": "CANVAS_WIDGET", + "canExtend": true, + "hideCard": true, + "shouldScrollContents": false, + "minHeight": 240.0, + "mobileRightColumn": 430.5, + "parentColumnSpace": 1.0, + "leftColumn": 0.0, + "dynamicBindingPathList": [], + "children": [ + { + "boxShadow": "none", + "borderColor": "#E0DEDE", + "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", + "onSubmit": "{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}", + "topRow": 0.0, + "type": "JSON_FORM_WIDGET", + "animateLoading": true, + "leftColumn": 0.0, + "dynamicBindingPathList": [ + { "key": "borderRadius" }, + { "key": "submitButtonStyles.buttonColor" }, + { "key": "submitButtonStyles.borderRadius" }, + { "key": "resetButtonStyles.buttonColor" }, + { "key": "resetButtonStyles.borderRadius" }, + { "key": "schema.__root_schema__.defaultValue" }, + { "key": "schema.__root_schema__.borderRadius" }, + { + "key": "schema.__root_schema__.cellBorderRadius" + }, + { + "key": "schema.__root_schema__.children.profileName.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profileName.accentColor" + }, + { + "key": "schema.__root_schema__.children.profileName.borderRadius" + }, + { + "key": "schema.__root_schema__.children.profileStatus.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profileStatus.accentColor" + }, + { + "key": "schema.__root_schema__.children.profileStatus.borderRadius" + }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.defaultValue" + }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.borderRadius" + }, + { "key": "sourceData" }, + { + "key": "schema.__root_schema__.children.profilePictureUrl.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.profile.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.status.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.online.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.last.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.accentColor" + }, + { + "key": "schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.defaultValue" + }, + { + "key": "schema.__root_schema__.children.privacySettings.borderRadius" + }, + { + "key": "schema.__root_schema__.children.privacySettings.cellBorderRadius" + } + ], + "showReset": false, + "dynamicHeight": "AUTO_HEIGHT", + "autoGenerateForm": true, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1.0, + "isLoading": false, + "submitButtonLabel": "Save", + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + }, + "disabledWhenInvalid": true, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "originalBottomRow": 92.0, + "useSourceData": false, + "schema": { + "__root_schema__": { + "children": { + "profileName": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "profileName", + "identifier": "profileName", + "position": 1.0, + "originalIdentifier": "profileName", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Name" + }, + "profileStatus": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "", + "isCustomField": false, + "accessor": "profileStatus", + "identifier": "profileStatus", + "position": 2.0, + "originalIdentifier": "profileStatus", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Status" + }, + "profilePictureUrl": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E", + "isCustomField": false, + "accessor": "profilePictureUrl", + "identifier": "profilePictureUrl", + "position": 0.0, + "originalIdentifier": "profilePictureUrl", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "Profile Picture Url" + }, + "privacySettings": { + "children": { + "readreceipts": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "readreceipts", + "identifier": "readreceipts", + "position": 0.0, + "originalIdentifier": "readreceipts", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Readreceipts", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "profile": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "profile", + "identifier": "profile", + "position": 1.0, + "originalIdentifier": "profile", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Profile", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "status": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "contacts", + "isCustomField": false, + "accessor": "status", + "identifier": "status", + "position": 2.0, + "originalIdentifier": "status", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Status", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "online": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "online", + "identifier": "online", + "position": 3.0, + "originalIdentifier": "online", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Online", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]" + }, + "last": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "contacts", + "isCustomField": false, + "accessor": "last", + "identifier": "last", + "position": 4.0, + "originalIdentifier": "last", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Last", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + }, + "groupadd": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Select", + "sourceData": "all", + "isCustomField": false, + "accessor": "groupadd", + "identifier": "groupadd", + "position": 5.0, + "originalIdentifier": "groupadd", + "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "isDisabled": false, + "isFilterable": false, + "isRequired": false, + "isVisible": true, + "label": "Groupadd", + "labelTextSize": "0.875rem", + "serverSideFiltering": false, + "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "readreceipts": "all", + "profile": "all", + "status": "contacts", + "online": "all", + "last": "contacts", + "groupadd": "all" + }, + "isCustomField": false, + "accessor": "privacySettings", + "identifier": "privacySettings", + "position": 3.0, + "originalIdentifier": "privacySettings", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "1rem", + "label": "Privacy Settings", + "labelStyle": "BOLD" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "date_of_birth": "20/02/1990", + "employee_id": 1001.0 + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1.0, + "originalIdentifier": "__root_schema__", + "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "boxShadow": "none", + "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", + "cellBoxShadow": "none", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "labelTextSize": "0.875rem", + "label": "" + } + }, + "mobileBottomRow": 41.0, + "widgetName": "FormProfile", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [], + "displayName": "JSON Form", + "bottomRow": 92.0, + "fieldLimitExceeded": false, + "parentRowSpace": 10.0, + "title": "Edit Profile", + "hideCard": false, + "mobileRightColumn": 25.0, + "parentColumnSpace": 6.9375, + "dynamicTriggerPathList": [{ "key": "onSubmit" }], + "borderWidth": "0", + "sourceData": "{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}", + "resetButtonLabel": "", + "key": "72nqor459k", + "backgroundColor": "#fff", + "isDeprecated": false, + "rightColumn": 64.0, + "widgetId": "hguxefink2", + "minWidth": 450.0, + "parentId": "basosxf5qt", + "renderMode": "CANVAS", + "mobileTopRow": 0.0, + "scrollContents": true, + "responsiveBehavior": "fill", + "fixedFooter": true, + "originalTopRow": 0.0, + "mobileLeftColumn": 0.0, + "maxDynamicHeight": 9000.0, + "minDynamicHeight": 4.0 + } + ], + "isDisabled": false, + "key": "mepf0qsn1e", + "isDeprecated": false, + "rightColumn": 430.5, + "detachFromLayout": true, + "widgetId": "basosxf5qt", + "minWidth": 450.0, + "isVisible": true, + "version": 1.0, + "parentId": "ss96aihlej", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 0.0, + "responsiveBehavior": "fill", + "mobileLeftColumn": 0.0, + "flexLayers": [] + } + ], + "key": "4ktj7iym0b", + "height": 940.0, + "isDeprecated": false, + "rightColumn": 35.0, + "detachFromLayout": true, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "ss96aihlej", + "canOutsideClickClose": true, + "canEscapeKeyClose": true, + "version": 2.0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "mobileTopRow": 35.0, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "mobileLeftColumn": 11.0, + "maxDynamicHeight": 9000.0, + "width": 456.0, + "minDynamicHeight": 24.0 + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Page1_Scripts.verifyConfig", + "name": "Scripts.verifyConfig", + "collectionId": "Page1_Scripts", + "clientSideExecution": true, + "confirmBeforeExecute": false, + "pluginType": "JS", + "jsonPathKeys": [ + "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" + ], + "timeoutInMillisecond": 10000.0 + } + ] + ], + "layoutOnLoadActionErrors": [], + "validOnPageLoadActions": true, + "id": "Page1", + "deleted": false, + "policies": [], + "userPermissions": [] + } + ], + "userPermissions": [], + "policies": [] + }, + "deleted": false, + "gitSyncId": "64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56" + } + ], + "actionList": [ + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "fetch_Instances", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/fetchInstances", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": ["appsmith.store.api_url", "appsmith.store.api_key"], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "publishedAction": { + "name": "fetch_Instances", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/fetchInstances", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": ["appsmith.store.api_url", "appsmith.store.api_key"], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "id": "Page1_fetch_Instances", + "deleted": false, + "gitSyncId": "64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788" + }, + { + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "verifyConfig", + "fullyQualifiedName": "Scripts.verifyConfig", + "datasource": { + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "collectionId": "Page1_Scripts", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}", + "selfReferencingDataPaths": [], + "jsArguments": [], + "isAsync": true + }, + "executeOnLoad": true, + "clientSideExecution": true, + "dynamicBindingPathList": [{ "key": "body" }], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "publishedAction": { + "name": "verifyConfig", + "fullyQualifiedName": "Scripts.verifyConfig", + "datasource": { + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "collectionId": "Page1_Scripts", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}", + "selfReferencingDataPaths": [], + "jsArguments": [], + "isAsync": true + }, + "executeOnLoad": true, + "clientSideExecution": true, + "dynamicBindingPathList": [{ "key": "body" }], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "id": "Page1_Scripts.verifyConfig", + "deleted": false, + "gitSyncId": "64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Connect", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/connect/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "publishedAction": { + "name": "Connect", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/connect/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-29T16:12:42Z" + }, + "id": "Page1_Connect", + "deleted": false, + "gitSyncId": "64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Restart", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/restart/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:01:05Z" + }, + "publishedAction": { + "name": "Restart", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/restart/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:01:05Z" + }, + "id": "Page1_Restart", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Logout", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/logout/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:02:00Z" + }, + "publishedAction": { + "name": "Logout", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/logout/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:02:00Z" + }, + "id": "Page1_Logout", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Delete", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/delete/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:02:32Z" + }, + "publishedAction": { + "name": "Delete", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/delete/{{TableInstances.selectedRow.instance}}", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:02:32Z" + }, + "id": "Page1_Delete", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Create_Instance", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/create", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}", + "bodyFormData": [ + { + "key": "instanceName", + "value": "{{FormInstance.data.InputNewInstanceName}}" + }, + { + "key": "token", + "value": "{{FormInstance.data.InputNewInstanceToken}}" + } + ], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "bodyFormData[0].value" }, + { "key": "bodyFormData[1].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n", + "FormInstance.data.InputNewInstanceName", + "FormInstance.data.InputNewInstanceToken", + "appsmith.store.api_url", + "appsmith.store.api_key" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:22:09Z" + }, + "publishedAction": { + "name": "Create_Instance", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/create", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}", + "bodyFormData": [ + { + "key": "instanceName", + "value": "{{FormInstance.data.InputNewInstanceName}}" + }, + { + "key": "token", + "value": "{{FormInstance.data.InputNewInstanceToken}}" + } + ], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "bodyFormData[0].value" }, + { "key": "bodyFormData[1].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n", + "FormInstance.data.InputNewInstanceName", + "FormInstance.data.InputNewInstanceToken", + "appsmith.store.api_url", + "appsmith.store.api_key" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T03:22:09Z" + }, + "id": "Page1_Create_Instance", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Find_Webhook", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/webhook/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:46:50Z" + }, + "publishedAction": { + "name": "Find_Webhook", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/webhook/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:46:50Z" + }, + "id": "Page1_Find_Webhook", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Find_Settings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/settings/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:48:45Z" + }, + "publishedAction": { + "name": "Find_Settings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/settings/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:48:45Z" + }, + "id": "Page1_Find_Settings", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Find_Chatwoot", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chatwoot/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:49:33Z" + }, + "publishedAction": { + "name": "Find_Chatwoot", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chatwoot/find/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T19:49:33Z" + }, + "id": "Page1_Find_Chatwoot", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Set_Webhook", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/webhook/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormWebhook.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\tFormWebhook.formData\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:10:19Z" + }, + "publishedAction": { + "name": "Set_Webhook", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/webhook/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormWebhook.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\tFormWebhook.formData\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:10:19Z" + }, + "id": "Page1_Set_Webhook", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Set_Settings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/settings/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormSettings.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "\n\tFormSettings.formData\n", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:13:25Z" + }, + "publishedAction": { + "name": "Set_Settings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/settings/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormSettings.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "\n\tFormSettings.formData\n", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:13:25Z" + }, + "id": "Page1_Set_Settings", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Set_Chatwoot", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chatwoot/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormChatwoot.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\tFormChatwoot.formData\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:15:01Z" + }, + "publishedAction": { + "name": "Set_Chatwoot", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chatwoot/set/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\tFormChatwoot.formData\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\tFormChatwoot.formData\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-30T20:15:01Z" + }, + "id": "Page1_Set_Chatwoot", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Fetch_Instance", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/fetchInstances", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [ + { + "key": "instanceName", + "value": "{{TableInstances.selectedRow.instance}}" + } + ], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "queryParameters[0].value" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:16:40Z" + }, + "publishedAction": { + "name": "Fetch_Instance", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/instance/fetchInstances", + "headers": [ + { "key": "apikey", "value": "{{appsmith.store.api_key}}" } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [ + { + "key": "instanceName", + "value": "{{TableInstances.selectedRow.instance}}" + } + ], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "queryParameters[0].value" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "appsmith.store.api_url", + "appsmith.store.api_key", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:16:40Z" + }, + "id": "Page1_Fetch_Instance", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Update_ProfileName", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfileName/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:22:45Z" + }, + "publishedAction": { + "name": "Update_ProfileName", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfileName/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:22:45Z" + }, + "id": "Page1_Update_ProfileName", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Update_ProfileStatus", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfileStatus/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "body" }, + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:25:00Z" + }, + "publishedAction": { + "name": "Update_ProfileStatus", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfileStatus/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "POST", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "application/json" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "body" }, + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:25:00Z" + }, + "id": "Page1_Update_ProfileStatus", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Update_ProfilePicture", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfilePicture/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:25:56Z" + }, + "publishedAction": { + "name": "Update_ProfilePicture", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updateProfilePicture/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" }, + { "key": "body" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:25:56Z" + }, + "id": "Page1_Update_ProfilePicture", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Remove_ProfilePicture", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/removeProfilePicture/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:27:20Z" + }, + "publishedAction": { + "name": "Remove_ProfilePicture", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/removeProfilePicture/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "bodyFormData": [], + "httpMethod": "DELETE", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:27:20Z" + }, + "id": "Page1_Remove_ProfilePicture", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Fetch_PrivacySettings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:27:52Z" + }, + "publishedAction": { + "name": "Fetch_PrivacySettings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [], + "bodyFormData": [], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "path" }, + { "key": "headers[0].value" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": true, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:27:52Z" + }, + "id": "Page1_Fetch_PrivacySettings", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62" + }, + { + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "Update_PrivacySettings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "headers[0].value" }, + { "key": "body" }, + { "key": "path" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:28:39Z" + }, + "publishedAction": { + "name": "Update_PrivacySettings", + "datasource": { + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { "url": "" }, + "invalids": [], + "messages": [], + "isAutoGenerated": false, + "deleted": false, + "policies": [], + "userPermissions": [] + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000.0, + "paginationType": "NONE", + "path": "{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{TableInstances.selectedRow.instance}}", + "headers": [ + { + "key": "apikey", + "value": "{{TableInstances.selectedRow.Apikey}}" + } + ], + "autoGeneratedHeaders": [ + { "key": "content-type", "value": "application/json" } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}", + "bodyFormData": [], + "httpMethod": "PUT", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [{ "value": true }], + "formData": { "apiContentType": "none" } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { "key": "headers[0].value" }, + { "key": "body" }, + { "key": "path" } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "TableInstances.selectedRow.Apikey", + "\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n", + "appsmith.store.api_url", + "TableInstances.selectedRow.instance" + ], + "userSetOnLoad": false, + "confirmBeforeExecute": false, + "policies": [], + "userPermissions": [], + "createdAt": "2023-07-31T12:28:39Z" + }, + "id": "Page1_Update_PrivacySettings", + "deleted": false, + "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64" + } + ], + "actionCollectionList": [ + { + "unpublishedCollection": { + "name": "Scripts", + "pageId": "Page1", + "pluginId": "js-plugin", + "pluginType": "JS", + "actions": [], + "archivedActions": [], + "body": "export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}", + "variables": [ + { "name": "myVar1", "value": "[]" }, + { "name": "myVar2", "value": "{}" } + ], + "userPermissions": [] + }, + "publishedCollection": { + "name": "Scripts", + "pageId": "Page1", + "pluginId": "js-plugin", + "pluginType": "JS", + "actions": [], + "archivedActions": [], + "body": "export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}", + "variables": [ + { "name": "myVar1", "value": "[]" }, + { "name": "myVar2", "value": "{}" } + ], + "userPermissions": [] + }, + "id": "Page1_Scripts", + "deleted": false, + "gitSyncId": "64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e" + } + ], + "updatedResources": { + "customJSLibList": [], + "actionList": [ + "Scripts.verifyConfig##ENTITY_SEPARATOR##Page1", + "Find_Chatwoot##ENTITY_SEPARATOR##Page1", + "Connect##ENTITY_SEPARATOR##Page1", + "Update_PrivacySettings##ENTITY_SEPARATOR##Page1", + "Fetch_Instance##ENTITY_SEPARATOR##Page1", + "fetch_Instances##ENTITY_SEPARATOR##Page1", + "Fetch_PrivacySettings##ENTITY_SEPARATOR##Page1", + "Restart##ENTITY_SEPARATOR##Page1", + "Update_ProfileName##ENTITY_SEPARATOR##Page1", + "Find_Settings##ENTITY_SEPARATOR##Page1", + "Set_Chatwoot##ENTITY_SEPARATOR##Page1", + "Delete##ENTITY_SEPARATOR##Page1", + "Create_Instance##ENTITY_SEPARATOR##Page1", + "Update_ProfileStatus##ENTITY_SEPARATOR##Page1", + "Update_ProfilePicture##ENTITY_SEPARATOR##Page1", + "Remove_ProfilePicture##ENTITY_SEPARATOR##Page1", + "Set_Settings##ENTITY_SEPARATOR##Page1", + "Find_Webhook##ENTITY_SEPARATOR##Page1", + "Set_Webhook##ENTITY_SEPARATOR##Page1", + "Logout##ENTITY_SEPARATOR##Page1" + ], + "pageList": ["Page1"], + "actionCollectionList": ["Scripts##ENTITY_SEPARATOR##Page1"] + }, + "editModeTheme": { + "name": "Default", + "displayName": "Modern", + "config": { + "colors": { "primaryColor": "#553DE9", "backgroundColor": "#F8FAFC" }, + "borderRadius": { + "appBorderRadius": { "none": "0px", "M": "0.375rem", "L": "1.5rem" } + }, + "boxShadow": { + "appBoxShadow": { + "none": "none", + "S": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", + "M": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", + "L": "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" + } + }, + "fontFamily": { + "appFont": [ + "System Default", + "Nunito Sans", + "Poppins", + "Inter", + "Montserrat", + "Noto Sans", + "Open Sans", + "Roboto", + "Rubik", + "Ubuntu" + ] + } + }, + "properties": { + "colors": { "primaryColor": "#16a34a", "backgroundColor": "#F8FAFC" }, + "borderRadius": { "appBorderRadius": "0.375rem" }, + "boxShadow": { + "appBoxShadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" + }, + "fontFamily": { "appFont": "Nunito Sans" } + }, + "stylesheet": { + "AUDIO_RECORDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "BUTTON_GROUP_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "childStylesheet": { + "button": { "buttonColor": "{{appsmith.theme.colors.primaryColor}}" } + } + }, + "CAMERA_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "CHART_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" + }, + "CHECKBOX_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CHECKBOX_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CONTAINER_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "CIRCULAR_PROGRESS_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATE_PICKER_WIDGET2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "FILE_PICKER_WIDGET_V2": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "FORM_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "FORM_BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "ICON_BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "IFRAME_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "IMAGE_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "INPUT_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "JSON_FORM_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + } + }, + "LIST_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "MAP_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "MAP_CHART_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" + }, + "MENU_BUTTON_WIDGET": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MODAL_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_TREE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DROP_DOWN_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PROGRESSBAR_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "PROGRESS_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CODE_SCANNER_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RATE_WIDGET": { + "activeColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "RADIO_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "RICH_TEXT_EDITOR_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "STATBOX_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "SWITCH_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SWITCH_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "SELECT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "TABLE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + } + }, + "TABLE_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + } + }, + "TABS_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "TEXT_WIDGET": { + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "VIDEO_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "SINGLE_SELECT_TREE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "CATEGORY_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "NUMBER_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "RANGE_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + } + }, + "isSystemTheme": false, + "deleted": false + }, + "publishedTheme": { + "name": "Default", + "displayName": "Modern", + "config": { + "colors": { "primaryColor": "#553DE9", "backgroundColor": "#F8FAFC" }, + "borderRadius": { + "appBorderRadius": { "none": "0px", "M": "0.375rem", "L": "1.5rem" } + }, + "boxShadow": { + "appBoxShadow": { + "none": "none", + "S": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", + "M": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", + "L": "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" + } + }, + "fontFamily": { + "appFont": [ + "System Default", + "Nunito Sans", + "Poppins", + "Inter", + "Montserrat", + "Noto Sans", + "Open Sans", + "Roboto", + "Rubik", + "Ubuntu" + ] + } + }, + "properties": { + "colors": { "primaryColor": "#16a34a", "backgroundColor": "#F8FAFC" }, + "borderRadius": { "appBorderRadius": "0.375rem" }, + "boxShadow": { + "appBoxShadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" + }, + "fontFamily": { "appFont": "Nunito Sans" } + }, + "stylesheet": { + "AUDIO_RECORDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "BUTTON_GROUP_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "childStylesheet": { + "button": { "buttonColor": "{{appsmith.theme.colors.primaryColor}}" } + } + }, + "CAMERA_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "CHART_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" + }, + "CHECKBOX_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CHECKBOX_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CONTAINER_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "CIRCULAR_PROGRESS_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATE_PICKER_WIDGET2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "FILE_PICKER_WIDGET_V2": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "FORM_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "FORM_BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "ICON_BUTTON_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "IFRAME_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "IMAGE_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "INPUT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "INPUT_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "JSON_FORM_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "submitButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "resetButtonStyles": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "childStylesheet": { + "ARRAY": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "OBJECT": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none", + "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "cellBoxShadow": "none" + }, + "CHECKBOX": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CURRENCY_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DATEPICKER": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "EMAIL_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTISELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTILINE_TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PASSWORD_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PHONE_NUMBER_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RADIO_GROUP": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SELECT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "SWITCH": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "TEXT_INPUT": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + } + }, + "LIST_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "MAP_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "MAP_CHART_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" + }, + "MENU_BUTTON_WIDGET": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MODAL_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_TREE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "MULTI_SELECT_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "DROP_DOWN_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "PROGRESSBAR_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "PROGRESS_WIDGET": { + "fillColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "CODE_SCANNER_WIDGET": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "RATE_WIDGET": { + "activeColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "RADIO_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "RICH_TEXT_EDITOR_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "STATBOX_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "SWITCH_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "boxShadow": "none" + }, + "SWITCH_GROUP_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "SELECT_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "TABLE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + } + } + }, + "TABLE_WIDGET_V2": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + } + }, + "TABS_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "TEXT_WIDGET": { + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + }, + "VIDEO_WIDGET": { + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" + }, + "SINGLE_SELECT_TREE_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "CATEGORY_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "NUMBER_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + }, + "RANGE_SLIDER_WIDGET": { + "accentColor": "{{appsmith.theme.colors.primaryColor}}" + } + }, + "isSystemTheme": false, + "deleted": false + } +} diff --git a/Extras/chatwoot/_Evolution__Configurar_Admin.json b/Extras/chatwoot/_Evolution__Configurar_Admin.json new file mode 100644 index 00000000..1399ff54 --- /dev/null +++ b/Extras/chatwoot/_Evolution__Configurar_Admin.json @@ -0,0 +1,233 @@ +{ + "name": "[Evolution] Configurar Admin", + "nodes": [ + { + "parameters": { + "values": { + "string": [ + { + "name": "api_access_token", + "value": "CHATWOOT_USER_TOKEN" + }, + { + "name": "chatwoot_url", + "value": "https://CHATWOOT_URL" + }, + { + "name": "n8n_url", + "value": "https://N8N_URL" + } + ] + }, + "options": {} + }, + "id": "322486a5-e6a7-4af9-8a3f-0ebc444912f0", + "name": "Info Base", + "type": "n8n-nodes-base.set", + "typeVersion": 2, + "position": [ + 1840, + 880 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/1/contacts/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"EvolutionAPI\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"https://evolution-api.com/files/evolution-api-favicon.png\"\n}", + "options": {} + }, + "id": "61742c2d-d195-4a68-a2eb-a36839b6376a", + "name": "Cria Contato Bot", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2240, + 880 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/1/inboxes/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"name\": \"StartEvolution\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", + "options": {} + }, + "id": "866ddf42-2d5f-4bf2-8552-2379a5cdc2a5", + "name": "Cria Inbox Start", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2040, + 880 + ] + }, + { + "parameters": {}, + "id": "f1c2478a-9a1d-4cd4-82de-2002281c020b", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [ + 1620, + 880 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/1/automation_rules/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"name\": \"Create Company Chatwoot\",\n \"description\": \"Create Company Chatwoot\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"https://webhooks.n8n.evolution-api.com/webhook/criadorchatwoot\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"Tema Criador de Empresa:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "options": {} + }, + "id": "e776b87b-57a6-4782-9ad9-cd0000aab29c", + "name": "Cria Automação Empresas", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2440, + 880 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/1/automation_rules/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"name\": \"Create Inbox EvolutionAPI\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\"api_access_token\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n \n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n\n\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "options": {} + }, + "id": "d89ed76c-a5e9-42e6-b55b-e779e9a33a53", + "name": "Cria Automação Inboxes", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2660, + 880 + ] + }, + { + "parameters": { + "content": "## Workflow Para Configurar admin\n**Aqui você prepara o Chatwoot Principal com um usuário (Superadmin) que poderá criar empresas e caixas de entrada**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\n**Obs: A variável api_access_token é o token do usuário que irá poder criar as empresas**", + "width": 1129.7777777777778 + }, + "id": "a4597492-843a-44c7-836a-f30c91d46a20", + "name": "Sticky Note", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 1620, + 680 + ] + } + ], + "pinData": {}, + "connections": { + "Info Base": { + "main": [ + [ + { + "node": "Cria Inbox Start", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Contato Bot": { + "main": [ + [ + { + "node": "Cria Automação Empresas", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Inbox Start": { + "main": [ + [ + { + "node": "Cria Contato Bot", + "type": "main", + "index": 0 + } + ] + ] + }, + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Info Base", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Automação Empresas": { + "main": [ + [ + { + "node": "Cria Automação Inboxes", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "4f0e166f-00fb-4ce6-989e-03c036351e35", + "id": "HmHVbJIXCOd57rBU", + "meta": { + "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" + }, + "tags": [] +} \ No newline at end of file diff --git a/Extras/chatwoot/_Evolution__Criador_de_Empresas.json b/Extras/chatwoot/_Evolution__Criador_de_Empresas.json new file mode 100644 index 00000000..c35bdf3d --- /dev/null +++ b/Extras/chatwoot/_Evolution__Criador_de_Empresas.json @@ -0,0 +1,444 @@ +{ + "name": "[Evolution] Criador de Empresas", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "criadorchatwoot", + "options": {} + }, + "id": "1bbcdc39-46af-4476-a381-981a96be3726", + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1, + "position": [ + 1360, + 840 + ], + "webhookId": "6fe428e3-1752-453c-9358-abf18b793387" + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/platform/api/v1/accounts", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "name", + "value": "={{ $json.name_company }}" + }, + { + "name": "locale", + "value": "pt_BR" + } + ] + }, + "options": {} + }, + "id": "ec9927e2-d075-4f3f-8655-d1269d25bac2", + "name": "Cria Conta", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 1960, + 840 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/platform/api/v1/users", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "name", + "value": "={{ $('Info Base').item.json.name_admin }}" + }, + { + "name": "email", + "value": "={{ $('Info Base').item.json[\"email\"] }}" + }, + { + "name": "password", + "value": "={{ $('Info Base').item.json[\"password\"] }}" + } + ] + }, + "options": {} + }, + "id": "1ce013fd-0445-488c-b73f-b86597a5b556", + "name": "Cria Usuario", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2160, + 840 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/platform/api/v1/accounts/{{ $node[\"Cria Conta\"].json[\"id\"] }}/account_users", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json[\"api_access_token\"] }}" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "user_id", + "value": "={{ $node[\"Cria Usuario\"].json[\"id\"] }}" + }, + { + "name": "role", + "value": "administrator" + } + ] + }, + "options": {} + }, + "id": "a9156473-1916-446b-9e50-e906794c7c5b", + "name": "Add Usuario a Conta", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2380, + 840 + ] + }, + { + "parameters": { + "fromEmail": "contato@agenciadgcode.com", + "toEmail": "={{ $('LimpaDados').item.json.email }}", + "subject": "Bem vindo ao Chatwoot", + "text": "=Olá seja bem vindo:\n\nAbaixo segue seus dados de acesso iniciais:\n\nURL: {{ $('Info Base').item.json[\"chatwoot_url\"] }}\n\nLoging: {{ $('LimpaDados').item.json[\"email\"] }}\n\nSenha: {{ $('LimpaDados').item.json[\"password\"] }}", + "options": {} + }, + "id": "2d0b3e35-6e51-4e9b-90b4-6382dc6fec88", + "name": "Send Email", + "type": "n8n-nodes-base.emailSend", + "typeVersion": 2, + "position": [ + 3180, + 840 + ], + "credentials": { + "smtp": { + "id": "6BxluEUV8zrXKoVG", + "name": "[Dgcode] SMTP" + } + } + }, + { + "parameters": { + "values": { + "string": [ + { + "name": "api_access_token", + "value": "TOKEN PLATAFORM" + }, + { + "name": "chatwoot_url", + "value": "https://CHATWOOT_URL" + }, + { + "name": "n8n_url", + "value": "https://N8N_URL" + }, + { + "name": "name", + "value": "={{ $json.name_company }}" + }, + { + "name": "email", + "value": "={{ $json.email }}" + }, + { + "name": "password", + "value": "={{ $json.password }}" + }, + { + "name": "name_company", + "value": "={{ $json.name_company }}" + } + ] + }, + "options": {} + }, + "id": "1efc0806-2fe7-4670-9a0c-ab71592d0bbb", + "name": "Info Base", + "type": "n8n-nodes-base.set", + "typeVersion": 2, + "position": [ + 1760, + 840 + ] + }, + { + "parameters": { + "keepOnlySet": true, + "values": { + "string": [ + { + "name": "name_admin", + "value": "={{$node[\"Webhook\"].json[\"body\"][\"messages\"][0][\"content\"].match(/Nome Usuario Administrador: ([^\\n]+)/)[1];}}" + }, + { + "name": "name_company", + "value": "={{$node[\"Webhook\"].json[\"body\"][\"messages\"][0][\"content\"].match(/Nome da Empresa: ([^\\n]+)/)[1];}}" + }, + { + "name": "email", + "value": "={{$node[\"Webhook\"].json[\"body\"][\"messages\"][0][\"content\"].match(/Email: ([^\\s]+)/)[1];}}" + }, + { + "name": "password", + "value": "={{$node[\"Webhook\"].json[\"body\"][\"messages\"][0][\"content\"].match(/Senha: ([^\\s]+)/)[1];}}" + } + ] + }, + "options": {} + }, + "id": "602accf3-f01a-46ac-a22f-37c964c0ec76", + "name": "LimpaDados", + "type": "n8n-nodes-base.set", + "typeVersion": 2, + "position": [ + 1560, + 840 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Add Usuario a Conta').item.json.account_id }}/contacts/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Cria Usuario').item.json.access_token }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"EvolutionAPI\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"https://evolution-api.com/files/evolution-api-favicon.png\"\n}", + "options": {} + }, + "id": "974e672e-fa4a-44ab-b6df-7aacd2bdb329", + "name": "Cria Contato Bot", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2800, + 840 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Add Usuario a Conta').item.json.account_id }}/automation_rules/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Cria Usuario').item.json.access_token }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"name\": \"Create Inbox EvolutionAPI\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "options": {} + }, + "id": "fb5597d4-0af1-461b-912b-7671a88c8368", + "name": "Cria Automação", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 3000, + 840 + ] + }, + { + "parameters": { + "method": "POST", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $json.account_id }}/inboxes/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Cria Usuario').item.json.access_token }}" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n \"name\": \"StartEvolution\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", + "options": {} + }, + "id": "a09bc90a-d643-422c-90ae-f8baa41ee532", + "name": "Cria Inbox Start", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2600, + 840 + ] + }, + { + "parameters": { + "content": "## Workflow Criador de Empresas\n**Cria Contas (Empresas) e Usuários através de tema**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\n**Obs: A variável api_access_token é o token PlatformApp encontrado no acesso ao Super Admin**\n**Tema para criar novas empresa:**\n\nTema Criador de Empresa:\n\nNome Usuario Administrador: Joao Linhares\nNome da Empresa: Oficina Linhates\nEmail: machineteste24@gmail.com\nSenha: Mfcd62!!", + "height": 304.02684563758396, + "width": 1129.7777777777778 + }, + "id": "f742f53d-58bc-4e26-bb82-1db352425eff", + "name": "Sticky Note", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 1360, + 500 + ] + } + ], + "pinData": {}, + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "LimpaDados", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Conta": { + "main": [ + [ + { + "node": "Cria Usuario", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Usuario": { + "main": [ + [ + { + "node": "Add Usuario a Conta", + "type": "main", + "index": 0 + } + ] + ] + }, + "Add Usuario a Conta": { + "main": [ + [ + { + "node": "Cria Inbox Start", + "type": "main", + "index": 0 + } + ] + ] + }, + "Info Base": { + "main": [ + [ + { + "node": "Cria Conta", + "type": "main", + "index": 0 + } + ] + ] + }, + "LimpaDados": { + "main": [ + [ + { + "node": "Info Base", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Contato Bot": { + "main": [ + [ + { + "node": "Cria Automação", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Automação": { + "main": [ + [ + { + "node": "Send Email", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Inbox Start": { + "main": [ + [ + { + "node": "Cria Contato Bot", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": {}, + "versionId": "5638171c-d64e-404f-b0f1-c8fbe4ec6fb0", + "id": "mVLlfZvGjtR8SZLT", + "meta": { + "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" + }, + "tags": [] +} \ No newline at end of file diff --git a/Extras/chatwoot/_Evolution__Criador_de_Inbox.json b/Extras/chatwoot/_Evolution__Criador_de_Inbox.json new file mode 100644 index 00000000..bf593a8e --- /dev/null +++ b/Extras/chatwoot/_Evolution__Criador_de_Inbox.json @@ -0,0 +1,364 @@ +{ + "name": "[Evolution] Criador de Inbox", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "inbox_whatsapp", + "options": {} + }, + "id": "8205b929-73e9-456a-9b0d-e1474991663a", + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1, + "position": [ + 320, + 300 + ], + "webhookId": "cf37002d-3869-4bb1-af3a-739fdd3c1756" + }, + { + "parameters": { + "method": "POST", + "url": "={{ $json.evolution_url }}/instance/create", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "apikey", + "value": "={{ $json.global_api_key }}" + } + ] + }, + "sendBody": true, + "bodyParameters": { + "parameters": [ + { + "name": "instanceName", + "value": "={{ $json.instance_name }}" + }, + { + "name": "qrcode", + "value": "={{ $json.qrcode }}" + }, + { + "name": "chatwoot_account_id", + "value": "={{ $json.chatwoot_account_id }}" + }, + { + "name": "chatwoot_token", + "value": "={{ $json.chatwoot_token }}" + }, + { + "name": "chatwoot_url", + "value": "={{ $json.chatwoot_url }}" + }, + { + "name": "chatwoot_sign_msg", + "value": "={{ $json.chatwoot_sign_msg }}" + }, + { + "name": "chatwoot_reopen_conversation", + "value": "={{ $json.chatwoot_reopen_conversation }}" + }, + { + "name": "chatwoot_conversation_pending", + "value": "={{ $json.chatwoot_conversation_pending }}" + }, + { + "name": "reject_call", + "value": "={{ $json.reject_call }}" + }, + { + "name": "msg_call", + "value": "={{ $json.msg_call }}" + }, + { + "name": "groups_ignore", + "value": "={{ $json.groups_ignore }}" + }, + { + "name": "always_online", + "value": "={{ $json.always_online }}" + }, + { + "name": "read_messages", + "value": "={{ $json.read_messages }}" + }, + { + "name": "read_status", + "value": "={{ $json.read_status }}" + } + ] + }, + "options": {} + }, + "id": "275aa370-2fdb-42f4-844a-2fb3051301bd", + "name": "Cria Instancia", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.1, + "position": [ + 760, + 300 + ] + }, + { + "parameters": { + "method": "DELETE", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.payload[0].id }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json.chatwoot_token }}" + } + ] + }, + "options": {} + }, + "id": "e2e2cfe4-0afc-47f2-9176-5e14cb4c66c3", + "name": "Deleta Inbox Start", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 1600, + 300 + ] + }, + { + "parameters": { + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json.chatwoot_token }}" + } + ] + }, + "options": {} + }, + "id": "e4650812-ba0a-4f72-8bd8-a235eca4b2de", + "name": "Lista Inboxes", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 980, + 300 + ] + }, + { + "parameters": { + "operation": "limit" + }, + "id": "c498a51e-53c5-4f0e-9aaa-eb1ebc4fbcb5", + "name": "Recupera Primeira Inbox", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 2.2, + "position": [ + 1180, + 300 + ] + }, + { + "parameters": { + "conditions": { + "string": [ + { + "value1": "={{ $json.payload[0].name }}", + "value2": "StartEvolution" + } + ] + } + }, + "id": "40f705df-b9ff-4645-94ec-e7a5a0ca4777", + "name": "é StartEvolution?", + "type": "n8n-nodes-base.if", + "typeVersion": 1, + "position": [ + 1380, + 300 + ] + }, + { + "parameters": { + "content": "## Workflow Para Criar Inbox\n**Aqui você configura a comunicação entre o chatwoot e a Evolution API para criar novas instâncias a partir do chatwoot**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e Evolution API**", + "width": 1129.7777777777778 + }, + "id": "aa763d9e-d973-44fc-8399-277bb24718a5", + "name": "Sticky Note", + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 320, + 80 + ] + }, + { + "parameters": { + "keepOnlySet": true, + "values": { + "string": [ + { + "name": "chatwoot_url", + "value": "https://CHATWOOT_URL" + }, + { + "name": "evolution_url", + "value": "https://EVOLUTION_URL" + }, + { + "name": "global_api_key", + "value": "GLOBAL_API_KEY" + }, + { + "name": "instance_name", + "value": "={{ $json.body.messages[0].content.split(':')[1] }}-cwId-{{ $json.body.messages[0].account_id }}" + }, + { + "name": "chatwoot_token", + "value": "={{ $json.query.utoken }}" + }, + { + "name": "msg_call", + "value": "Não aceitamos chamadas, por favor deixe uma mensagem!" + } + ], + "boolean": [ + { + "name": "qrcode", + "value": true + }, + { + "name": "chatwoot_sign_msg", + "value": true + }, + { + "name": "chatwoot_reopen_conversation", + "value": true + }, + { + "name": "chatwoot_conversation_pending" + }, + { + "name": "reject_call", + "value": true + }, + { + "name": "groups_ignore" + }, + { + "name": "always_online", + "value": true + }, + { + "name": "read_messages", + "value": true + }, + { + "name": "read_status" + } + ], + "number": [ + { + "name": "chatwoot_account_id", + "value": "={{ $json.body.messages[0].account_id }}" + } + ] + }, + "options": {} + }, + "id": "297df325-ecc4-4a34-817c-092d16d5753b", + "name": "Info Base", + "type": "n8n-nodes-base.set", + "typeVersion": 2, + "position": [ + 540, + 300 + ] + } + ], + "pinData": {}, + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Info Base", + "type": "main", + "index": 0 + } + ] + ] + }, + "Lista Inboxes": { + "main": [ + [ + { + "node": "Recupera Primeira Inbox", + "type": "main", + "index": 0 + } + ] + ] + }, + "Recupera Primeira Inbox": { + "main": [ + [ + { + "node": "é StartEvolution?", + "type": "main", + "index": 0 + } + ] + ] + }, + "é StartEvolution?": { + "main": [ + [ + { + "node": "Deleta Inbox Start", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cria Instancia": { + "main": [ + [ + { + "node": "Lista Inboxes", + "type": "main", + "index": 0 + } + ] + ] + }, + "Info Base": { + "main": [ + [ + { + "node": "Cria Instancia", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": {}, + "versionId": "ee6fcc3a-3815-4f9b-9a6b-e282c66fc37b", + "id": "ByW2ccjR4XPrOyio", + "meta": { + "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" + }, + "tags": [] +} \ No newline at end of file diff --git a/views/manager.hbs b/views/manager.hbs index 0c81dcc8..aac84bdf 100644 --- a/views/manager.hbs +++ b/views/manager.hbs @@ -11,13 +11,6 @@ integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"> - Instance Manager From 2637aebb7fb4303df8011dc72b8891a0aa0afac4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 12:34:01 -0300 Subject: [PATCH 102/177] fix: Encoded spaces in chatwoot webhook --- src/whatsapp/controllers/chatwoot.controller.ts | 4 ++-- src/whatsapp/services/monitor.service.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index 9dc493dc..46b93aee 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -52,7 +52,7 @@ export class ChatwootController { const response = { ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`, }; return response; @@ -78,7 +78,7 @@ export class ChatwootController { const response = { ...result, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`, }; return response; diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index c0b9b610..f64c9a54 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -94,7 +94,7 @@ export class WAMonitoringService { if (findChatwoot && findChatwoot.enabled) { chatwoot = { ...findChatwoot, - webhook_url: `${urlServer}/chatwoot/webhook/${key}`, + webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`, }; } From 1b39eb1a23eef3125252d301b9fdfb1cac3e7db2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 13:13:41 -0300 Subject: [PATCH 103/177] add: Added extra files for chatwoot and appsmith --- Extras/appsmith/manager.json | 12288 +------------------- src/whatsapp/services/chatwoot.service.ts | 2 +- 2 files changed, 2 insertions(+), 12288 deletions(-) diff --git a/Extras/appsmith/manager.json b/Extras/appsmith/manager.json index 8cd958c2..6ba96e76 100644 --- a/Extras/appsmith/manager.json +++ b/Extras/appsmith/manager.json @@ -1,12287 +1 @@ -{ - "clientSchemaVersion": 1.0, - "serverSchemaVersion": 6.0, - "exportedApplication": { - "name": "EvolutionAPI", - "isPublic": true, - "pages": [{ "id": "Page1", "isDefault": true }], - "publishedPages": [{ "id": "Page1", "isDefault": true }], - "viewMode": false, - "appIsExample": false, - "unreadCommentThreads": 0.0, - "color": "#F5D1D1", - "icon": "bar-graph", - "slug": "evolutionapi", - "unpublishedAppLayout": { "type": "DESKTOP" }, - "publishedAppLayout": { "type": "DESKTOP" }, - "unpublishedCustomJSLibs": [], - "publishedCustomJSLibs": [], - "evaluationVersion": 2.0, - "applicationVersion": 2.0, - "collapseInvisibleWidgets": true, - "isManualUpdate": false, - "deleted": false - }, - "datasourceList": [], - "customJSLibList": [], - "pageList": [ - { - "unpublishedPage": { - "name": "Page1", - "slug": "page1", - "layouts": [ - { - "viewMode": false, - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 4896.0, - "snapColumns": 64.0, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0.0, - "bottomRow": 420.0, - "containerStyle": "none", - "snapRows": 124.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 80.0, - "minHeight": 1292.0, - "dynamicTriggerPathList": [], - "parentColumnSpace": 1.0, - "dynamicBindingPathList": [], - "leftColumn": 0.0, - "children": [ - { - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "borderColor": "#E0DEDE", - "isVisibleDownload": true, - "iconSVG": "https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg", - "topRow": 6.0, - "isSortable": true, - "type": "TABLE_WIDGET_V2", - "inlineEditingSaveOption": "ROW_LEVEL", - "animateLoading": true, - "dynamicBindingPathList": [ - { "key": "tableData" }, - { "key": "primaryColumns.customColumn9.boxShadow" }, - { "key": "primaryColumns.customColumn9.borderRadius" }, - { "key": "primaryColumns.customColumn9.menuColor" }, - { "key": "primaryColumns.customColumn8.computedValue" }, - { "key": "primaryColumns.customColumn7.computedValue" }, - { "key": "primaryColumns.customColumn6.computedValue" }, - { "key": "primaryColumns.customColumn5.computedValue" }, - { "key": "primaryColumns.customColumn2.computedValue" }, - { "key": "primaryColumns.customColumn1.textColor" }, - { "key": "primaryColumns.customColumn1.cellBackground" }, - { "key": "primaryColumns.customColumn1.computedValue" }, - { "key": "primaryColumns.instance.computedValue" }, - { "key": "isVisible" }, - { "key": "accentColor" }, - { "key": "borderRadius" }, - { "key": "boxShadow" } - ], - "needsHeightForContent": true, - "leftColumn": 14.0, - "delimiter": ",", - "defaultSelectedRowIndex": 0.0, - "showInlineEditingOptionDropdown": true, - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "isVisibleFilters": true, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "enableClientSideSearch": true, - "version": 2.0, - "totalRecordsCount": 0.0, - "isLoading": false, - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "editActions": { - "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - } - }, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "columnUpdatedAt": 1.690746223636e12, - "defaultSelectedRowIndices": [0.0], - "mobileBottomRow": 32.0, - "widgetName": "TableInstances", - "defaultPageSize": 0.0, - "columnOrder": [ - "instance", - "customColumn5", - "customColumn1", - "customColumn2", - "customColumn6", - "customColumn7", - "customColumn8", - "customColumn9" - ], - "dynamicPropertyPathList": [ - { "key": "primaryColumns.customColumn1.cellBackground" }, - { "key": "isVisible" } - ], - "displayName": "Table", - "bottomRow": 42.0, - "columnWidthMap": { - "customColumn3": 92.0, - "customColumn2": 340.0, - "customColumn5": 254.0, - "customColumn9": 97.0 - }, - "parentRowSpace": 10.0, - "hideCard": false, - "mobileRightColumn": 36.0, - "parentColumnSpace": 20.078125, - "dynamicTriggerPathList": [ - { - "key": "primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick" - }, - { - "key": "primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick" - }, - { - "key": "primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick" - } - ], - "borderWidth": "1", - "primaryColumns": { - "instance": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 0.0, - "width": 150.0, - "originalId": "instance", - "id": "instance", - "alias": "instance", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": false, - "label": "Instance", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}", - "sticky": "", - "validation": {} - }, - "customColumn1": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 1.0, - "width": 150.0, - "originalId": "customColumn1", - "id": "customColumn1", - "alias": "Status", - "horizontalAlignment": "CENTER", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Status", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF", - "cellBackground": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}", - "textColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}" - }, - "customColumn2": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 2.0, - "width": 150.0, - "originalId": "customColumn2", - "id": "customColumn2", - "alias": "Apikey", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Apikey", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn5": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 5.0, - "width": 150.0, - "originalId": "customColumn5", - "id": "customColumn5", - "alias": "Owner", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Owner", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn6": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 6.0, - "width": 150.0, - "originalId": "customColumn6", - "id": "customColumn6", - "alias": "profilePictureUrl", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profilePictureUrl", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn7": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 7.0, - "width": 150.0, - "originalId": "customColumn7", - "id": "customColumn7", - "alias": "profileName", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profileName", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn8": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 8.0, - "width": 150.0, - "originalId": "customColumn8", - "id": "customColumn8", - "alias": "profileStatus", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profileStatus", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn9": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 9.0, - "width": 150.0, - "originalId": "customColumn9", - "id": "customColumn9", - "alias": "Actions", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "menuButton", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Actions", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF", - "menuColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}", - "borderRadius": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}", - "boxShadow": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}", - "customAlias": "", - "menuItemsSource": "STATIC", - "menuButtonLabel": " ", - "menuButtoniconName": "chevron-down", - "menuItems": { - "menuItemjfzsd8g6yr": { - "id": "menuItemjfzsd8g6yr", - "index": 0.0, - "label": "Webhook", - "widgetId": "vygcejtdun", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Webhook.run();\nshowModal('ModalWebhook');}}" - }, - "menuItem4sqork5nmt": { - "id": "menuItem4sqork5nmt", - "index": 1.0, - "label": "Settings", - "widgetId": "0hw8oqpwcj", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Settings.run();\nshowModal('ModalSettings');}}" - }, - "menuItemig6ua4ixjx": { - "id": "menuItemig6ua4ixjx", - "index": 2.0, - "label": "Chatwoot", - "widgetId": "fuq5dtgbqc", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}" - } - } - } - }, - "key": "e3yxhhyeel", - "canFreezeColumn": true, - "isDeprecated": false, - "rightColumn": 63.0, - "textSize": "0.875rem", - "widgetId": "uupm7enu8u", - "minWidth": 450.0, - "tableData": "{{fetch_Instances.data}}", - "label": "Data", - "searchKey": "", - "parentId": "0", - "renderMode": "CANVAS", - "mobileTopRow": 4.0, - "horizontalAlignment": "LEFT", - "isVisibleSearch": true, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "isVisiblePagination": true, - "verticalAlignment": "CENTER" - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "BtnNewInstance", - "onClick": "{{showModal('ModalInstance');}}", - "buttonColor": "rgb(3, 179, 101)", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 8.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 7.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "text": "New Instance", - "isDisabled": false, - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 19.0, - "isDefaultClickDisabled": true, - "iconName": "add", - "widgetId": "84ei9q1ugm", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 74.0, - "widgetName": "ModalQrcode", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 50.0, - "bottomRow": 500.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 45.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "leftColumn": 21.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas1", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 450.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 52.0, - "widgetName": "ImageQrcode", - "displayName": "Image", - "iconSVG": "https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", - "topRow": 6.0, - "bottomRow": 43.0, - "parentRowSpace": 10.0, - "type": "IMAGE_WIDGET", - "hideCard": false, - "mobileRightColumn": 55.0, - "animateLoading": true, - "parentColumnSpace": 20.078125, - "dynamicTriggerPathList": [], - "imageShape": "RECTANGLE", - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "image" }, - { "key": "borderRadius" } - ], - "defaultImage": "https://evolution-api.com/files/evolution-api-favicon.png", - "key": "4chlj9l432", - "image": "{{Connect.data.base64}}", - "isDeprecated": false, - "rightColumn": 61.0, - "objectFit": "contain", - "widgetId": "27dpgapd7q", - "isVisible": true, - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 40.0, - "maxZoomLevel": 1.0, - "enableDownload": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 43.0, - "enableRotation": false - }, - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton1", - "onClick": "{{closeModal('ModalQrcode');\nfetch_Instances.run()}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 58.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "iconSize": 24.0, - "isDisabled": false, - "key": "pezy0hb491", - "isDeprecated": false, - "rightColumn": 64.0, - "iconName": "cross", - "widgetId": "i1dw369dch", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 58.0, - "buttonVariant": "TERTIARY" - }, - { - "mobileBottomRow": 5.0, - "widgetName": "Text1", - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 1.0, - "bottomRow": 5.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 41.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "fontFamily" }], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "Qrcode", - "key": "9s8f10sepn", - "isDeprecated": false, - "rightColumn": 41.0, - "textAlign": "LEFT", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "mg2cqsi9fn", - "minWidth": 450.0, - "isVisible": true, - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "we6j3r2byy", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "ljwryrjhy7", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "g8xx6ocuvi", - "height": 450.0, - "isDeprecated": false, - "rightColumn": 45.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "ljwryrjhy7", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 50.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 21.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "BtnConfig", - "onClick": "{{showModal('ModalConfig');}}", - "buttonColor": "#2563eb", - "dynamicPropertyPathList": [], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 30.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "text": "Access", - "isDisabled": false, - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 7.0, - "isDefaultClickDisabled": true, - "iconName": "user", - "widgetId": "uegjpy37i6", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 14.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 73.0, - "widgetName": "ModalConfig", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 49.0, - "bottomRow": 30.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 25.0, - "minHeight": 300.0, - "animateLoading": true, - "parentColumnSpace": 11.75, - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas2", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 300.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 300.0, - "mobileRightColumn": 282.0, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 84.0, - "borderColor": "#E0DEDE", - "widgetName": "FormConfig", - "isCanvas": true, - "displayName": "Form", - "iconSVG": "/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg", - "searchTags": ["group"], - "topRow": 0.0, - "bottomRow": 28.0, - "parentRowSpace": 10.0, - "type": "FORM_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 25.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [], - "children": [ - { - "mobileBottomRow": 400.0, - "widgetName": "Canvas2Copy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 280.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": false, - "hideCard": true, - "minHeight": 400.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "mobileBottomRow": 5.0, - "widgetName": "Text2", - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": [ - "typography", - "paragraph", - "label" - ], - "topRow": 1.0, - "bottomRow": 5.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 25.5, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "dynamicTriggerPathList": [], - "leftColumn": 1.5, - "dynamicBindingPathList": [ - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "Access Credentials", - "key": "9s8f10sepn", - "isDeprecated": false, - "rightColumn": 25.5, - "textAlign": "LEFT", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "tps5rw2lk9", - "minWidth": 450.0, - "isVisible": true, - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.5, - "maxDynamicHeight": 9000.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - }, - { - "resetFormOnClick": true, - "boxShadow": "none", - "mobileBottomRow": 37.0, - "widgetName": "Button1", - "onClick": "{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "dynamicPropertyPathList": [ - { "key": "isDisabled" } - ], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 22.0, - "bottomRow": 26.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 62.0, - "animateLoading": true, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 51.0, - "dynamicBindingPathList": [ - { "key": "isDisabled" }, - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "text": "Login", - "isDisabled": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 63.0, - "isDefaultClickDisabled": true, - "iconName": "log-in", - "widgetId": "gzxvnsxk0y", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 33.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 46.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "resetFormOnClick": true, - "boxShadow": "none", - "mobileBottomRow": 37.0, - "widgetName": "Button1Copy", - "onClick": "{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}", - "buttonColor": "#dc2626", - "dynamicPropertyPathList": [ - { "key": "isDisabled" } - ], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 21.0, - "bottomRow": 25.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 62.0, - "animateLoading": true, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "isDisabled" }, - { "key": "borderRadius" } - ], - "text": "Logout", - "isDisabled": "{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}", - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 14.0, - "isDefaultClickDisabled": true, - "iconName": "log-out", - "widgetId": "f2i8tsbgx1", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 33.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 46.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", - "topRow": 6.0, - "labelWidth": 5.0, - "type": "INPUT_WIDGET_V2", - "animateLoading": true, - "resetOnSubmit": true, - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "defaultText" }, - { "key": "accentColor" }, - { "key": "borderRadius" } - ], - "labelStyle": "", - "inputType": "TEXT", - "placeholderText": "", - "isDisabled": false, - "isRequired": true, - "dynamicHeight": "FIXED", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "showStepArrows": false, - "isVisible": true, - "version": 2.0, - "isLoading": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileBottomRow": 13.0, - "widgetName": "InputApiUrl", - "displayName": "Input", - "searchTags": [ - "form", - "text input", - "number", - "textarea" - ], - "bottomRow": 13.0, - "parentRowSpace": 10.0, - "autoFocus": false, - "hideCard": false, - "mobileRightColumn": 22.0, - "parentColumnSpace": 5.047119140625, - "dynamicTriggerPathList": [], - "labelPosition": "Top", - "key": "r1hfat3ouf", - "labelTextSize": "0.875rem", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "spgryrb5ao", - "minWidth": 450.0, - "label": "API URL", - "parentId": "lrtvcpswru", - "labelAlignment": "left", - "renderMode": "CANVAS", - "mobileTopRow": 6.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "maxDynamicHeight": 9000.0, - "isSpellCheck": false, - "iconAlign": "left", - "defaultText": "{{appsmith.store.api_url || ''}}", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", - "topRow": 14.0, - "labelWidth": 5.0, - "type": "INPUT_WIDGET_V2", - "animateLoading": true, - "resetOnSubmit": true, - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "defaultText" }, - { "key": "accentColor" }, - { "key": "borderRadius" } - ], - "labelStyle": "", - "inputType": "PASSWORD", - "isDisabled": false, - "isRequired": true, - "dynamicHeight": "FIXED", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "showStepArrows": false, - "isVisible": true, - "version": 2.0, - "isLoading": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileBottomRow": 13.0, - "widgetName": "InputGlobalApiKey", - "displayName": "Input", - "searchTags": [ - "form", - "text input", - "number", - "textarea" - ], - "bottomRow": 21.0, - "parentRowSpace": 10.0, - "autoFocus": false, - "hideCard": false, - "mobileRightColumn": 22.0, - "parentColumnSpace": 5.047119140625, - "dynamicTriggerPathList": [], - "labelPosition": "Top", - "key": "r1hfat3ouf", - "labelTextSize": "0.875rem", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "v2vedr13py", - "minWidth": 450.0, - "label": "GLOBAL API KEY", - "parentId": "lrtvcpswru", - "labelAlignment": "left", - "renderMode": "CANVAS", - "mobileTopRow": 6.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "maxDynamicHeight": 9000.0, - "shouldAllowAutofill": true, - "iconAlign": "left", - "defaultText": "{{appsmith.store.api_key || ''}}", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton2", - "onClick": "{{closeModal('ModalConfig');}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "parentRowSpace": 10.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "parentColumnSpace": 9.072265625, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 60.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "isDisabled": false, - "key": "pezy0hb491", - "isDeprecated": false, - "rightColumn": 64.0, - "iconName": "cross", - "widgetId": "oaouelmhi1", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 60.0, - "buttonVariant": "TERTIARY" - } - ], - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "lrtvcpswru", - "containerStyle": "none", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "h97rbttd5c", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "borderWidth": "0", - "positioning": "fixed", - "key": "dtzd07zsya", - "backgroundColor": "#FFFFFF", - "isDeprecated": false, - "rightColumn": 63.0, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "h97rbttd5c", - "minWidth": 450.0, - "isVisible": true, - "parentId": "es5gsctogb", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 44.0, - "responsiveBehavior": "fill", - "originalTopRow": 0.0, - "borderRadius": "0.375rem", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 28.0, - "minDynamicHeight": 10.0 - } - ], - "isDisabled": false, - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 282.0, - "detachFromLayout": true, - "widgetId": "es5gsctogb", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "gneh33z88k", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "g8xx6ocuvi", - "height": 300.0, - "isDeprecated": false, - "rightColumn": 25.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "gneh33z88k", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 49.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "width": 632.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 66.0, - "widgetName": "ModalInstance", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 42.0, - "bottomRow": 149.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 37.0, - "minHeight": 1490.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "leftColumn": 13.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas3", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 1490.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 1140.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton3Copy", - "onClick": "{{closeModal('ModalInstance');}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 57.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "iconSize": 24.0, - "isDisabled": false, - "key": "mr6bto7c8j", - "isDeprecated": false, - "rightColumn": 63.0, - "iconName": "cross", - "widgetId": "xofakp4har", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "esgwuzqcwt", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 58.0, - "buttonVariant": "TERTIARY" - }, - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}", - "topRow": 4.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "resetButtonStyles.buttonColor" }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.children.webhook.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.borderRadius" - }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.borderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.borderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.borderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.borderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.accentColor" - } - ], - "showReset": true, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY", - "iconAlign": "left" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Create", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 147.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "webhook": { - "children": { - "webhook": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "webhook", - "identifier": "webhook", - "position": 0.0, - "originalIdentifier": "webhook", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook" - }, - "events": { - "children": {}, - "dataType": "array", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Multiselect", - "sourceData": [ - "APPLICATION_STARTUP", - "QRCODE_UPDATED", - "MESSAGES_SET", - "MESSAGES_UPSERT", - "MESSAGES_UPDATE", - "MESSAGES_DELETE", - "SEND_MESSAGE", - "CONTACTS_SET", - "CONTACTS_UPSERT", - "CONTACTS_UPDATE", - "PRESENCE_UPDATE", - "CHATS_SET", - "CHATS_UPSERT", - "CHATS_UPDATE", - "CHATS_DELETE", - "GROUPS_UPSERT", - "GROUP_UPDATE", - "GROUP_PARTICIPANTS_UPDATE", - "CONNECTION_UPDATE", - "CALL", - "NEW_JWT_TOKEN" - ], - "isCustomField": false, - "accessor": "events", - "identifier": "events", - "position": 2.0, - "originalIdentifier": "events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Events", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]" - }, - "webhook_by_events": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "webhook_by_events", - "identifier": "webhook_by_events", - "position": 2.0, - "originalIdentifier": "webhook_by_events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook By Events" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "webhook", - "identifier": "webhook", - "position": 1.0, - "originalIdentifier": "webhook", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Webhook", - "labelStyle": "BOLD" - }, - "instance": { - "children": { - "instanceName": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "instanceName", - "identifier": "instanceName", - "position": 0.0, - "originalIdentifier": "instanceName", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Instance Name" - }, - "token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "token", - "identifier": "token", - "position": 1.0, - "originalIdentifier": "token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Token" - }, - "qrcode": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "qrcode", - "identifier": "qrcode", - "position": 2.0, - "originalIdentifier": "qrcode", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Qrcode" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "instance", - "identifier": "instance", - "position": 0.0, - "originalIdentifier": "instance", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Instance", - "labelStyle": "BOLD" - }, - "settings": { - "children": { - "reject_call": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "reject_call", - "identifier": "reject_call", - "position": 0.0, - "originalIdentifier": "reject_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reject Call" - }, - "msg_call": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "msg_call", - "identifier": "msg_call", - "position": 1.0, - "originalIdentifier": "msg_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Msg Call" - }, - "groups_ignore": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "groups_ignore", - "identifier": "groups_ignore", - "position": 2.0, - "originalIdentifier": "groups_ignore", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Groups Ignore" - }, - "always_online": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "always_online", - "identifier": "always_online", - "position": 3.0, - "originalIdentifier": "always_online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Always Online" - }, - "read_messages": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_messages", - "identifier": "read_messages", - "position": 4.0, - "originalIdentifier": "read_messages", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Messages" - }, - "read_status": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_status", - "identifier": "read_status", - "position": 5.0, - "originalIdentifier": "read_status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Status" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "settings", - "identifier": "settings", - "position": 2.0, - "originalIdentifier": "settings", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Settings", - "labelStyle": "BOLD" - }, - "chatwoot": { - "children": { - "chatwoot_account_id": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_account_id", - "identifier": "chatwoot_account_id", - "position": 0.0, - "originalIdentifier": "chatwoot_account_id", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Account Id" - }, - "chatwoot_token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Password Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_token", - "identifier": "chatwoot_token", - "position": 1.0, - "originalIdentifier": "chatwoot_token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Token", - "shouldAllowAutofill": true - }, - "chatwoot_url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_url", - "identifier": "chatwoot_url", - "position": 2.0, - "originalIdentifier": "chatwoot_url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Url" - }, - "chatwoot_sign_msg": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_sign_msg", - "identifier": "chatwoot_sign_msg", - "position": 3.0, - "originalIdentifier": "chatwoot_sign_msg", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Sign Msg" - }, - "chatwoot_reopen_conversation": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_reopen_conversation", - "identifier": "chatwoot_reopen_conversation", - "position": 4.0, - "originalIdentifier": "chatwoot_reopen_conversation", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Reopen Conversation" - }, - "chatwoot_conversation_pending": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_conversation_pending", - "identifier": "chatwoot_conversation_pending", - "position": 5.0, - "originalIdentifier": "chatwoot_conversation_pending", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Conversation Pending" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "chatwoot", - "identifier": "chatwoot", - "position": 3.0, - "originalIdentifier": "chatwoot", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Chatwoot", - "labelStyle": "BOLD" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "instanceName": "", - "token": "", - "webhook": "", - "webhook_by_events": false, - "events": [ - "APPLICATION_STARTUP", - "QRCODE_UPDATED", - "MESSAGES_SET", - "MESSAGES_UPSERT", - "MESSAGES_UPDATE", - "MESSAGES_DELETE", - "SEND_MESSAGE", - "CONTACTS_SET", - "CONTACTS_UPSERT", - "CONTACTS_UPDATE", - "PRESENCE_UPDATE", - "CHATS_SET", - "CHATS_UPSERT", - "CHATS_UPDATE", - "CHATS_DELETE", - "GROUPS_UPSERT", - "GROUP_UPDATE", - "GROUP_PARTICIPANTS_UPDATE", - "CONNECTION_UPDATE", - "CALL", - "NEW_JWT_TOKEN" - ], - "reject_call": false, - "msg_call": "", - "groups_ignore": false, - "always_online": false, - "read_messages": false, - "read_status": false, - "chatwoot_account_id": "", - "chatwoot_token": "", - "chatwoot_url": "", - "chatwoot_sign_msg": false, - "chatwoot_reopen_conversation": false, - "chatwoot_conversation_pending": false - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 85.0, - "widgetName": "FormInstance", - "submitButtonStyles": { - "buttonColor": "rgb(3, 179, 101)", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 147.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "New Instance", - "hideCard": false, - "mobileRightColumn": 22.0, - "shouldScrollContents": true, - "parentColumnSpace": 17.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "o0v8ypwnya", - "minWidth": 450.0, - "parentId": "esgwuzqcwt", - "renderMode": "CANVAS", - "mobileTopRow": 44.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 4.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "w17ra2a85u", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "esgwuzqcwt", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "rnttu90jzr", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "bkvkzj4d20", - "height": 1490.0, - "isDeprecated": false, - "rightColumn": 37.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "rnttu90jzr", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 42.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 13.0, - "maxDynamicHeight": 9000.0, - "width": 628.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "ButtonRefreshData", - "onClick": "{{fetch_Instances.run()}}", - "buttonColor": "#60a5fa", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 35.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 19.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "text": "", - "isDisabled": false, - "key": "k10nyfsas3", - "isDeprecated": false, - "rightColumn": 24.0, - "isDefaultClickDisabled": true, - "iconName": "refresh", - "widgetId": "dn1ehe3gvu", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 19.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "ButtonGroup1", - "isCanvas": false, - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button Group", - "iconSVG": "/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "groupButtons": { - "groupButton1": { - "label": "Connect", - "iconName": "camera", - "id": "groupButton1", - "widgetId": "", - "buttonType": "SIMPLE", - "placement": "CENTER", - "isVisible": true, - "isDisabled": false, - "index": 0.0, - "menuItems": {}, - "buttonColor": "#16a34a", - "onClick": "{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}" - }, - "groupButton2": { - "label": "Restart", - "iconName": "reset", - "id": "groupButton2", - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "", - "isVisible": true, - "isDisabled": false, - "index": 1.0, - "menuItems": {}, - "buttonColor": "#2563eb", - "onClick": "{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}" - }, - "groupButton3": { - "label": "Logout", - "iconName": "log-in", - "id": "groupButton3", - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "", - "isVisible": true, - "isDisabled": false, - "index": 2.0, - "menuItems": { - "menuItem1": { - "label": "First Option", - "backgroundColor": "#FFFFFF", - "id": "menuItem1", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 0.0 - }, - "menuItem2": { - "label": "Second Option", - "backgroundColor": "#FFFFFF", - "id": "menuItem2", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 1.0 - }, - "menuItem3": { - "label": "Delete", - "iconName": "trash", - "iconColor": "#FFFFFF", - "iconAlign": "right", - "textColor": "#FFFFFF", - "backgroundColor": "#DD4B34", - "id": "menuItem3", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 2.0 - } - }, - "buttonColor": "#a16207", - "onClick": "{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}" - }, - "groupButtonmghcs8rd4g": { - "id": "groupButtonmghcs8rd4g", - "index": 3.0, - "label": "Delete", - "menuItems": {}, - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "v0qkg2pjo2", - "isDisabled": false, - "isVisible": true, - "buttonColor": "#ef4444", - "iconName": "cross", - "onClick": "{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}" - } - }, - "type": "BUTTON_GROUP_WIDGET", - "hideCard": false, - "mobileRightColumn": 51.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [ - { "key": "groupButtons.groupButton1.onClick" }, - { "key": "groupButtons.groupButton2.onClick" }, - { "key": "groupButtons.groupButton3.onClick" }, - { "key": "groupButtons.groupButtonmghcs8rd4g.onClick" } - ], - "leftColumn": 27.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "isDisabled": false, - "key": "za8m3k8x7w", - "orientation": "horizontal", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "2s6fqi483g", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}" - } - }, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 27.0, - "buttonVariant": "PRIMARY" - }, - { - "boxShadow": "none", - "mobileBottomRow": 18.0, - "widgetName": "ProfilePicture", - "dynamicPropertyPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "displayName": "Image", - "iconSVG": "/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", - "topRow": 6.0, - "bottomRow": 28.0, - "parentRowSpace": 10.0, - "type": "IMAGE_WIDGET", - "hideCard": false, - "mobileRightColumn": 13.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "imageShape": "RECTANGLE", - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "image" }, - { "key": "isVisible" } - ], - "defaultImage": "https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1", - "key": "bl30j21wwb", - "image": "{{TableInstances.selectedRow.profilePictureUrl}}", - "isDeprecated": false, - "rightColumn": 13.0, - "objectFit": "contain", - "widgetId": "1sjznr31jo", - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 6.0, - "maxZoomLevel": 1.0, - "enableDownload": false, - "borderRadius": "0.335rem", - "mobileLeftColumn": 1.0, - "enableRotation": false - }, - { - "mobileBottomRow": 22.0, - "widgetName": "Text4", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 36.0, - "bottomRow": 42.0, - "parentRowSpace": 10.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 11.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "text" }, - { "key": "isVisible" }, - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}", - "key": "gqt8t28m33", - "isDeprecated": false, - "rightColumn": 13.0, - "textAlign": "CENTER", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "0c356c66hp", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 18.0, - "responsiveBehavior": "fill", - "originalTopRow": 36.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 41.0, - "fontSize": "0.875rem", - "minDynamicHeight": 4.0 - }, - { - "mobileBottomRow": 41.0, - "widgetName": "Text5", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 32.0, - "bottomRow": 36.0, - "parentRowSpace": 10.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 9.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "parentColumnSpace": 11.75, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "text" }, - { "key": "isVisible" }, - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "{{TableInstances.selectedRow.instance || ''}}", - "key": "gqt8t28m33", - "isDeprecated": false, - "rightColumn": 13.0, - "textAlign": "CENTER", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "5qg2iscn1l", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 37.0, - "responsiveBehavior": "fill", - "originalTopRow": 32.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 38.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalWebhook", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 46.0, - "bottomRow": 476.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 430.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 430.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.events.borderRadius" - }, - { - "key": "schema.__root_schema__.children.events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.accentColor" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_by_events.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" - }, - { "key": "borderRadius" }, - { - "key": "schema.__root_schema__.children.events.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.borderRadius" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 41.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "webhook_by_events": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "webhook_by_events", - "identifier": "webhook_by_events", - "position": 3.0, - "originalIdentifier": "webhook_by_events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook By Events" - }, - "enabled": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "enabled", - "identifier": "enabled", - "position": 0.0, - "originalIdentifier": "enabled", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Enabled" - }, - "url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c", - "isCustomField": false, - "accessor": "url", - "identifier": "url", - "position": 1.0, - "originalIdentifier": "url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Url" - }, - "events": { - "children": {}, - "dataType": "array", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Multiselect", - "sourceData": [], - "isCustomField": false, - "accessor": "events", - "identifier": "events", - "position": 2.0, - "originalIdentifier": "events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Events", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": [ - { "label": "Blue", "value": "BLUE" }, - { "label": "Green", "value": "GREEN" }, - { "label": "Red", "value": "RED" } - ] - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormWebhook", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 41.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Webhook", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "tb1ekur7fx", - "minWidth": 450.0, - "parentId": "mv02ta6pzr", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "mv02ta6pzr", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "0g8ql5hukz", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 430.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "0g8ql5hukz", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalSettings", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 46.0, - "bottomRow": 516.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 470.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4Copy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 470.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { - "key": "schema.__root_schema__.children.read_status.accentColor" - }, - { - "key": "schema.__root_schema__.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_messages.accentColor" - }, - { - "key": "schema.__root_schema__.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.always_online.accentColor" - }, - { - "key": "schema.__root_schema__.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.accentColor" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.msg_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.msg_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reject_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.reject_call.defaultValue" - }, - { "key": "borderRadius" }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.msg_call.borderRadius" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 45.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "reject_call": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "reject_call", - "identifier": "reject_call", - "position": 0.0, - "originalIdentifier": "reject_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reject Call" - }, - "msg_call": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "Não aceitamos chamadas!", - "isCustomField": false, - "accessor": "msg_call", - "identifier": "msg_call", - "position": 1.0, - "originalIdentifier": "msg_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Msg Call" - }, - "groups_ignore": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "groups_ignore", - "identifier": "groups_ignore", - "position": 2.0, - "originalIdentifier": "groups_ignore", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Groups Ignore" - }, - "always_online": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "always_online", - "identifier": "always_online", - "position": 3.0, - "originalIdentifier": "always_online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Always Online" - }, - "read_messages": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "read_messages", - "identifier": "read_messages", - "position": 4.0, - "originalIdentifier": "read_messages", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Messages" - }, - "read_status": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_status", - "identifier": "read_status", - "position": 5.0, - "originalIdentifier": "read_status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Status" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormSettings", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.msg_call.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 45.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Settings", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 64.0, - "widgetId": "3wajdobhry", - "minWidth": 450.0, - "parentId": "bj66ktxeor", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "bj66ktxeor", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "9pvl5efylb", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 470.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "9pvl5efylb", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalChatwoot", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 50.0, - "bottomRow": 780.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 730.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4CopyCopy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 730.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 730.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { - "key": "schema.__root_schema__.children.conversation_pending.accentColor" - }, - { - "key": "schema.__root_schema__.children.conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.accentColor" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.sign_msg.accentColor" - }, - { - "key": "schema.__root_schema__.children.sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.borderRadius" - }, - { - "key": "schema.__root_schema__.children.url.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.token.accentColor" - }, - { - "key": "schema.__root_schema__.children.token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.account_id.accentColor" - }, - { - "key": "schema.__root_schema__.children.account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.accentColor" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { "key": "borderRadius" }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.account_id.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook_url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_url.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook_url.borderRadius" - }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.name_inbox.defaultValue" - }, - { - "key": "schema.__root_schema__.children.name_inbox.borderRadius" - }, - { - "key": "schema.__root_schema__.children.name_inbox.accentColor" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 71.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "enabled": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "enabled", - "identifier": "enabled", - "position": 0.0, - "originalIdentifier": "enabled", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Enabled" - }, - "account_id": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "4", - "isCustomField": false, - "accessor": "account_id", - "identifier": "account_id", - "position": 1.0, - "originalIdentifier": "account_id", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Account Id" - }, - "token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Password Input", - "sourceData": "uHquVJgCdkee8JPJm9YBkdH6", - "isCustomField": false, - "accessor": "token", - "identifier": "token", - "position": 2.0, - "originalIdentifier": "token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Token", - "shouldAllowAutofill": true - }, - "url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://chatwoot.evolution.dgcode.com.br", - "isCustomField": false, - "accessor": "url", - "identifier": "url", - "position": 3.0, - "originalIdentifier": "url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Url" - }, - "sign_msg": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "sign_msg", - "identifier": "sign_msg", - "position": 4.0, - "originalIdentifier": "sign_msg", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Sign Msg" - }, - "reopen_conversation": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "reopen_conversation", - "identifier": "reopen_conversation", - "position": 5.0, - "originalIdentifier": "reopen_conversation", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reopen Conversation" - }, - "conversation_pending": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "conversation_pending", - "identifier": "conversation_pending", - "position": 6.0, - "originalIdentifier": "conversation_pending", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Conversation Pending" - }, - "webhook_url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4", - "isCustomField": false, - "accessor": "webhook_url", - "identifier": "webhook_url", - "position": 8.0, - "originalIdentifier": "webhook_url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": true, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook Url" - }, - "name_inbox": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "evolution-cwId-4", - "isCustomField": false, - "accessor": "name_inbox", - "identifier": "name_inbox", - "position": 7.0, - "originalIdentifier": "name_inbox", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": true, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Name Inbox" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormChatwoot", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_url.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 71.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Chatwoot", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "c5v1lwuyrk", - "minWidth": 450.0, - "parentId": "wqoo05rt9h", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "wqoo05rt9h", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "kekx3o71p4", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 730.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "kekx3o71p4", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 692.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 50.0, - "widgetName": "Button2", - "onClick": "{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}", - "buttonColor": "#2770fc", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 28.0, - "bottomRow": 32.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 21.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "isVisible" } - ], - "text": "Edit Profile", - "isDisabled": false, - "key": "zhd9fobc1z", - "isDeprecated": false, - "rightColumn": 13.0, - "isDefaultClickDisabled": true, - "iconName": "edit", - "widgetId": "uh6430ysqy", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "responsiveBehavior": "hug", - "originalTopRow": 51.0, - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 5.0, - "originalBottomRow": 55.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 59.0, - "widgetName": "ModalProfile", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 35.0, - "bottomRow": 975.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 940.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas5", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 940.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "submitButtonStyles.buttonColor" }, - { "key": "submitButtonStyles.borderRadius" }, - { "key": "resetButtonStyles.buttonColor" }, - { "key": "resetButtonStyles.borderRadius" }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.profileName.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profileName.accentColor" - }, - { - "key": "schema.__root_schema__.children.profileName.borderRadius" - }, - { - "key": "schema.__root_schema__.children.profileStatus.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profileStatus.accentColor" - }, - { - "key": "schema.__root_schema__.children.profileStatus.borderRadius" - }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.borderRadius" - }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.cellBorderRadius" - } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 92.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "profileName": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "profileName", - "identifier": "profileName", - "position": 1.0, - "originalIdentifier": "profileName", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Name" - }, - "profileStatus": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "profileStatus", - "identifier": "profileStatus", - "position": 2.0, - "originalIdentifier": "profileStatus", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Status" - }, - "profilePictureUrl": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E", - "isCustomField": false, - "accessor": "profilePictureUrl", - "identifier": "profilePictureUrl", - "position": 0.0, - "originalIdentifier": "profilePictureUrl", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Picture Url" - }, - "privacySettings": { - "children": { - "readreceipts": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "readreceipts", - "identifier": "readreceipts", - "position": 0.0, - "originalIdentifier": "readreceipts", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Readreceipts", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "profile": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "profile", - "identifier": "profile", - "position": 1.0, - "originalIdentifier": "profile", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Profile", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "status": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "contacts", - "isCustomField": false, - "accessor": "status", - "identifier": "status", - "position": 2.0, - "originalIdentifier": "status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Status", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "online": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "online", - "identifier": "online", - "position": 3.0, - "originalIdentifier": "online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Online", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]" - }, - "last": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "contacts", - "isCustomField": false, - "accessor": "last", - "identifier": "last", - "position": 4.0, - "originalIdentifier": "last", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Last", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "groupadd": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "groupadd", - "identifier": "groupadd", - "position": 5.0, - "originalIdentifier": "groupadd", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Groupadd", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "readreceipts": "all", - "profile": "all", - "status": "contacts", - "online": "all", - "last": "contacts", - "groupadd": "all" - }, - "isCustomField": false, - "accessor": "privacySettings", - "identifier": "privacySettings", - "position": 3.0, - "originalIdentifier": "privacySettings", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Privacy Settings", - "labelStyle": "BOLD" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormProfile", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [], - "displayName": "JSON Form", - "bottomRow": 92.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Edit Profile", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}", - "resetButtonLabel": "", - "key": "72nqor459k", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 64.0, - "widgetId": "hguxefink2", - "minWidth": 450.0, - "parentId": "basosxf5qt", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "mepf0qsn1e", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "basosxf5qt", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "ss96aihlej", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "4ktj7iym0b", - "height": 940.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "ss96aihlej", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 35.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - } - ] - }, - "layoutOnLoadActions": [ - [ - { - "id": "Page1_Scripts.verifyConfig", - "name": "Scripts.verifyConfig", - "collectionId": "Page1_Scripts", - "clientSideExecution": true, - "confirmBeforeExecute": false, - "pluginType": "JS", - "jsonPathKeys": [ - "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" - ], - "timeoutInMillisecond": 10000.0 - } - ] - ], - "layoutOnLoadActionErrors": [], - "validOnPageLoadActions": true, - "id": "Page1", - "deleted": false, - "policies": [], - "userPermissions": [] - } - ], - "userPermissions": [], - "policies": [] - }, - "publishedPage": { - "name": "Page1", - "slug": "page1", - "layouts": [ - { - "viewMode": false, - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 4896.0, - "snapColumns": 64.0, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0.0, - "bottomRow": 420.0, - "containerStyle": "none", - "snapRows": 124.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 80.0, - "minHeight": 1292.0, - "dynamicTriggerPathList": [], - "parentColumnSpace": 1.0, - "dynamicBindingPathList": [], - "leftColumn": 0.0, - "children": [ - { - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "borderColor": "#E0DEDE", - "isVisibleDownload": true, - "iconSVG": "https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg", - "topRow": 6.0, - "isSortable": true, - "type": "TABLE_WIDGET_V2", - "inlineEditingSaveOption": "ROW_LEVEL", - "animateLoading": true, - "dynamicBindingPathList": [ - { "key": "tableData" }, - { "key": "primaryColumns.customColumn9.boxShadow" }, - { "key": "primaryColumns.customColumn9.borderRadius" }, - { "key": "primaryColumns.customColumn9.menuColor" }, - { "key": "primaryColumns.customColumn8.computedValue" }, - { "key": "primaryColumns.customColumn7.computedValue" }, - { "key": "primaryColumns.customColumn6.computedValue" }, - { "key": "primaryColumns.customColumn5.computedValue" }, - { "key": "primaryColumns.customColumn2.computedValue" }, - { "key": "primaryColumns.customColumn1.textColor" }, - { "key": "primaryColumns.customColumn1.cellBackground" }, - { "key": "primaryColumns.customColumn1.computedValue" }, - { "key": "primaryColumns.instance.computedValue" }, - { "key": "isVisible" }, - { "key": "accentColor" }, - { "key": "borderRadius" }, - { "key": "boxShadow" } - ], - "needsHeightForContent": true, - "leftColumn": 14.0, - "delimiter": ",", - "defaultSelectedRowIndex": 0.0, - "showInlineEditingOptionDropdown": true, - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "isVisibleFilters": true, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "enableClientSideSearch": true, - "version": 2.0, - "totalRecordsCount": 0.0, - "isLoading": false, - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "editActions": { - "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - } - }, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "columnUpdatedAt": 1.690746223636e12, - "defaultSelectedRowIndices": [0.0], - "mobileBottomRow": 32.0, - "widgetName": "TableInstances", - "defaultPageSize": 0.0, - "columnOrder": [ - "instance", - "customColumn5", - "customColumn1", - "customColumn2", - "customColumn6", - "customColumn7", - "customColumn8", - "customColumn9" - ], - "dynamicPropertyPathList": [ - { "key": "primaryColumns.customColumn1.cellBackground" }, - { "key": "isVisible" } - ], - "displayName": "Table", - "bottomRow": 42.0, - "columnWidthMap": { - "customColumn3": 92.0, - "customColumn2": 340.0, - "customColumn5": 254.0, - "customColumn9": 97.0 - }, - "parentRowSpace": 10.0, - "hideCard": false, - "mobileRightColumn": 36.0, - "parentColumnSpace": 20.078125, - "dynamicTriggerPathList": [ - { - "key": "primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick" - }, - { - "key": "primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick" - }, - { - "key": "primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick" - } - ], - "borderWidth": "1", - "primaryColumns": { - "instance": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 0.0, - "width": 150.0, - "originalId": "instance", - "id": "instance", - "alias": "instance", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": false, - "label": "Instance", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}", - "sticky": "", - "validation": {} - }, - "customColumn1": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 1.0, - "width": 150.0, - "originalId": "customColumn1", - "id": "customColumn1", - "alias": "Status", - "horizontalAlignment": "CENTER", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Status", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF", - "cellBackground": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}", - "textColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}" - }, - "customColumn2": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 2.0, - "width": 150.0, - "originalId": "customColumn2", - "id": "customColumn2", - "alias": "Apikey", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Apikey", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn5": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 5.0, - "width": 150.0, - "originalId": "customColumn5", - "id": "customColumn5", - "alias": "Owner", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Owner", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn6": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 6.0, - "width": 150.0, - "originalId": "customColumn6", - "id": "customColumn6", - "alias": "profilePictureUrl", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profilePictureUrl", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn7": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 7.0, - "width": 150.0, - "originalId": "customColumn7", - "id": "customColumn7", - "alias": "profileName", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profileName", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn8": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 8.0, - "width": 150.0, - "originalId": "customColumn8", - "id": "customColumn8", - "alias": "profileStatus", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": false, - "isDerived": true, - "label": "profileStatus", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF" - }, - "customColumn9": { - "allowCellWrapping": false, - "allowSameOptionsInNewRow": true, - "index": 9.0, - "width": 150.0, - "originalId": "customColumn9", - "id": "customColumn9", - "alias": "Actions", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "menuButton", - "textSize": "0.875rem", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellEditable": false, - "isEditable": false, - "isCellVisible": true, - "isDerived": true, - "label": "Actions", - "isSaveVisible": true, - "isDiscardVisible": true, - "computedValue": "", - "sticky": "", - "validation": {}, - "buttonStyle": "rgb(3, 179, 101)", - "labelColor": "#FFFFFF", - "menuColor": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}", - "borderRadius": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}", - "boxShadow": "{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}", - "customAlias": "", - "menuItemsSource": "STATIC", - "menuButtonLabel": " ", - "menuButtoniconName": "chevron-down", - "menuItems": { - "menuItemjfzsd8g6yr": { - "id": "menuItemjfzsd8g6yr", - "index": 0.0, - "label": "Webhook", - "widgetId": "vygcejtdun", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Webhook.run();\nshowModal('ModalWebhook');}}" - }, - "menuItem4sqork5nmt": { - "id": "menuItem4sqork5nmt", - "index": 1.0, - "label": "Settings", - "widgetId": "0hw8oqpwcj", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Settings.run();\nshowModal('ModalSettings');}}" - }, - "menuItemig6ua4ixjx": { - "id": "menuItemig6ua4ixjx", - "index": 2.0, - "label": "Chatwoot", - "widgetId": "fuq5dtgbqc", - "isDisabled": false, - "isVisible": true, - "onClick": "{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}" - } - } - } - }, - "key": "e3yxhhyeel", - "canFreezeColumn": true, - "isDeprecated": false, - "rightColumn": 63.0, - "textSize": "0.875rem", - "widgetId": "uupm7enu8u", - "minWidth": 450.0, - "tableData": "{{fetch_Instances.data}}", - "label": "Data", - "searchKey": "", - "parentId": "0", - "renderMode": "CANVAS", - "mobileTopRow": 4.0, - "horizontalAlignment": "LEFT", - "isVisibleSearch": true, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "isVisiblePagination": true, - "verticalAlignment": "CENTER" - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "BtnNewInstance", - "onClick": "{{showModal('ModalInstance');}}", - "buttonColor": "rgb(3, 179, 101)", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 8.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 7.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "text": "New Instance", - "isDisabled": false, - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 19.0, - "isDefaultClickDisabled": true, - "iconName": "add", - "widgetId": "84ei9q1ugm", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 74.0, - "widgetName": "ModalQrcode", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 50.0, - "bottomRow": 500.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 45.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "leftColumn": 21.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas1", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 450.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 52.0, - "widgetName": "ImageQrcode", - "displayName": "Image", - "iconSVG": "https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", - "topRow": 6.0, - "bottomRow": 43.0, - "parentRowSpace": 10.0, - "type": "IMAGE_WIDGET", - "hideCard": false, - "mobileRightColumn": 55.0, - "animateLoading": true, - "parentColumnSpace": 20.078125, - "dynamicTriggerPathList": [], - "imageShape": "RECTANGLE", - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "image" }, - { "key": "borderRadius" } - ], - "defaultImage": "https://evolution-api.com/files/evolution-api-favicon.png", - "key": "4chlj9l432", - "image": "{{Connect.data.base64}}", - "isDeprecated": false, - "rightColumn": 61.0, - "objectFit": "contain", - "widgetId": "27dpgapd7q", - "isVisible": true, - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 40.0, - "maxZoomLevel": 1.0, - "enableDownload": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 43.0, - "enableRotation": false - }, - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton1", - "onClick": "{{closeModal('ModalQrcode');\nfetch_Instances.run()}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 58.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "iconSize": 24.0, - "isDisabled": false, - "key": "pezy0hb491", - "isDeprecated": false, - "rightColumn": 64.0, - "iconName": "cross", - "widgetId": "i1dw369dch", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 58.0, - "buttonVariant": "TERTIARY" - }, - { - "mobileBottomRow": 5.0, - "widgetName": "Text1", - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 1.0, - "bottomRow": 5.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 41.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "fontFamily" }], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "Qrcode", - "key": "9s8f10sepn", - "isDeprecated": false, - "rightColumn": 41.0, - "textAlign": "LEFT", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "mg2cqsi9fn", - "minWidth": 450.0, - "isVisible": true, - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "we6j3r2byy", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "we6j3r2byy", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "ljwryrjhy7", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "g8xx6ocuvi", - "height": 450.0, - "isDeprecated": false, - "rightColumn": 45.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "ljwryrjhy7", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 50.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 21.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "BtnConfig", - "onClick": "{{showModal('ModalConfig');}}", - "buttonColor": "#2563eb", - "dynamicPropertyPathList": [], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 30.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "text": "Access", - "isDisabled": false, - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 7.0, - "isDefaultClickDisabled": true, - "iconName": "user", - "widgetId": "uegjpy37i6", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 14.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 73.0, - "widgetName": "ModalConfig", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 49.0, - "bottomRow": 30.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 25.0, - "minHeight": 300.0, - "animateLoading": true, - "parentColumnSpace": 11.75, - "leftColumn": 1.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas2", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 300.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 300.0, - "mobileRightColumn": 282.0, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 84.0, - "borderColor": "#E0DEDE", - "widgetName": "FormConfig", - "isCanvas": true, - "displayName": "Form", - "iconSVG": "/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg", - "searchTags": ["group"], - "topRow": 0.0, - "bottomRow": 28.0, - "parentRowSpace": 10.0, - "type": "FORM_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 25.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [], - "children": [ - { - "mobileBottomRow": 400.0, - "widgetName": "Canvas2Copy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 280.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": false, - "hideCard": true, - "minHeight": 400.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "mobileBottomRow": 5.0, - "widgetName": "Text2", - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": [ - "typography", - "paragraph", - "label" - ], - "topRow": 1.0, - "bottomRow": 5.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 25.5, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "dynamicTriggerPathList": [], - "leftColumn": 1.5, - "dynamicBindingPathList": [ - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "Access Credentials", - "key": "9s8f10sepn", - "isDeprecated": false, - "rightColumn": 25.5, - "textAlign": "LEFT", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "tps5rw2lk9", - "minWidth": 450.0, - "isVisible": true, - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.5, - "maxDynamicHeight": 9000.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - }, - { - "resetFormOnClick": true, - "boxShadow": "none", - "mobileBottomRow": 37.0, - "widgetName": "Button1", - "onClick": "{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "dynamicPropertyPathList": [ - { "key": "isDisabled" } - ], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 22.0, - "bottomRow": 26.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 62.0, - "animateLoading": true, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 51.0, - "dynamicBindingPathList": [ - { "key": "isDisabled" }, - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "text": "Login", - "isDisabled": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 63.0, - "isDefaultClickDisabled": true, - "iconName": "log-in", - "widgetId": "gzxvnsxk0y", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 33.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 46.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "resetFormOnClick": true, - "boxShadow": "none", - "mobileBottomRow": 37.0, - "widgetName": "Button1Copy", - "onClick": "{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}", - "buttonColor": "#dc2626", - "dynamicPropertyPathList": [ - { "key": "isDisabled" } - ], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 21.0, - "bottomRow": 25.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 62.0, - "animateLoading": true, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "isDisabled" }, - { "key": "borderRadius" } - ], - "text": "Logout", - "isDisabled": "{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}", - "key": "crzwqv3pdr", - "isDeprecated": false, - "rightColumn": 14.0, - "isDefaultClickDisabled": true, - "iconName": "log-out", - "widgetId": "f2i8tsbgx1", - "minWidth": 120.0, - "isVisible": true, - "recaptchaType": "V3", - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 33.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 46.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", - "topRow": 6.0, - "labelWidth": 5.0, - "type": "INPUT_WIDGET_V2", - "animateLoading": true, - "resetOnSubmit": true, - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "defaultText" }, - { "key": "accentColor" }, - { "key": "borderRadius" } - ], - "labelStyle": "", - "inputType": "TEXT", - "placeholderText": "", - "isDisabled": false, - "isRequired": true, - "dynamicHeight": "FIXED", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "showStepArrows": false, - "isVisible": true, - "version": 2.0, - "isLoading": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileBottomRow": 13.0, - "widgetName": "InputApiUrl", - "displayName": "Input", - "searchTags": [ - "form", - "text input", - "number", - "textarea" - ], - "bottomRow": 13.0, - "parentRowSpace": 10.0, - "autoFocus": false, - "hideCard": false, - "mobileRightColumn": 22.0, - "parentColumnSpace": 5.047119140625, - "dynamicTriggerPathList": [], - "labelPosition": "Top", - "key": "r1hfat3ouf", - "labelTextSize": "0.875rem", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "spgryrb5ao", - "minWidth": 450.0, - "label": "API URL", - "parentId": "lrtvcpswru", - "labelAlignment": "left", - "renderMode": "CANVAS", - "mobileTopRow": 6.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "maxDynamicHeight": 9000.0, - "isSpellCheck": false, - "iconAlign": "left", - "defaultText": "{{appsmith.store.api_url || ''}}", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "iconSVG": "/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg", - "topRow": 14.0, - "labelWidth": 5.0, - "type": "INPUT_WIDGET_V2", - "animateLoading": true, - "resetOnSubmit": true, - "leftColumn": 2.0, - "dynamicBindingPathList": [ - { "key": "defaultText" }, - { "key": "accentColor" }, - { "key": "borderRadius" } - ], - "labelStyle": "", - "inputType": "PASSWORD", - "isDisabled": false, - "isRequired": true, - "dynamicHeight": "FIXED", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "showStepArrows": false, - "isVisible": true, - "version": 2.0, - "isLoading": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileBottomRow": 13.0, - "widgetName": "InputGlobalApiKey", - "displayName": "Input", - "searchTags": [ - "form", - "text input", - "number", - "textarea" - ], - "bottomRow": 21.0, - "parentRowSpace": 10.0, - "autoFocus": false, - "hideCard": false, - "mobileRightColumn": 22.0, - "parentColumnSpace": 5.047119140625, - "dynamicTriggerPathList": [], - "labelPosition": "Top", - "key": "r1hfat3ouf", - "labelTextSize": "0.875rem", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "v2vedr13py", - "minWidth": 450.0, - "label": "GLOBAL API KEY", - "parentId": "lrtvcpswru", - "labelAlignment": "left", - "renderMode": "CANVAS", - "mobileTopRow": 6.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 2.0, - "maxDynamicHeight": 9000.0, - "shouldAllowAutofill": true, - "iconAlign": "left", - "defaultText": "{{appsmith.store.api_key || ''}}", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton2", - "onClick": "{{closeModal('ModalConfig');}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "parentRowSpace": 10.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "parentColumnSpace": 9.072265625, - "dynamicTriggerPathList": [ - { "key": "onClick" } - ], - "leftColumn": 60.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "isDisabled": false, - "key": "pezy0hb491", - "isDeprecated": false, - "rightColumn": 64.0, - "iconName": "cross", - "widgetId": "oaouelmhi1", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "lrtvcpswru", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 60.0, - "buttonVariant": "TERTIARY" - } - ], - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "lrtvcpswru", - "containerStyle": "none", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "h97rbttd5c", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "borderWidth": "0", - "positioning": "fixed", - "key": "dtzd07zsya", - "backgroundColor": "#FFFFFF", - "isDeprecated": false, - "rightColumn": 63.0, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "h97rbttd5c", - "minWidth": 450.0, - "isVisible": true, - "parentId": "es5gsctogb", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 44.0, - "responsiveBehavior": "fill", - "originalTopRow": 0.0, - "borderRadius": "0.375rem", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 28.0, - "minDynamicHeight": 10.0 - } - ], - "isDisabled": false, - "key": "e8r23nd8j4", - "isDeprecated": false, - "rightColumn": 282.0, - "detachFromLayout": true, - "widgetId": "es5gsctogb", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "gneh33z88k", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "g8xx6ocuvi", - "height": 300.0, - "isDeprecated": false, - "rightColumn": 25.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "gneh33z88k", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 49.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 1.0, - "maxDynamicHeight": 9000.0, - "width": 632.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 66.0, - "widgetName": "ModalInstance", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 42.0, - "bottomRow": 149.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 37.0, - "minHeight": 1490.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "leftColumn": 13.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas3", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 1490.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 1140.0, - "mobileRightColumn": 283.875, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "mobileBottomRow": 4.0, - "widgetName": "IconButton3Copy", - "onClick": "{{closeModal('ModalInstance');}}", - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "displayName": "Icon button", - "iconSVG": "/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg", - "searchTags": ["click", "submit"], - "topRow": 0.0, - "bottomRow": 4.0, - "type": "ICON_BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 64.0, - "animateLoading": true, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 57.0, - "dynamicBindingPathList": [ - { "key": "buttonColor" }, - { "key": "borderRadius" } - ], - "iconSize": 24.0, - "isDisabled": false, - "key": "mr6bto7c8j", - "isDeprecated": false, - "rightColumn": 63.0, - "iconName": "cross", - "widgetId": "xofakp4har", - "minWidth": 50.0, - "isVisible": true, - "version": 1.0, - "parentId": "esgwuzqcwt", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "hug", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 58.0, - "buttonVariant": "TERTIARY" - }, - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}", - "topRow": 4.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "resetButtonStyles.buttonColor" }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.children.webhook.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.borderRadius" - }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.borderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.instanceName.borderRadius" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook.children.events.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.borderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.msg_call.borderRadius" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.accentColor" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.accentColor" - } - ], - "showReset": true, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY", - "iconAlign": "left" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Create", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 143.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "webhook": { - "children": { - "webhook": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "webhook", - "identifier": "webhook", - "position": 0.0, - "originalIdentifier": "webhook", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook" - }, - "events": { - "children": {}, - "dataType": "array", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Multiselect", - "sourceData": [ - "APPLICATION_STARTUP", - "QRCODE_UPDATED", - "MESSAGES_SET", - "MESSAGES_UPSERT", - "MESSAGES_UPDATE", - "MESSAGES_DELETE", - "SEND_MESSAGE", - "CONTACTS_SET", - "CONTACTS_UPSERT", - "CONTACTS_UPDATE", - "PRESENCE_UPDATE", - "CHATS_SET", - "CHATS_UPSERT", - "CHATS_UPDATE", - "CHATS_DELETE", - "GROUPS_UPSERT", - "GROUP_UPDATE", - "GROUP_PARTICIPANTS_UPDATE", - "CONNECTION_UPDATE", - "CALL", - "NEW_JWT_TOKEN" - ], - "isCustomField": false, - "accessor": "events", - "identifier": "events", - "position": 2.0, - "originalIdentifier": "events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Events", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]" - }, - "webhook_by_events": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "webhook_by_events", - "identifier": "webhook_by_events", - "position": 2.0, - "originalIdentifier": "webhook_by_events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook By Events" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "webhook", - "identifier": "webhook", - "position": 1.0, - "originalIdentifier": "webhook", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Webhook", - "labelStyle": "BOLD" - }, - "instance": { - "children": { - "instanceName": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "instanceName", - "identifier": "instanceName", - "position": 0.0, - "originalIdentifier": "instanceName", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Instance Name" - }, - "token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "token", - "identifier": "token", - "position": 1.0, - "originalIdentifier": "token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Token" - }, - "qrcode": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "qrcode", - "identifier": "qrcode", - "position": 2.0, - "originalIdentifier": "qrcode", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Qrcode" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "instance", - "identifier": "instance", - "position": 0.0, - "originalIdentifier": "instance", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Instance", - "labelStyle": "BOLD" - }, - "settings": { - "children": { - "reject_call": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "reject_call", - "identifier": "reject_call", - "position": 0.0, - "originalIdentifier": "reject_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reject Call" - }, - "msg_call": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "msg_call", - "identifier": "msg_call", - "position": 1.0, - "originalIdentifier": "msg_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Msg Call" - }, - "groups_ignore": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "groups_ignore", - "identifier": "groups_ignore", - "position": 2.0, - "originalIdentifier": "groups_ignore", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Groups Ignore" - }, - "always_online": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "always_online", - "identifier": "always_online", - "position": 3.0, - "originalIdentifier": "always_online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Always Online" - }, - "read_messages": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_messages", - "identifier": "read_messages", - "position": 4.0, - "originalIdentifier": "read_messages", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Messages" - }, - "read_status": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_status", - "identifier": "read_status", - "position": 5.0, - "originalIdentifier": "read_status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Status" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "settings", - "identifier": "settings", - "position": 2.0, - "originalIdentifier": "settings", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Settings", - "labelStyle": "BOLD" - }, - "chatwoot": { - "children": { - "chatwoot_account_id": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_account_id", - "identifier": "chatwoot_account_id", - "position": 0.0, - "originalIdentifier": "chatwoot_account_id", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Account Id" - }, - "chatwoot_token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Password Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_token", - "identifier": "chatwoot_token", - "position": 1.0, - "originalIdentifier": "chatwoot_token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Token", - "shouldAllowAutofill": true - }, - "chatwoot_url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "chatwoot_url", - "identifier": "chatwoot_url", - "position": 2.0, - "originalIdentifier": "chatwoot_url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Url" - }, - "chatwoot_sign_msg": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_sign_msg", - "identifier": "chatwoot_sign_msg", - "position": 3.0, - "originalIdentifier": "chatwoot_sign_msg", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Sign Msg" - }, - "chatwoot_reopen_conversation": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_reopen_conversation", - "identifier": "chatwoot_reopen_conversation", - "position": 4.0, - "originalIdentifier": "chatwoot_reopen_conversation", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Reopen Conversation" - }, - "chatwoot_conversation_pending": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "chatwoot_conversation_pending", - "identifier": "chatwoot_conversation_pending", - "position": 5.0, - "originalIdentifier": "chatwoot_conversation_pending", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Chatwoot Conversation Pending" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": {}, - "isCustomField": false, - "accessor": "chatwoot", - "identifier": "chatwoot", - "position": 3.0, - "originalIdentifier": "chatwoot", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Chatwoot", - "labelStyle": "BOLD" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "instanceName": "", - "token": "", - "webhook": "", - "webhook_by_events": false, - "events": [ - "APPLICATION_STARTUP", - "QRCODE_UPDATED", - "MESSAGES_SET", - "MESSAGES_UPSERT", - "MESSAGES_UPDATE", - "MESSAGES_DELETE", - "SEND_MESSAGE", - "CONTACTS_SET", - "CONTACTS_UPSERT", - "CONTACTS_UPDATE", - "PRESENCE_UPDATE", - "CHATS_SET", - "CHATS_UPSERT", - "CHATS_UPDATE", - "CHATS_DELETE", - "GROUPS_UPSERT", - "GROUP_UPDATE", - "GROUP_PARTICIPANTS_UPDATE", - "CONNECTION_UPDATE", - "CALL", - "NEW_JWT_TOKEN" - ], - "reject_call": false, - "msg_call": "", - "groups_ignore": false, - "always_online": false, - "read_messages": false, - "read_status": false, - "chatwoot_account_id": "", - "chatwoot_token": "", - "chatwoot_url": "", - "chatwoot_sign_msg": false, - "chatwoot_reopen_conversation": false, - "chatwoot_conversation_pending": false - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 85.0, - "widgetName": "FormInstance", - "submitButtonStyles": { - "buttonColor": "rgb(3, 179, 101)", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.settings.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.instance.children.qrcode.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 147.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "New Instance", - "hideCard": false, - "mobileRightColumn": 22.0, - "shouldScrollContents": true, - "parentColumnSpace": 17.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "o0v8ypwnya", - "minWidth": 450.0, - "parentId": "esgwuzqcwt", - "renderMode": "CANVAS", - "mobileTopRow": 44.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 4.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "w17ra2a85u", - "isDeprecated": false, - "rightColumn": 283.875, - "detachFromLayout": true, - "widgetId": "esgwuzqcwt", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "rnttu90jzr", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "bkvkzj4d20", - "height": 1490.0, - "isDeprecated": false, - "rightColumn": 37.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "rnttu90jzr", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 42.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 13.0, - "maxDynamicHeight": 9000.0, - "width": 628.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "ButtonRefreshData", - "onClick": "{{fetch_Instances.run()}}", - "buttonColor": "#60a5fa", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 35.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 19.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "text": "", - "isDisabled": false, - "key": "k10nyfsas3", - "isDeprecated": false, - "rightColumn": 24.0, - "isDefaultClickDisabled": true, - "iconName": "refresh", - "widgetId": "dn1ehe3gvu", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "hug", - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 19.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 5.0, - "widgetName": "ButtonGroup1", - "isCanvas": false, - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button Group", - "iconSVG": "/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg", - "searchTags": ["click", "submit"], - "topRow": 1.0, - "bottomRow": 5.0, - "parentRowSpace": 10.0, - "groupButtons": { - "groupButton1": { - "label": "Connect", - "iconName": "camera", - "id": "groupButton1", - "widgetId": "", - "buttonType": "SIMPLE", - "placement": "CENTER", - "isVisible": true, - "isDisabled": false, - "index": 0.0, - "menuItems": {}, - "buttonColor": "#16a34a", - "onClick": "{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}" - }, - "groupButton2": { - "label": "Restart", - "iconName": "reset", - "id": "groupButton2", - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "", - "isVisible": true, - "isDisabled": false, - "index": 1.0, - "menuItems": {}, - "buttonColor": "#2563eb", - "onClick": "{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}" - }, - "groupButton3": { - "label": "Logout", - "iconName": "log-in", - "id": "groupButton3", - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "", - "isVisible": true, - "isDisabled": false, - "index": 2.0, - "menuItems": { - "menuItem1": { - "label": "First Option", - "backgroundColor": "#FFFFFF", - "id": "menuItem1", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 0.0 - }, - "menuItem2": { - "label": "Second Option", - "backgroundColor": "#FFFFFF", - "id": "menuItem2", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 1.0 - }, - "menuItem3": { - "label": "Delete", - "iconName": "trash", - "iconColor": "#FFFFFF", - "iconAlign": "right", - "textColor": "#FFFFFF", - "backgroundColor": "#DD4B34", - "id": "menuItem3", - "widgetId": "", - "onClick": "", - "isVisible": true, - "isDisabled": false, - "index": 2.0 - } - }, - "buttonColor": "#a16207", - "onClick": "{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}" - }, - "groupButtonmghcs8rd4g": { - "id": "groupButtonmghcs8rd4g", - "index": 3.0, - "label": "Delete", - "menuItems": {}, - "buttonType": "SIMPLE", - "placement": "CENTER", - "widgetId": "v0qkg2pjo2", - "isDisabled": false, - "isVisible": true, - "buttonColor": "#ef4444", - "iconName": "cross", - "onClick": "{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}" - } - }, - "type": "BUTTON_GROUP_WIDGET", - "hideCard": false, - "mobileRightColumn": 51.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [ - { "key": "groupButtons.groupButton1.onClick" }, - { "key": "groupButtons.groupButton2.onClick" }, - { "key": "groupButtons.groupButton3.onClick" }, - { "key": "groupButtons.groupButtonmghcs8rd4g.onClick" } - ], - "leftColumn": 27.0, - "dynamicBindingPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "isDisabled": false, - "key": "za8m3k8x7w", - "orientation": "horizontal", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "2s6fqi483g", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 1.0, - "responsiveBehavior": "fill", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}" - } - }, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 27.0, - "buttonVariant": "PRIMARY" - }, - { - "boxShadow": "none", - "mobileBottomRow": 18.0, - "widgetName": "ProfilePicture", - "dynamicPropertyPathList": [ - { "key": "isVisible" }, - { "key": "borderRadius" } - ], - "displayName": "Image", - "iconSVG": "/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg", - "topRow": 6.0, - "bottomRow": 28.0, - "parentRowSpace": 10.0, - "type": "IMAGE_WIDGET", - "hideCard": false, - "mobileRightColumn": 13.0, - "animateLoading": true, - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "imageShape": "RECTANGLE", - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "image" }, - { "key": "isVisible" } - ], - "defaultImage": "https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1", - "key": "bl30j21wwb", - "image": "{{TableInstances.selectedRow.profilePictureUrl}}", - "isDeprecated": false, - "rightColumn": 13.0, - "objectFit": "contain", - "widgetId": "1sjznr31jo", - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 6.0, - "maxZoomLevel": 1.0, - "enableDownload": false, - "borderRadius": "0.335rem", - "mobileLeftColumn": 1.0, - "enableRotation": false - }, - { - "mobileBottomRow": 22.0, - "widgetName": "Text4", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 36.0, - "bottomRow": 41.0, - "parentRowSpace": 10.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 11.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "parentColumnSpace": 11.828125, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "text" }, - { "key": "isVisible" }, - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}", - "key": "gqt8t28m33", - "isDeprecated": false, - "rightColumn": 13.0, - "textAlign": "CENTER", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "0c356c66hp", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 18.0, - "responsiveBehavior": "fill", - "originalTopRow": 36.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 42.0, - "fontSize": "0.875rem", - "minDynamicHeight": 4.0 - }, - { - "mobileBottomRow": 41.0, - "widgetName": "Text5", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Text", - "iconSVG": "/static/media/icon.c3b6033f570046f8c6288d911333a827.svg", - "searchTags": ["typography", "paragraph", "label"], - "topRow": 32.0, - "bottomRow": 36.0, - "parentRowSpace": 10.0, - "type": "TEXT_WIDGET", - "hideCard": false, - "mobileRightColumn": 9.0, - "animateLoading": true, - "overflow": "NONE", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "parentColumnSpace": 11.75, - "dynamicTriggerPathList": [], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "text" }, - { "key": "isVisible" }, - { "key": "fontFamily" } - ], - "shouldTruncate": false, - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "text": "{{TableInstances.selectedRow.instance || ''}}", - "key": "gqt8t28m33", - "isDeprecated": false, - "rightColumn": 13.0, - "textAlign": "CENTER", - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "5qg2iscn1l", - "minWidth": 450.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}", - "fontStyle": "BOLD", - "textColor": "#231F20", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 37.0, - "responsiveBehavior": "fill", - "originalTopRow": 32.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "originalBottomRow": 38.0, - "fontSize": "1.25rem", - "minDynamicHeight": 4.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalWebhook", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 46.0, - "bottomRow": 43.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 430.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 430.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.events.borderRadius" - }, - { - "key": "schema.__root_schema__.children.events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.accentColor" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_by_events.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" - }, - { "key": "borderRadius" }, - { - "key": "schema.__root_schema__.children.events.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.borderRadius" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 41.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "webhook_by_events": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "webhook_by_events", - "identifier": "webhook_by_events", - "position": 3.0, - "originalIdentifier": "webhook_by_events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook By Events" - }, - "enabled": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "enabled", - "identifier": "enabled", - "position": 0.0, - "originalIdentifier": "enabled", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Enabled" - }, - "url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c", - "isCustomField": false, - "accessor": "url", - "identifier": "url", - "position": 1.0, - "originalIdentifier": "url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Url" - }, - "events": { - "children": {}, - "dataType": "array", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Multiselect", - "sourceData": [], - "isCustomField": false, - "accessor": "events", - "identifier": "events", - "position": 2.0, - "originalIdentifier": "events", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Events", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": [ - { "label": "Blue", "value": "BLUE" }, - { "label": "Green", "value": "GREEN" }, - { "label": "Red", "value": "RED" } - ] - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormWebhook", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.webhook_by_events.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 41.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Webhook", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "tb1ekur7fx", - "minWidth": 450.0, - "parentId": "mv02ta6pzr", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "mv02ta6pzr", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "0g8ql5hukz", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 430.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "0g8ql5hukz", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalSettings", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 46.0, - "bottomRow": 47.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 470.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4Copy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 470.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { - "key": "schema.__root_schema__.children.read_status.accentColor" - }, - { - "key": "schema.__root_schema__.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_messages.accentColor" - }, - { - "key": "schema.__root_schema__.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.always_online.accentColor" - }, - { - "key": "schema.__root_schema__.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.accentColor" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.msg_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.msg_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reject_call.accentColor" - }, - { - "key": "schema.__root_schema__.children.reject_call.defaultValue" - }, - { "key": "borderRadius" }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.msg_call.borderRadius" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 45.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "reject_call": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "reject_call", - "identifier": "reject_call", - "position": 0.0, - "originalIdentifier": "reject_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reject Call" - }, - "msg_call": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "Não aceitamos chamadas!", - "isCustomField": false, - "accessor": "msg_call", - "identifier": "msg_call", - "position": 1.0, - "originalIdentifier": "msg_call", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Msg Call" - }, - "groups_ignore": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "groups_ignore", - "identifier": "groups_ignore", - "position": 2.0, - "originalIdentifier": "groups_ignore", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Groups Ignore" - }, - "always_online": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "always_online", - "identifier": "always_online", - "position": 3.0, - "originalIdentifier": "always_online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Always Online" - }, - "read_messages": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "read_messages", - "identifier": "read_messages", - "position": 4.0, - "originalIdentifier": "read_messages", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Messages" - }, - "read_status": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "read_status", - "identifier": "read_status", - "position": 5.0, - "originalIdentifier": "read_status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Read Status" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormSettings", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.reject_call.defaultValue" - }, - { - "key": "schema.__root_schema__.children.groups_ignore.defaultValue" - }, - { - "key": "schema.__root_schema__.children.always_online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_messages.defaultValue" - }, - { - "key": "schema.__root_schema__.children.read_status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.msg_call.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 45.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Settings", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 64.0, - "widgetId": "3wajdobhry", - "minWidth": 450.0, - "parentId": "bj66ktxeor", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "bj66ktxeor", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "9pvl5efylb", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 470.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "9pvl5efylb", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - }, - { - "boxShadow": "none", - "mobileBottomRow": 70.0, - "widgetName": "ModalChatwoot", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 50.0, - "bottomRow": 73.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 730.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas4CopyCopy", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 730.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 730.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { - "key": "schema.__root_schema__.children.conversation_pending.accentColor" - }, - { - "key": "schema.__root_schema__.children.conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.accentColor" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.sign_msg.accentColor" - }, - { - "key": "schema.__root_schema__.children.sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.url.borderRadius" - }, - { - "key": "schema.__root_schema__.children.url.accentColor" - }, - { - "key": "schema.__root_schema__.children.url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.token.borderRadius" - }, - { - "key": "schema.__root_schema__.children.token.accentColor" - }, - { - "key": "schema.__root_schema__.children.token.defaultValue" - }, - { - "key": "schema.__root_schema__.children.account_id.accentColor" - }, - { - "key": "schema.__root_schema__.children.account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.enabled.accentColor" - }, - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { "key": "borderRadius" }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.account_id.borderRadius" - }, - { - "key": "schema.__root_schema__.children.webhook_url.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_url.accentColor" - }, - { - "key": "schema.__root_schema__.children.webhook_url.borderRadius" - }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.name_inbox.defaultValue" - }, - { - "key": "schema.__root_schema__.children.name_inbox.borderRadius" - }, - { - "key": "schema.__root_schema__.children.name_inbox.accentColor" - }, - { "key": "submitButtonStyles.buttonColor" } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 71.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "enabled": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "enabled", - "identifier": "enabled", - "position": 0.0, - "originalIdentifier": "enabled", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Enabled" - }, - "account_id": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "4", - "isCustomField": false, - "accessor": "account_id", - "identifier": "account_id", - "position": 1.0, - "originalIdentifier": "account_id", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Account Id" - }, - "token": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Password Input", - "sourceData": "uHquVJgCdkee8JPJm9YBkdH6", - "isCustomField": false, - "accessor": "token", - "identifier": "token", - "position": 2.0, - "originalIdentifier": "token", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Token", - "shouldAllowAutofill": true - }, - "url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://chatwoot.evolution.dgcode.com.br", - "isCustomField": false, - "accessor": "url", - "identifier": "url", - "position": 3.0, - "originalIdentifier": "url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Url" - }, - "sign_msg": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "sign_msg", - "identifier": "sign_msg", - "position": 4.0, - "originalIdentifier": "sign_msg", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Sign Msg" - }, - "reopen_conversation": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": true, - "isCustomField": false, - "accessor": "reopen_conversation", - "identifier": "reopen_conversation", - "position": 5.0, - "originalIdentifier": "reopen_conversation", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Reopen Conversation" - }, - "conversation_pending": { - "children": {}, - "dataType": "boolean", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Switch", - "sourceData": false, - "isCustomField": false, - "accessor": "conversation_pending", - "identifier": "conversation_pending", - "position": 6.0, - "originalIdentifier": "conversation_pending", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "alignWidget": "LEFT", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Conversation Pending" - }, - "webhook_url": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4", - "isCustomField": false, - "accessor": "webhook_url", - "identifier": "webhook_url", - "position": 8.0, - "originalIdentifier": "webhook_url", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": true, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Webhook Url" - }, - "name_inbox": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "evolution-cwId-4", - "isCustomField": false, - "accessor": "name_inbox", - "identifier": "name_inbox", - "position": 7.0, - "originalIdentifier": "name_inbox", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": true, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Name Inbox" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormChatwoot", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [ - { - "key": "schema.__root_schema__.children.enabled.defaultValue" - }, - { - "key": "schema.__root_schema__.children.sign_msg.defaultValue" - }, - { - "key": "schema.__root_schema__.children.reopen_conversation.defaultValue" - }, - { - "key": "schema.__root_schema__.children.conversation_pending.defaultValue" - }, - { - "key": "schema.__root_schema__.children.account_id.defaultValue" - }, - { - "key": "schema.__root_schema__.children.webhook_url.defaultValue" - } - ], - "displayName": "JSON Form", - "bottomRow": 71.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Chatwoot", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}", - "resetButtonLabel": "Reset", - "key": "lgqqk5r1jk", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 63.0, - "widgetId": "c5v1lwuyrk", - "minWidth": 450.0, - "parentId": "wqoo05rt9h", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "svq68rvpdn", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "wqoo05rt9h", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "kekx3o71p4", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "6x3z5yow7u", - "height": 730.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "kekx3o71p4", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 692.0, - "minDynamicHeight": 24.0 - }, - { - "resetFormOnClick": false, - "boxShadow": "none", - "mobileBottomRow": 50.0, - "widgetName": "Button2", - "onClick": "{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}", - "buttonColor": "#2770fc", - "dynamicPropertyPathList": [{ "key": "isVisible" }], - "displayName": "Button", - "iconSVG": "/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg", - "searchTags": ["click", "submit"], - "topRow": 28.0, - "bottomRow": 32.0, - "parentRowSpace": 10.0, - "type": "BUTTON_WIDGET", - "hideCard": false, - "mobileRightColumn": 21.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "dynamicTriggerPathList": [{ "key": "onClick" }], - "leftColumn": 1.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "isVisible" } - ], - "text": "Edit Profile", - "isDisabled": false, - "key": "zhd9fobc1z", - "isDeprecated": false, - "rightColumn": 13.0, - "isDefaultClickDisabled": true, - "iconName": "edit", - "widgetId": "uh6430ysqy", - "minWidth": 120.0, - "isVisible": "{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}", - "recaptchaType": "V3", - "version": 1.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 46.0, - "responsiveBehavior": "hug", - "originalTopRow": 51.0, - "disabledWhenInvalid": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 5.0, - "originalBottomRow": 55.0, - "buttonVariant": "PRIMARY", - "iconAlign": "left", - "placement": "CENTER" - }, - { - "boxShadow": "none", - "mobileBottomRow": 59.0, - "widgetName": "ModalProfile", - "isCanvas": true, - "displayName": "Modal", - "iconSVG": "/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg", - "searchTags": ["dialog", "popup", "notification"], - "topRow": 35.0, - "bottomRow": 94.0, - "parentRowSpace": 10.0, - "type": "MODAL_WIDGET", - "hideCard": false, - "shouldScrollContents": true, - "mobileRightColumn": 35.0, - "minHeight": 940.0, - "animateLoading": true, - "parentColumnSpace": 17.9375, - "leftColumn": 11.0, - "dynamicBindingPathList": [{ "key": "borderRadius" }], - "children": [ - { - "mobileBottomRow": 240.0, - "widgetName": "Canvas5", - "displayName": "Canvas", - "topRow": 0.0, - "bottomRow": 940.0, - "parentRowSpace": 1.0, - "type": "CANVAS_WIDGET", - "canExtend": true, - "hideCard": true, - "shouldScrollContents": false, - "minHeight": 240.0, - "mobileRightColumn": 430.5, - "parentColumnSpace": 1.0, - "leftColumn": 0.0, - "dynamicBindingPathList": [], - "children": [ - { - "boxShadow": "none", - "borderColor": "#E0DEDE", - "iconSVG": "/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg", - "onSubmit": "{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}", - "topRow": 0.0, - "type": "JSON_FORM_WIDGET", - "animateLoading": true, - "leftColumn": 0.0, - "dynamicBindingPathList": [ - { "key": "borderRadius" }, - { "key": "submitButtonStyles.buttonColor" }, - { "key": "submitButtonStyles.borderRadius" }, - { "key": "resetButtonStyles.buttonColor" }, - { "key": "resetButtonStyles.borderRadius" }, - { "key": "schema.__root_schema__.defaultValue" }, - { "key": "schema.__root_schema__.borderRadius" }, - { - "key": "schema.__root_schema__.cellBorderRadius" - }, - { - "key": "schema.__root_schema__.children.profileName.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profileName.accentColor" - }, - { - "key": "schema.__root_schema__.children.profileName.borderRadius" - }, - { - "key": "schema.__root_schema__.children.profileStatus.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profileStatus.accentColor" - }, - { - "key": "schema.__root_schema__.children.profileStatus.borderRadius" - }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.defaultValue" - }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.borderRadius" - }, - { "key": "sourceData" }, - { - "key": "schema.__root_schema__.children.profilePictureUrl.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.profile.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.status.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.online.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.last.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.accentColor" - }, - { - "key": "schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.defaultValue" - }, - { - "key": "schema.__root_schema__.children.privacySettings.borderRadius" - }, - { - "key": "schema.__root_schema__.children.privacySettings.cellBorderRadius" - } - ], - "showReset": false, - "dynamicHeight": "AUTO_HEIGHT", - "autoGenerateForm": true, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "SECONDARY" - }, - "isVisible": true, - "version": 1.0, - "isLoading": false, - "submitButtonLabel": "Save", - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - }, - "disabledWhenInvalid": true, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "originalBottomRow": 92.0, - "useSourceData": false, - "schema": { - "__root_schema__": { - "children": { - "profileName": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "profileName", - "identifier": "profileName", - "position": 1.0, - "originalIdentifier": "profileName", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Name" - }, - "profileStatus": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "", - "isCustomField": false, - "accessor": "profileStatus", - "identifier": "profileStatus", - "position": 2.0, - "originalIdentifier": "profileStatus", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Status" - }, - "profilePictureUrl": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Text Input", - "sourceData": "https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E", - "isCustomField": false, - "accessor": "profilePictureUrl", - "identifier": "profilePictureUrl", - "position": 0.0, - "originalIdentifier": "profilePictureUrl", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "iconAlign": "left", - "isDisabled": false, - "isRequired": false, - "isSpellCheck": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "Profile Picture Url" - }, - "privacySettings": { - "children": { - "readreceipts": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "readreceipts", - "identifier": "readreceipts", - "position": 0.0, - "originalIdentifier": "readreceipts", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Readreceipts", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "profile": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "profile", - "identifier": "profile", - "position": 1.0, - "originalIdentifier": "profile", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Profile", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "status": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "contacts", - "isCustomField": false, - "accessor": "status", - "identifier": "status", - "position": 2.0, - "originalIdentifier": "status", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Status", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "online": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "online", - "identifier": "online", - "position": 3.0, - "originalIdentifier": "online", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Online", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]" - }, - "last": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "contacts", - "isCustomField": false, - "accessor": "last", - "identifier": "last", - "position": 4.0, - "originalIdentifier": "last", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Last", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - }, - "groupadd": { - "children": {}, - "dataType": "string", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Select", - "sourceData": "all", - "isCustomField": false, - "accessor": "groupadd", - "identifier": "groupadd", - "position": 5.0, - "originalIdentifier": "groupadd", - "accentColor": "{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "isDisabled": false, - "isFilterable": false, - "isRequired": false, - "isVisible": true, - "label": "Groupadd", - "labelTextSize": "0.875rem", - "serverSideFiltering": false, - "options": "[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "readreceipts": "all", - "profile": "all", - "status": "contacts", - "online": "all", - "last": "contacts", - "groupadd": "all" - }, - "isCustomField": false, - "accessor": "privacySettings", - "identifier": "privacySettings", - "position": 3.0, - "originalIdentifier": "privacySettings", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "1rem", - "label": "Privacy Settings", - "labelStyle": "BOLD" - } - }, - "dataType": "object", - "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "fieldType": "Object", - "sourceData": { - "name": "John", - "date_of_birth": "20/02/1990", - "employee_id": 1001.0 - }, - "isCustomField": false, - "accessor": "__root_schema__", - "identifier": "__root_schema__", - "position": -1.0, - "originalIdentifier": "__root_schema__", - "borderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "boxShadow": "none", - "cellBorderRadius": "{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}", - "cellBoxShadow": "none", - "isDisabled": false, - "isRequired": false, - "isVisible": true, - "labelTextSize": "0.875rem", - "label": "" - } - }, - "mobileBottomRow": 41.0, - "widgetName": "FormProfile", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "buttonVariant": "PRIMARY" - }, - "dynamicPropertyPathList": [], - "displayName": "JSON Form", - "bottomRow": 92.0, - "fieldLimitExceeded": false, - "parentRowSpace": 10.0, - "title": "Edit Profile", - "hideCard": false, - "mobileRightColumn": 25.0, - "parentColumnSpace": 6.9375, - "dynamicTriggerPathList": [{ "key": "onSubmit" }], - "borderWidth": "0", - "sourceData": "{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}", - "resetButtonLabel": "", - "key": "72nqor459k", - "backgroundColor": "#fff", - "isDeprecated": false, - "rightColumn": 64.0, - "widgetId": "hguxefink2", - "minWidth": 450.0, - "parentId": "basosxf5qt", - "renderMode": "CANVAS", - "mobileTopRow": 0.0, - "scrollContents": true, - "responsiveBehavior": "fill", - "fixedFooter": true, - "originalTopRow": 0.0, - "mobileLeftColumn": 0.0, - "maxDynamicHeight": 9000.0, - "minDynamicHeight": 4.0 - } - ], - "isDisabled": false, - "key": "mepf0qsn1e", - "isDeprecated": false, - "rightColumn": 430.5, - "detachFromLayout": true, - "widgetId": "basosxf5qt", - "minWidth": 450.0, - "isVisible": true, - "version": 1.0, - "parentId": "ss96aihlej", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 0.0, - "responsiveBehavior": "fill", - "mobileLeftColumn": 0.0, - "flexLayers": [] - } - ], - "key": "4ktj7iym0b", - "height": 940.0, - "isDeprecated": false, - "rightColumn": 35.0, - "detachFromLayout": true, - "dynamicHeight": "AUTO_HEIGHT", - "widgetId": "ss96aihlej", - "canOutsideClickClose": true, - "canEscapeKeyClose": true, - "version": 2.0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "mobileTopRow": 35.0, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "mobileLeftColumn": 11.0, - "maxDynamicHeight": 9000.0, - "width": 456.0, - "minDynamicHeight": 24.0 - } - ] - }, - "layoutOnLoadActions": [ - [ - { - "id": "Page1_Scripts.verifyConfig", - "name": "Scripts.verifyConfig", - "collectionId": "Page1_Scripts", - "clientSideExecution": true, - "confirmBeforeExecute": false, - "pluginType": "JS", - "jsonPathKeys": [ - "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" - ], - "timeoutInMillisecond": 10000.0 - } - ] - ], - "layoutOnLoadActionErrors": [], - "validOnPageLoadActions": true, - "id": "Page1", - "deleted": false, - "policies": [], - "userPermissions": [] - } - ], - "userPermissions": [], - "policies": [] - }, - "deleted": false, - "gitSyncId": "64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56" - } - ], - "actionList": [ - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "fetch_Instances", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/fetchInstances", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": ["appsmith.store.api_url", "appsmith.store.api_key"], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "publishedAction": { - "name": "fetch_Instances", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/fetchInstances", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": ["appsmith.store.api_url", "appsmith.store.api_key"], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "id": "Page1_fetch_Instances", - "deleted": false, - "gitSyncId": "64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788" - }, - { - "pluginType": "JS", - "pluginId": "js-plugin", - "unpublishedAction": { - "name": "verifyConfig", - "fullyQualifiedName": "Scripts.verifyConfig", - "datasource": { - "name": "UNUSED_DATASOURCE", - "pluginId": "js-plugin", - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "collectionId": "Page1_Scripts", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}", - "selfReferencingDataPaths": [], - "jsArguments": [], - "isAsync": true - }, - "executeOnLoad": true, - "clientSideExecution": true, - "dynamicBindingPathList": [{ "key": "body" }], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "publishedAction": { - "name": "verifyConfig", - "fullyQualifiedName": "Scripts.verifyConfig", - "datasource": { - "name": "UNUSED_DATASOURCE", - "pluginId": "js-plugin", - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "collectionId": "Page1_Scripts", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}", - "selfReferencingDataPaths": [], - "jsArguments": [], - "isAsync": true - }, - "executeOnLoad": true, - "clientSideExecution": true, - "dynamicBindingPathList": [{ "key": "body" }], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "id": "Page1_Scripts.verifyConfig", - "deleted": false, - "gitSyncId": "64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Connect", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/connect/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "publishedAction": { - "name": "Connect", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/connect/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-29T16:12:42Z" - }, - "id": "Page1_Connect", - "deleted": false, - "gitSyncId": "64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Restart", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/restart/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:01:05Z" - }, - "publishedAction": { - "name": "Restart", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/restart/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:01:05Z" - }, - "id": "Page1_Restart", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Logout", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/logout/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:02:00Z" - }, - "publishedAction": { - "name": "Logout", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/logout/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:02:00Z" - }, - "id": "Page1_Logout", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Delete", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/delete/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:02:32Z" - }, - "publishedAction": { - "name": "Delete", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/delete/{{TableInstances.selectedRow.instance}}", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:02:32Z" - }, - "id": "Page1_Delete", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Create_Instance", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/create", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}", - "bodyFormData": [ - { - "key": "instanceName", - "value": "{{FormInstance.data.InputNewInstanceName}}" - }, - { - "key": "token", - "value": "{{FormInstance.data.InputNewInstanceToken}}" - } - ], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "bodyFormData[0].value" }, - { "key": "bodyFormData[1].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n", - "FormInstance.data.InputNewInstanceName", - "FormInstance.data.InputNewInstanceToken", - "appsmith.store.api_url", - "appsmith.store.api_key" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:22:09Z" - }, - "publishedAction": { - "name": "Create_Instance", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/create", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}", - "bodyFormData": [ - { - "key": "instanceName", - "value": "{{FormInstance.data.InputNewInstanceName}}" - }, - { - "key": "token", - "value": "{{FormInstance.data.InputNewInstanceToken}}" - } - ], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "bodyFormData[0].value" }, - { "key": "bodyFormData[1].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n", - "FormInstance.data.InputNewInstanceName", - "FormInstance.data.InputNewInstanceToken", - "appsmith.store.api_url", - "appsmith.store.api_key" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T03:22:09Z" - }, - "id": "Page1_Create_Instance", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Find_Webhook", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/webhook/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:46:50Z" - }, - "publishedAction": { - "name": "Find_Webhook", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/webhook/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:46:50Z" - }, - "id": "Page1_Find_Webhook", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Find_Settings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/settings/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:48:45Z" - }, - "publishedAction": { - "name": "Find_Settings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/settings/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:48:45Z" - }, - "id": "Page1_Find_Settings", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Find_Chatwoot", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chatwoot/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:49:33Z" - }, - "publishedAction": { - "name": "Find_Chatwoot", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chatwoot/find/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T19:49:33Z" - }, - "id": "Page1_Find_Chatwoot", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Set_Webhook", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/webhook/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormWebhook.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\tFormWebhook.formData\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:10:19Z" - }, - "publishedAction": { - "name": "Set_Webhook", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/webhook/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormWebhook.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\tFormWebhook.formData\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:10:19Z" - }, - "id": "Page1_Set_Webhook", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Set_Settings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/settings/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormSettings.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "\n\tFormSettings.formData\n", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:13:25Z" - }, - "publishedAction": { - "name": "Set_Settings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/settings/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormSettings.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "\n\tFormSettings.formData\n", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:13:25Z" - }, - "id": "Page1_Set_Settings", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Set_Chatwoot", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chatwoot/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormChatwoot.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\tFormChatwoot.formData\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:15:01Z" - }, - "publishedAction": { - "name": "Set_Chatwoot", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chatwoot/set/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\tFormChatwoot.formData\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\tFormChatwoot.formData\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-30T20:15:01Z" - }, - "id": "Page1_Set_Chatwoot", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Fetch_Instance", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/fetchInstances", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [ - { - "key": "instanceName", - "value": "{{TableInstances.selectedRow.instance}}" - } - ], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "queryParameters[0].value" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:16:40Z" - }, - "publishedAction": { - "name": "Fetch_Instance", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/instance/fetchInstances", - "headers": [ - { "key": "apikey", "value": "{{appsmith.store.api_key}}" } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [ - { - "key": "instanceName", - "value": "{{TableInstances.selectedRow.instance}}" - } - ], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "queryParameters[0].value" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "appsmith.store.api_url", - "appsmith.store.api_key", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:16:40Z" - }, - "id": "Page1_Fetch_Instance", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Update_ProfileName", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfileName/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:22:45Z" - }, - "publishedAction": { - "name": "Update_ProfileName", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfileName/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:22:45Z" - }, - "id": "Page1_Update_ProfileName", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Update_ProfileStatus", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfileStatus/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "body" }, - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:25:00Z" - }, - "publishedAction": { - "name": "Update_ProfileStatus", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfileStatus/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "application/json" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "body" }, - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:25:00Z" - }, - "id": "Page1_Update_ProfileStatus", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Update_ProfilePicture", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfilePicture/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:25:56Z" - }, - "publishedAction": { - "name": "Update_ProfilePicture", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updateProfilePicture/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" }, - { "key": "body" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:25:56Z" - }, - "id": "Page1_Update_ProfilePicture", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Remove_ProfilePicture", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/removeProfilePicture/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:27:20Z" - }, - "publishedAction": { - "name": "Remove_ProfilePicture", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/removeProfilePicture/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "bodyFormData": [], - "httpMethod": "DELETE", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:27:20Z" - }, - "id": "Page1_Remove_ProfilePicture", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Fetch_PrivacySettings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:27:52Z" - }, - "publishedAction": { - "name": "Fetch_PrivacySettings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [], - "encodeParamsToggle": true, - "queryParameters": [], - "bodyFormData": [], - "httpMethod": "GET", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "path" }, - { "key": "headers[0].value" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": true, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:27:52Z" - }, - "id": "Page1_Fetch_PrivacySettings", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62" - }, - { - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "Update_PrivacySettings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "headers[0].value" }, - { "key": "body" }, - { "key": "path" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:28:39Z" - }, - "publishedAction": { - "name": "Update_PrivacySettings", - "datasource": { - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { "url": "" }, - "invalids": [], - "messages": [], - "isAutoGenerated": false, - "deleted": false, - "policies": [], - "userPermissions": [] - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000.0, - "paginationType": "NONE", - "path": "{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{TableInstances.selectedRow.instance}}", - "headers": [ - { - "key": "apikey", - "value": "{{TableInstances.selectedRow.Apikey}}" - } - ], - "autoGeneratedHeaders": [ - { "key": "content-type", "value": "application/json" } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}", - "bodyFormData": [], - "httpMethod": "PUT", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [{ "value": true }], - "formData": { "apiContentType": "none" } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { "key": "headers[0].value" }, - { "key": "body" }, - { "key": "path" } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "TableInstances.selectedRow.Apikey", - "\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n", - "appsmith.store.api_url", - "TableInstances.selectedRow.instance" - ], - "userSetOnLoad": false, - "confirmBeforeExecute": false, - "policies": [], - "userPermissions": [], - "createdAt": "2023-07-31T12:28:39Z" - }, - "id": "Page1_Update_PrivacySettings", - "deleted": false, - "gitSyncId": "64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64" - } - ], - "actionCollectionList": [ - { - "unpublishedCollection": { - "name": "Scripts", - "pageId": "Page1", - "pluginId": "js-plugin", - "pluginType": "JS", - "actions": [], - "archivedActions": [], - "body": "export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}", - "variables": [ - { "name": "myVar1", "value": "[]" }, - { "name": "myVar2", "value": "{}" } - ], - "userPermissions": [] - }, - "publishedCollection": { - "name": "Scripts", - "pageId": "Page1", - "pluginId": "js-plugin", - "pluginType": "JS", - "actions": [], - "archivedActions": [], - "body": "export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}", - "variables": [ - { "name": "myVar1", "value": "[]" }, - { "name": "myVar2", "value": "{}" } - ], - "userPermissions": [] - }, - "id": "Page1_Scripts", - "deleted": false, - "gitSyncId": "64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e" - } - ], - "updatedResources": { - "customJSLibList": [], - "actionList": [ - "Scripts.verifyConfig##ENTITY_SEPARATOR##Page1", - "Find_Chatwoot##ENTITY_SEPARATOR##Page1", - "Connect##ENTITY_SEPARATOR##Page1", - "Update_PrivacySettings##ENTITY_SEPARATOR##Page1", - "Fetch_Instance##ENTITY_SEPARATOR##Page1", - "fetch_Instances##ENTITY_SEPARATOR##Page1", - "Fetch_PrivacySettings##ENTITY_SEPARATOR##Page1", - "Restart##ENTITY_SEPARATOR##Page1", - "Update_ProfileName##ENTITY_SEPARATOR##Page1", - "Find_Settings##ENTITY_SEPARATOR##Page1", - "Set_Chatwoot##ENTITY_SEPARATOR##Page1", - "Delete##ENTITY_SEPARATOR##Page1", - "Create_Instance##ENTITY_SEPARATOR##Page1", - "Update_ProfileStatus##ENTITY_SEPARATOR##Page1", - "Update_ProfilePicture##ENTITY_SEPARATOR##Page1", - "Remove_ProfilePicture##ENTITY_SEPARATOR##Page1", - "Set_Settings##ENTITY_SEPARATOR##Page1", - "Find_Webhook##ENTITY_SEPARATOR##Page1", - "Set_Webhook##ENTITY_SEPARATOR##Page1", - "Logout##ENTITY_SEPARATOR##Page1" - ], - "pageList": ["Page1"], - "actionCollectionList": ["Scripts##ENTITY_SEPARATOR##Page1"] - }, - "editModeTheme": { - "name": "Default", - "displayName": "Modern", - "config": { - "colors": { "primaryColor": "#553DE9", "backgroundColor": "#F8FAFC" }, - "borderRadius": { - "appBorderRadius": { "none": "0px", "M": "0.375rem", "L": "1.5rem" } - }, - "boxShadow": { - "appBoxShadow": { - "none": "none", - "S": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", - "M": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", - "L": "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" - } - }, - "fontFamily": { - "appFont": [ - "System Default", - "Nunito Sans", - "Poppins", - "Inter", - "Montserrat", - "Noto Sans", - "Open Sans", - "Roboto", - "Rubik", - "Ubuntu" - ] - } - }, - "properties": { - "colors": { "primaryColor": "#16a34a", "backgroundColor": "#F8FAFC" }, - "borderRadius": { "appBorderRadius": "0.375rem" }, - "boxShadow": { - "appBoxShadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" - }, - "fontFamily": { "appFont": "Nunito Sans" } - }, - "stylesheet": { - "AUDIO_RECORDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "BUTTON_GROUP_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "childStylesheet": { - "button": { "buttonColor": "{{appsmith.theme.colors.primaryColor}}" } - } - }, - "CAMERA_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "CHART_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" - }, - "CHECKBOX_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CHECKBOX_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CONTAINER_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "CIRCULAR_PROGRESS_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATE_PICKER_WIDGET2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "FILE_PICKER_WIDGET_V2": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "FORM_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "FORM_BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "ICON_BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "IFRAME_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "IMAGE_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "INPUT_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "JSON_FORM_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - } - }, - "LIST_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "MAP_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "MAP_CHART_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" - }, - "MENU_BUTTON_WIDGET": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MODAL_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_TREE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DROP_DOWN_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PROGRESSBAR_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "PROGRESS_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CODE_SCANNER_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RATE_WIDGET": { - "activeColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "RADIO_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "RICH_TEXT_EDITOR_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "STATBOX_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "SWITCH_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SWITCH_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "SELECT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "TABLE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - } - }, - "TABLE_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "editActions": { - "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - } - } - }, - "TABS_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "TEXT_WIDGET": { - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "VIDEO_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "SINGLE_SELECT_TREE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "CATEGORY_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "NUMBER_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "RANGE_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - } - }, - "isSystemTheme": false, - "deleted": false - }, - "publishedTheme": { - "name": "Default", - "displayName": "Modern", - "config": { - "colors": { "primaryColor": "#553DE9", "backgroundColor": "#F8FAFC" }, - "borderRadius": { - "appBorderRadius": { "none": "0px", "M": "0.375rem", "L": "1.5rem" } - }, - "boxShadow": { - "appBoxShadow": { - "none": "none", - "S": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)", - "M": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", - "L": "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)" - } - }, - "fontFamily": { - "appFont": [ - "System Default", - "Nunito Sans", - "Poppins", - "Inter", - "Montserrat", - "Noto Sans", - "Open Sans", - "Roboto", - "Rubik", - "Ubuntu" - ] - } - }, - "properties": { - "colors": { "primaryColor": "#16a34a", "backgroundColor": "#F8FAFC" }, - "borderRadius": { "appBorderRadius": "0.375rem" }, - "boxShadow": { - "appBoxShadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)" - }, - "fontFamily": { "appFont": "Nunito Sans" } - }, - "stylesheet": { - "AUDIO_RECORDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "BUTTON_GROUP_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "childStylesheet": { - "button": { "buttonColor": "{{appsmith.theme.colors.primaryColor}}" } - } - }, - "CAMERA_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "CHART_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" - }, - "CHECKBOX_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CHECKBOX_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CONTAINER_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "CIRCULAR_PROGRESS_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATE_PICKER_WIDGET2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "FILE_PICKER_WIDGET_V2": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "FORM_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "FORM_BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "ICON_BUTTON_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "IFRAME_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "IMAGE_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "INPUT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "INPUT_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "JSON_FORM_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "submitButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "resetButtonStyles": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "childStylesheet": { - "ARRAY": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "OBJECT": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none", - "cellBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "cellBoxShadow": "none" - }, - "CHECKBOX": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CURRENCY_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DATEPICKER": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "EMAIL_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTISELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTILINE_TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PASSWORD_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PHONE_NUMBER_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RADIO_GROUP": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SELECT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "SWITCH": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "TEXT_INPUT": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - } - }, - "LIST_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "MAP_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "MAP_CHART_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}" - }, - "MENU_BUTTON_WIDGET": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MODAL_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_TREE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "MULTI_SELECT_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "DROP_DOWN_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "PROGRESSBAR_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "PROGRESS_WIDGET": { - "fillColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "CODE_SCANNER_WIDGET": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "RATE_WIDGET": { - "activeColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "RADIO_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "RICH_TEXT_EDITOR_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "STATBOX_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "SWITCH_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "boxShadow": "none" - }, - "SWITCH_GROUP_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "SELECT_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "TABLE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - } - } - }, - "TABLE_WIDGET_V2": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", - "childStylesheet": { - "button": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "menuButton": { - "menuColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "iconButton": { - "buttonColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "editActions": { - "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - } - } - }, - "TABS_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "TEXT_WIDGET": { - "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", - "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" - }, - "VIDEO_WIDGET": { - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}" - }, - "SINGLE_SELECT_TREE_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "boxShadow": "none" - }, - "CATEGORY_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "NUMBER_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - }, - "RANGE_SLIDER_WIDGET": { - "accentColor": "{{appsmith.theme.colors.primaryColor}}" - } - }, - "isSystemTheme": false, - "deleted": false - } -} +{"clientSchemaVersion":1.0,"serverSchemaVersion":6.0,"exportedApplication":{"name":"EvolutionAPI Public","isPublic":true,"pages":[{"id":"Home","isDefault":true}],"publishedPages":[{"id":"Home","isDefault":true}],"viewMode":false,"appIsExample":false,"unreadCommentThreads":0.0,"color":"#F5D1D1","icon":"bar-graph","slug":"evolutionapi-public","unpublishedAppLayout":{"type":"DESKTOP"},"publishedAppLayout":{"type":"DESKTOP"},"unpublishedCustomJSLibs":[],"publishedCustomJSLibs":[],"evaluationVersion":2.0,"applicationVersion":2.0,"collapseInvisibleWidgets":true,"isManualUpdate":false,"deleted":false},"datasourceList":[],"customJSLibList":[],"pageList":[{"unpublishedPage":{"name":"Home","slug":"home","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":80.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":97.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"Actions","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Actions","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run();\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":2.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":149.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1490.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1490.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":3.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"}],"displayName":"JSON Form","bottomRow":147.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1490.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":42.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"4","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"publishedPage":{"name":"Home","slug":"home","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":80.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":97.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"Actions","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Actions","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run();\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":2.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":149.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1490.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1490.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":3.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"}],"displayName":"JSON Form","bottomRow":147.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1490.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":42.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"4","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56"}],"actionList":[{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_fetch_Instances","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788"},{"pluginType":"JS","pluginId":"js-plugin","unpublishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Scripts.verifyConfig","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Connect","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"publishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"id":"Home_Restart","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"publishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"id":"Home_Logout","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"publishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"id":"Home_Delete","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"publishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"id":"Home_Create_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"publishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"id":"Home_Find_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"publishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"id":"Home_Find_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"publishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"id":"Home_Find_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"publishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"id":"Home_Set_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"publishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"id":"Home_Set_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormChatwoot.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormChatwoot.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"publishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormChatwoot.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormChatwoot.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"id":"Home_Set_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"publishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"id":"Home_Fetch_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"publishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"id":"Home_Update_ProfileName","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"publishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"id":"Home_Update_ProfileStatus","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"publishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"id":"Home_Update_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"publishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"id":"Home_Remove_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"publishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"id":"Home_Fetch_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"publishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"id":"Home_Update_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64"}],"actionCollectionList":[{"unpublishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"publishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"id":"Home_Scripts","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e"}],"updatedResources":{"customJSLibList":[],"actionList":["Delete##ENTITY_SEPARATOR##Home","Scripts.verifyConfig##ENTITY_SEPARATOR##Home","Find_Chatwoot##ENTITY_SEPARATOR##Home","Logout##ENTITY_SEPARATOR##Home","Connect##ENTITY_SEPARATOR##Home","Fetch_Instance##ENTITY_SEPARATOR##Home","Set_Chatwoot##ENTITY_SEPARATOR##Home","Update_ProfileName##ENTITY_SEPARATOR##Home","Remove_ProfilePicture##ENTITY_SEPARATOR##Home","Create_Instance##ENTITY_SEPARATOR##Home","Fetch_PrivacySettings##ENTITY_SEPARATOR##Home","Restart##ENTITY_SEPARATOR##Home","Update_ProfileStatus##ENTITY_SEPARATOR##Home","Find_Webhook##ENTITY_SEPARATOR##Home","Update_ProfilePicture##ENTITY_SEPARATOR##Home","Find_Settings##ENTITY_SEPARATOR##Home","fetch_Instances##ENTITY_SEPARATOR##Home","Set_Settings##ENTITY_SEPARATOR##Home","Set_Webhook##ENTITY_SEPARATOR##Home","Update_PrivacySettings##ENTITY_SEPARATOR##Home"],"pageList":["Home"],"actionCollectionList":["Scripts##ENTITY_SEPARATOR##Home"]},"editModeTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false},"publishedTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false}} \ No newline at end of file diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index f78f1c36..84cf18e8 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1022,7 +1022,7 @@ export class ChatwootService { if (senderName === null || senderName === undefined) { formatText = messageReceived; } else { - formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; + formatText = this.provider.sign_msg ? `*${senderName}:*\n${messageReceived}` : messageReceived; } for (const message of body.conversation.messages) { From 0dca009c01b46d9a796ec2719c23c226c7b9fee4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 13:42:37 -0300 Subject: [PATCH 104/177] fix: Adjustment in the saving of contacts, saving the information of the number and Jid --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 640d0f6d..f023e69b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Solved problem when disconnecting from the instance the instance was deleted * Encoded spaces in chatwoot webhook +* Adjustment in the saving of contacts, saving the information of the number and Jid ### Integrations diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 84cf18e8..b3117753 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -205,7 +205,14 @@ export class ChatwootService { this.logger.verbose('find contact in chatwoot and create if not exists'); const contact = (await this.findContact(instance, '123456')) || - ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); + ((await this.createContact( + instance, + '123456', + inboxId, + false, + 'EvolutionAPI', + 'https://evolution-api.com/files/evolution-api-favicon.png', + )) as any); if (!contact) { this.logger.warn('contact not found'); @@ -269,6 +276,7 @@ export class ChatwootService { isGroup: boolean, name?: string, avatar_url?: string, + jid?: string, ) { this.logger.verbose('create contact to instance: ' + instance.instanceName); @@ -286,6 +294,7 @@ export class ChatwootService { inbox_id: inboxId, name: name || phoneNumber, phone_number: `+${phoneNumber}`, + identifier: jid, avatar_url: avatar_url, }; } else { @@ -437,6 +446,7 @@ export class ChatwootService { false, body.pushName, picture_url.profilePictureUrl || null, + body.key.participant, ); } } @@ -452,6 +462,7 @@ export class ChatwootService { if (findContact) { contact = findContact; } else { + const jid = isGroup ? null : body.key.remoteJid; contact = await this.createContact( instance, chatId, @@ -459,6 +470,7 @@ export class ChatwootService { isGroup, nameContact, picture_url.profilePictureUrl || null, + jid, ); } } else { @@ -472,6 +484,7 @@ export class ChatwootService { contact = findContact; } } else { + const jid = isGroup ? null : body.key.remoteJid; contact = await this.createContact( instance, chatId, @@ -479,6 +492,7 @@ export class ChatwootService { isGroup, nameContact, picture_url.profilePictureUrl || null, + jid, ); } } From 2614088faecc1e40d9887ce3f88b1c85c3622d0b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 15:25:48 -0300 Subject: [PATCH 105/177] Revert "Update Dockerfile" --- Dockerfile | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 01f24799..0b3ac950 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,16 @@ FROM node:16.18-alpine -LABEL version="1.4.7" description="Api to control whatsapp features through http requests." +LABEL version="1.1.3" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" RUN apk update && apk upgrade && \ - apk add --no-cache git tzdata ffmpeg wget curl + apk add --no-cache git WORKDIR /evolution COPY ./package.json . -ENV TZ=America/Sao_Paulo ENV DOCKER_ENV=true ENV SERVER_URL=http://localhost:8080 @@ -41,17 +40,17 @@ ENV DATABASE_ENABLED=false ENV DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true ENV DATABASE_CONNECTION_DB_PREFIX_NAME=evolution -ENV DATABASE_SAVE_DATA_INSTANCE=true -ENV DATABASE_SAVE_DATA_NEW_MESSAGE=true -ENV DATABASE_SAVE_MESSAGE_UPDATE=true -ENV DATABASE_SAVE_DATA_CONTACTS=true -ENV DATABASE_SAVE_DATA_CHATS=true +ENV DATABASE_SAVE_DATA_INSTANCE=false +ENV DATABASE_SAVE_DATA_NEW_MESSAGE=false +ENV DATABASE_SAVE_MESSAGE_UPDATE=false +ENV DATABASE_SAVE_DATA_CONTACTS=false +ENV DATABASE_SAVE_DATA_CHATS=false ENV REDIS_ENABLED=false ENV REDIS_URI=redis://redis:6379 ENV REDIS_PREFIX_KEY=evolution -ENV WEBHOOK_GLOBAL_URL= +ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false @@ -92,13 +91,18 @@ ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true ENV AUTHENTICATION_JWT_EXPIRIN_IN=0 ENV AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`' +ENV AUTHENTICATION_INSTANCE_MODE=server + +ENV AUTHENTICATION_INSTANCE_NAME=evolution +ENV AUTHENTICATION_INSTANCE_WEBHOOK_URL= +ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 +ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 +ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL= + RUN npm install COPY . . RUN npm run build -HEALTHCHECK --interval=1m --retries=250 --start-period=2m \ - CMD curl --fail http://$SERVER_URL/ || exit 1 - CMD [ "node", "./dist/src/main.js" ] From 84366002db771b7db0ce931a7d0aa8a8febc6128 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 15:27:47 -0300 Subject: [PATCH 106/177] fix: Update Dockerfile --- Dockerfile | 10 +- .../_Evolution__Configurar_Admin.json | 30 +++-- .../_Evolution__Criador_de_Empresas.json | 38 ++++-- .../_Evolution__Criador_de_Inbox.json | 120 +++++++++--------- views/manager.hbs | 5 - 5 files changed, 113 insertions(+), 90 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b3ac950..55af604b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,17 @@ FROM node:16.18-alpine -LABEL version="1.1.3" description="Api to control whatsapp features through http requests." +LABEL version="1.5.0" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" RUN apk update && apk upgrade && \ - apk add --no-cache git + apk add --no-cache git tzdata ffmpeg wget curl WORKDIR /evolution COPY ./package.json . +ENV TZ=America/Sao_Paulo ENV DOCKER_ENV=true ENV SERVER_URL=http://localhost:8080 @@ -50,7 +51,7 @@ ENV REDIS_ENABLED=false ENV REDIS_URI=redis://redis:6379 ENV REDIS_PREFIX_KEY=evolution -ENV WEBHOOK_GLOBAL_URL= +ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false @@ -105,4 +106,7 @@ COPY . . RUN npm run build +HEALTHCHECK --interval=1m --retries=250 --start-period=2m \ + CMD curl --fail http://$SERVER_URL/ || exit 1 + CMD [ "node", "./dist/src/main.js" ] diff --git a/Extras/chatwoot/_Evolution__Configurar_Admin.json b/Extras/chatwoot/_Evolution__Configurar_Admin.json index 1399ff54..3b791be1 100644 --- a/Extras/chatwoot/_Evolution__Configurar_Admin.json +++ b/Extras/chatwoot/_Evolution__Configurar_Admin.json @@ -7,7 +7,7 @@ "string": [ { "name": "api_access_token", - "value": "CHATWOOT_USER_TOKEN" + "value": "CHATWOOT_ADMIN_USER_TOKEN" }, { "name": "chatwoot_url", @@ -16,6 +16,14 @@ { "name": "n8n_url", "value": "https://N8N_URL" + }, + { + "name": "organization", + "value": "ORGANIZATION_NAME" + }, + { + "name": "logo", + "value": "ORGANIZATION_LOGO" } ] }, @@ -26,7 +34,7 @@ "type": "n8n-nodes-base.set", "typeVersion": 2, "position": [ - 1840, + 1820, 880 ] }, @@ -45,7 +53,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"EvolutionAPI\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"https://evolution-api.com/files/evolution-api-favicon.png\"\n}", + "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"Bot {{ $('Info Base').item.json[\"organization\"] }}\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"{{ $('Info Base').item.json[\"logo\"] }}\"\n}", "options": {} }, "id": "61742c2d-d195-4a68-a2eb-a36839b6376a", @@ -53,7 +61,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2240, + 2220, 880 ] }, @@ -72,7 +80,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"StartEvolution\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", + "jsonBody": "={\n \"name\": \"Start {{ $('Info Base').item.json[\"organization\"] }}\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", "options": {} }, "id": "866ddf42-2d5f-4bf2-8552-2379a5cdc2a5", @@ -80,7 +88,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2040, + 2020, 880 ] }, @@ -118,7 +126,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2440, + 2420, 880 ] }, @@ -137,7 +145,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"Create Inbox EvolutionAPI\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\"api_access_token\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n \n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n\n\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\"api_access_token\"] }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n \n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n\n\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", "options": {} }, "id": "d89ed76c-a5e9-42e6-b55b-e779e9a33a53", @@ -145,14 +153,14 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2660, + 2620, 880 ] }, { "parameters": { "content": "## Workflow Para Configurar admin\n**Aqui você prepara o Chatwoot Principal com um usuário (Superadmin) que poderá criar empresas e caixas de entrada**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\n**Obs: A variável api_access_token é o token do usuário que irá poder criar as empresas**", - "width": 1129.7777777777778 + "width": 894.6435495898575 }, "id": "a4597492-843a-44c7-836a-f30c91d46a20", "name": "Sticky Note", @@ -224,7 +232,7 @@ }, "active": false, "settings": {}, - "versionId": "4f0e166f-00fb-4ce6-989e-03c036351e35", + "versionId": "5275c59f-9230-4149-9107-e87c86759427", "id": "HmHVbJIXCOd57rBU", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" diff --git a/Extras/chatwoot/_Evolution__Criador_de_Empresas.json b/Extras/chatwoot/_Evolution__Criador_de_Empresas.json index c35bdf3d..a6a740e4 100644 --- a/Extras/chatwoot/_Evolution__Criador_de_Empresas.json +++ b/Extras/chatwoot/_Evolution__Criador_de_Empresas.json @@ -128,16 +128,16 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2380, + 2360, 840 ] }, { "parameters": { - "fromEmail": "contato@agenciadgcode.com", + "fromEmail": "={{ $('Info Base').item.json[\"from_email\"] }}", "toEmail": "={{ $('LimpaDados').item.json.email }}", - "subject": "Bem vindo ao Chatwoot", - "text": "=Olá seja bem vindo:\n\nAbaixo segue seus dados de acesso iniciais:\n\nURL: {{ $('Info Base').item.json[\"chatwoot_url\"] }}\n\nLoging: {{ $('LimpaDados').item.json[\"email\"] }}\n\nSenha: {{ $('LimpaDados').item.json[\"password\"] }}", + "subject": "=Bem vindo à {{ $('Info Base').item.json[\"organization\"] }}", + "text": "=Olá seja bem vindo:\n\nAbaixo segue seus dados de acesso:\n\nURL: {{ $('Info Base').item.json[\"chatwoot_url\"] }}\n\nuser: {{ $('LimpaDados').item.json[\"email\"] }}\n\nSenha: {{ $('LimpaDados').item.json[\"password\"] }}", "options": {} }, "id": "2d0b3e35-6e51-4e9b-90b4-6382dc6fec88", @@ -145,7 +145,7 @@ "type": "n8n-nodes-base.emailSend", "typeVersion": 2, "position": [ - 3180, + 3160, 840 ], "credentials": { @@ -161,7 +161,7 @@ "string": [ { "name": "api_access_token", - "value": "TOKEN PLATAFORM" + "value": "CHATWOOT_PLATFORM_TOKEN" }, { "name": "chatwoot_url", @@ -171,6 +171,18 @@ "name": "n8n_url", "value": "https://N8N_URL" }, + { + "name": "organization", + "value": "ORGANIZATION_NAME" + }, + { + "name": "logo", + "value": "ORGANIZATION_LOGO" + }, + { + "name": "from_email", + "value": "FROM_EMAIL" + }, { "name": "name", "value": "={{ $json.name_company }}" @@ -249,7 +261,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"EvolutionAPI\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"https://evolution-api.com/files/evolution-api-favicon.png\"\n}", + "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"Bot {{ $('Info Base').item.json[\"organization\"] }}\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"{{ $('Info Base').item.json[\"logo\"] }}\"\n}", "options": {} }, "id": "974e672e-fa4a-44ab-b6df-7aacd2bdb329", @@ -257,7 +269,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2800, + 2760, 840 ] }, @@ -276,7 +288,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"Create Inbox EvolutionAPI\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", "options": {} }, "id": "fb5597d4-0af1-461b-912b-7671a88c8368", @@ -284,7 +296,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 3000, + 2960, 840 ] }, @@ -303,7 +315,7 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"StartEvolution\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", + "jsonBody": "={\n \"name\": \"Start {{ $('Info Base').item.json[\"organization\"] }}\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", "options": {} }, "id": "a09bc90a-d643-422c-90ae-f8baa41ee532", @@ -311,7 +323,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2600, + 2560, 840 ] }, @@ -435,7 +447,7 @@ }, "active": true, "settings": {}, - "versionId": "5638171c-d64e-404f-b0f1-c8fbe4ec6fb0", + "versionId": "98d3de5d-b1b2-4e13-b6e6-07fa827f54fd", "id": "mVLlfZvGjtR8SZLT", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" diff --git a/Extras/chatwoot/_Evolution__Criador_de_Inbox.json b/Extras/chatwoot/_Evolution__Criador_de_Inbox.json index bf593a8e..86ccc25a 100644 --- a/Extras/chatwoot/_Evolution__Criador_de_Inbox.json +++ b/Extras/chatwoot/_Evolution__Criador_de_Inbox.json @@ -126,7 +126,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 1600, + 1620, 300 ] }, @@ -153,39 +153,6 @@ 300 ] }, - { - "parameters": { - "operation": "limit" - }, - "id": "c498a51e-53c5-4f0e-9aaa-eb1ebc4fbcb5", - "name": "Recupera Primeira Inbox", - "type": "n8n-nodes-base.itemLists", - "typeVersion": 2.2, - "position": [ - 1180, - 300 - ] - }, - { - "parameters": { - "conditions": { - "string": [ - { - "value1": "={{ $json.payload[0].name }}", - "value2": "StartEvolution" - } - ] - } - }, - "id": "40f705df-b9ff-4645-94ec-e7a5a0ca4777", - "name": "é StartEvolution?", - "type": "n8n-nodes-base.if", - "typeVersion": 1, - "position": [ - 1380, - 300 - ] - }, { "parameters": { "content": "## Workflow Para Criar Inbox\n**Aqui você configura a comunicação entre o chatwoot e a Evolution API para criar novas instâncias a partir do chatwoot**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e Evolution API**", @@ -215,7 +182,11 @@ }, { "name": "global_api_key", - "value": "GLOBAL_API_KEY" + "value": "EVOLUTION_GLOBAL_API_KEY" + }, + { + "name": "organization", + "value": "={{ $json.query.organization }}" }, { "name": "instance_name", @@ -282,6 +253,39 @@ 540, 300 ] + }, + { + "parameters": { + "operation": "limit" + }, + "id": "9ed7331d-f2fd-4ee0-8730-2ae7f444aa1e", + "name": "Recupera Primeira Inbox", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 2.2, + "position": [ + 1200, + 300 + ] + }, + { + "parameters": { + "conditions": { + "string": [ + { + "value1": "={{ $json.payload[0].name }}", + "value2": "=Start {{ $('Info Base').item.json[\"organization\"] }}" + } + ] + } + }, + "id": "40f705df-b9ff-4645-94ec-e7a5a0ca4777", + "name": "é Start Inbox?", + "type": "n8n-nodes-base.if", + "typeVersion": 1, + "position": [ + 1400, + 300 + ] } ], "pinData": {}, @@ -308,28 +312,6 @@ ] ] }, - "Recupera Primeira Inbox": { - "main": [ - [ - { - "node": "é StartEvolution?", - "type": "main", - "index": 0 - } - ] - ] - }, - "é StartEvolution?": { - "main": [ - [ - { - "node": "Deleta Inbox Start", - "type": "main", - "index": 0 - } - ] - ] - }, "Cria Instancia": { "main": [ [ @@ -351,11 +333,33 @@ } ] ] + }, + "Recupera Primeira Inbox": { + "main": [ + [ + { + "node": "é Start Inbox?", + "type": "main", + "index": 0 + } + ] + ] + }, + "é Start Inbox?": { + "main": [ + [ + { + "node": "Deleta Inbox Start", + "type": "main", + "index": 0 + } + ] + ] } }, "active": true, "settings": {}, - "versionId": "ee6fcc3a-3815-4f9b-9a6b-e282c66fc37b", + "versionId": "6fcdaf0a-5bf9-4c3a-b518-364246bd92c2", "id": "ByW2ccjR4XPrOyio", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" diff --git a/views/manager.hbs b/views/manager.hbs index aac84bdf..5dc10da1 100644 --- a/views/manager.hbs +++ b/views/manager.hbs @@ -5,11 +5,6 @@ - - Instance Manager From 38f61cdf7597c169af274b8b5930f70230bba813 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 15:28:00 -0300 Subject: [PATCH 107/177] fix: Update Dockerfile --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f023e69b..b85c0250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Solved problem when disconnecting from the instance the instance was deleted * Encoded spaces in chatwoot webhook * Adjustment in the saving of contacts, saving the information of the number and Jid +* Update Dockerfile ### Integrations From aefe6a5943a846370af034ad8ba882640b062884 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 15:30:48 -0300 Subject: [PATCH 108/177] feat: Added Get Last Message and Archive for Chat --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b85c0250..82f4d639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * New instance manager in /manager route * Added extra files for chatwoot and appsmith +* Added Get Last Message and Archive for Chat ### Fixed From b88656829e4a577f09d79c8139c95be190ade848 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 15:51:05 -0300 Subject: [PATCH 109/177] feat: Added env var QRCODE_COLOR --- CHANGELOG.md | 1 + Docker/.env.example | 1 + Dockerfile | 1 + src/config/env.config.ts | 3 ++- src/dev-env.yml | 1 + src/whatsapp/services/whatsapp.service.ts | 4 +++- 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82f4d639..e246c383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * New instance manager in /manager route * Added extra files for chatwoot and appsmith * Added Get Last Message and Archive for Chat +* Added env var QRCODE_COLOR ### Fixed diff --git a/Docker/.env.example b/Docker/.env.example index f4e8291d..6c62b8bc 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -84,6 +84,7 @@ CONFIG_SESSION_PHONE_NAME=chrome # Set qrcode display limit QRCODE_LIMIT=30 +QRCODE_COLOR=#198754 # Defines an authentication type for the api # We recommend using the apikey because it will allow you to use a custom token, diff --git a/Dockerfile b/Dockerfile index 55af604b..24497be6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -83,6 +83,7 @@ ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI ENV CONFIG_SESSION_PHONE_NAME=chrome ENV QRCODE_LIMIT=30 +ENV QRCODE_COLOR=#198754 ENV AUTHENTICATION_TYPE=apikey diff --git a/src/config/env.config.ts b/src/config/env.config.ts index b90141ff..a7638435 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -105,7 +105,7 @@ export type GlobalWebhook = { export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; export type ConfigSessionPhone = { CLIENT: string; NAME: string }; -export type QrCode = { LIMIT: number }; +export type QrCode = { LIMIT: number; COLOR: string }; export type Production = boolean; export interface Env { @@ -245,6 +245,7 @@ export class ConfigService { }, QRCODE: { LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, + COLOR: process.env.QRCODE_COLOR || '#198754', }, AUTHENTICATION: { TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', diff --git a/src/dev-env.yml b/src/dev-env.yml index b45d3201..ed2df448 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -122,6 +122,7 @@ CONFIG_SESSION_PHONE: # Set qrcode display limit QRCODE: LIMIT: 30 + COLOR: '#198754' # Defines an authentication type for the api # We recommend using the apikey because it will allow you to use a custom token, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index fbe91f54..1116a835 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -597,11 +597,13 @@ export class WAStartupService { this.logger.verbose('Incrementing QR code count'); this.instance.qrcode.count++; + const color = this.configService.get('QRCODE').COLOR; + const optsQrcode: QRCodeToDataURLOptions = { margin: 3, scale: 4, errorCorrectionLevel: 'H', - color: { light: '#ffffff', dark: '#198754' }, + color: { light: '#ffffff', dark: color }, }; if (this.phoneNumber) { From 074a861fb42e8a55f21643a06eed7ccd0ebe1361 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 31 Jul 2023 16:02:40 -0300 Subject: [PATCH 110/177] fix: Update Dockerfile --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 24497be6..94f885a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -107,7 +107,4 @@ COPY . . RUN npm run build -HEALTHCHECK --interval=1m --retries=250 --start-period=2m \ - CMD curl --fail http://$SERVER_URL/ || exit 1 - CMD [ "node", "./dist/src/main.js" ] From ed5e66e4300b570f3bdaaf854cc9d057ecf9b663 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 1 Aug 2023 18:01:29 -0300 Subject: [PATCH 111/177] fix: Update view manager --- CHANGELOG.md | 1 + ...gurar_Admin.json => configurar_admin.json} | 50 ++-- ...Empresas.json => criador_de_empresas.json} | 72 +++--- ...or_de_Inbox.json => criador_de_inbox.json} | 226 ++++++++++++++---- src/whatsapp/services/chatwoot.service.ts | 6 +- views/manager.hbs | 2 +- 6 files changed, 250 insertions(+), 107 deletions(-) rename Extras/chatwoot/{_Evolution__Configurar_Admin.json => configurar_admin.json} (71%) rename Extras/chatwoot/{_Evolution__Criador_de_Empresas.json => criador_de_empresas.json} (84%) rename Extras/chatwoot/{_Evolution__Criador_de_Inbox.json => criador_de_inbox.json} (69%) diff --git a/CHANGELOG.md b/CHANGELOG.md index e246c383..2e5d940e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### Integrations - Chatwoot: v2.18.0 - v3.0.0 +- Manager Evolution API # 1.4.8 (2023-07-27 10:27) diff --git a/Extras/chatwoot/_Evolution__Configurar_Admin.json b/Extras/chatwoot/configurar_admin.json similarity index 71% rename from Extras/chatwoot/_Evolution__Configurar_Admin.json rename to Extras/chatwoot/configurar_admin.json index 3b791be1..823bae65 100644 --- a/Extras/chatwoot/_Evolution__Configurar_Admin.json +++ b/Extras/chatwoot/configurar_admin.json @@ -29,13 +29,13 @@ }, "options": {} }, - "id": "322486a5-e6a7-4af9-8a3f-0ebc444912f0", + "id": "7a89a538-2cae-4032-8896-09627c07bc68", "name": "Info Base", "type": "n8n-nodes-base.set", "typeVersion": 2, "position": [ - 1820, - 880 + 620, + 480 ] }, { @@ -56,13 +56,13 @@ "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"Bot {{ $('Info Base').item.json[\"organization\"] }}\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"{{ $('Info Base').item.json[\"logo\"] }}\"\n}", "options": {} }, - "id": "61742c2d-d195-4a68-a2eb-a36839b6376a", + "id": "12a39df3-6b95-4f83-a0bc-50b25adaca7f", "name": "Cria Contato Bot", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2220, - 880 + 1020, + 480 ] }, { @@ -83,24 +83,24 @@ "jsonBody": "={\n \"name\": \"Start {{ $('Info Base').item.json[\"organization\"] }}\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", "options": {} }, - "id": "866ddf42-2d5f-4bf2-8552-2379a5cdc2a5", + "id": "bed7c54d-e232-4fe4-9584-0515e9679868", "name": "Cria Inbox Start", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2020, - 880 + 820, + 480 ] }, { "parameters": {}, - "id": "f1c2478a-9a1d-4cd4-82de-2002281c020b", + "id": "36ada769-a757-4193-989b-0cc4ea504b80", "name": "When clicking \"Execute Workflow\"", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ - 1620, - 880 + 420, + 480 ] }, { @@ -118,16 +118,16 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"Create Company Chatwoot\",\n \"description\": \"Create Company Chatwoot\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"https://webhooks.n8n.evolution-api.com/webhook/criadorchatwoot\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"Tema Criador de Empresa:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "jsonBody": "={\n \"name\": \"Create Company Chatwoot\",\n \"description\": \"Create Company Chatwoot\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/criadorchatwoot\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"Tema Criador de Empresa:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", "options": {} }, - "id": "e776b87b-57a6-4782-9ad9-cd0000aab29c", + "id": "f5bbb285-71a8-4c58-a4d7-e56002d697f0", "name": "Cria Automação Empresas", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2420, - 880 + 1220, + 480 ] }, { @@ -145,16 +145,16 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\"api_access_token\"] }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n \n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n\n\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\"api_access_token\"] }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n \n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n\n\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", "options": {} }, - "id": "d89ed76c-a5e9-42e6-b55b-e779e9a33a53", + "id": "a36bebdc-a318-40a2-8532-c7f476f8adb7", "name": "Cria Automação Inboxes", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2620, - 880 + 1420, + 480 ] }, { @@ -162,13 +162,13 @@ "content": "## Workflow Para Configurar admin\n**Aqui você prepara o Chatwoot Principal com um usuário (Superadmin) que poderá criar empresas e caixas de entrada**\n**Instruções**\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\n**Obs: A variável api_access_token é o token do usuário que irá poder criar as empresas**", "width": 894.6435495898575 }, - "id": "a4597492-843a-44c7-836a-f30c91d46a20", + "id": "db66e867-e9f4-452d-b521-725eeac652c8", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - 1620, - 680 + 420, + 280 ] } ], @@ -232,8 +232,8 @@ }, "active": false, "settings": {}, - "versionId": "5275c59f-9230-4149-9107-e87c86759427", - "id": "HmHVbJIXCOd57rBU", + "versionId": "78f155dc-7809-4bfc-9282-63f49b07fc4d", + "id": "BSATyGpGWLR4ZwNm", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" }, diff --git a/Extras/chatwoot/_Evolution__Criador_de_Empresas.json b/Extras/chatwoot/criador_de_empresas.json similarity index 84% rename from Extras/chatwoot/_Evolution__Criador_de_Empresas.json rename to Extras/chatwoot/criador_de_empresas.json index a6a740e4..aa97a6bd 100644 --- a/Extras/chatwoot/_Evolution__Criador_de_Empresas.json +++ b/Extras/chatwoot/criador_de_empresas.json @@ -7,13 +7,13 @@ "path": "criadorchatwoot", "options": {} }, - "id": "1bbcdc39-46af-4476-a381-981a96be3726", + "id": "5a47c10a-e43c-4fa5-baad-4b6cc511bfcd", "name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1, "position": [ - 1360, - 840 + 1420, + 860 ], "webhookId": "6fe428e3-1752-453c-9358-abf18b793387" }, @@ -45,13 +45,13 @@ }, "options": {} }, - "id": "ec9927e2-d075-4f3f-8655-d1269d25bac2", + "id": "8295c119-3a96-424e-9386-43d75f6816f5", "name": "Cria Conta", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 1960, - 840 + 2020, + 860 ] }, { @@ -86,13 +86,13 @@ }, "options": {} }, - "id": "1ce013fd-0445-488c-b73f-b86597a5b556", + "id": "4fe5007a-3a6b-490a-a446-e45cc168189f", "name": "Cria Usuario", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2160, - 840 + 2220, + 860 ] }, { @@ -123,13 +123,13 @@ }, "options": {} }, - "id": "a9156473-1916-446b-9e50-e906794c7c5b", + "id": "848c55e2-5678-4291-9602-c94d994da95b", "name": "Add Usuario a Conta", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2360, - 840 + 2420, + 860 ] }, { @@ -140,13 +140,13 @@ "text": "=Olá seja bem vindo:\n\nAbaixo segue seus dados de acesso:\n\nURL: {{ $('Info Base').item.json[\"chatwoot_url\"] }}\n\nuser: {{ $('LimpaDados').item.json[\"email\"] }}\n\nSenha: {{ $('LimpaDados').item.json[\"password\"] }}", "options": {} }, - "id": "2d0b3e35-6e51-4e9b-90b4-6382dc6fec88", + "id": "27f3b24f-1cf2-4d0d-a354-ecba066059f6", "name": "Send Email", "type": "n8n-nodes-base.emailSend", "typeVersion": 2, "position": [ - 3160, - 840 + 3220, + 860 ], "credentials": { "smtp": { @@ -203,13 +203,13 @@ }, "options": {} }, - "id": "1efc0806-2fe7-4670-9a0c-ab71592d0bbb", + "id": "38b4069d-e51e-4db7-933f-941b1be6d124", "name": "Info Base", "type": "n8n-nodes-base.set", "typeVersion": 2, "position": [ - 1760, - 840 + 1820, + 860 ] }, { @@ -237,13 +237,13 @@ }, "options": {} }, - "id": "602accf3-f01a-46ac-a22f-37c964c0ec76", + "id": "28e29e73-aadc-49ca-bd6d-b57ee0160a21", "name": "LimpaDados", "type": "n8n-nodes-base.set", "typeVersion": 2, "position": [ - 1560, - 840 + 1620, + 860 ] }, { @@ -264,13 +264,13 @@ "jsonBody": "={\n \"inbox_id\": {{ $('Cria Inbox Start').item.json[\"id\"] }},\n \"name\": \"Bot {{ $('Info Base').item.json[\"organization\"] }}\",\n \"phone_number\": \"+123456\",\n \"avatar_url\": \"{{ $('Info Base').item.json[\"logo\"] }}\"\n}", "options": {} }, - "id": "974e672e-fa4a-44ab-b6df-7aacd2bdb329", + "id": "bb671443-bdb4-4f56-99af-f0baef246a3e", "name": "Cria Contato Bot", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2760, - 840 + 2820, + 860 ] }, { @@ -288,16 +288,16 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox EvolutionAPI\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", + "jsonBody": "={\n \"name\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"description\": \"Create Inbox {{ $('Info Base').item.json[\"organization\"] }}\",\n \"event_name\": \"message_created\",\n \"active\": true,\n \"actions\": \n [\n {\n \"action_name\": \"send_webhook_event\",\n \"action_params\": [\"{{ $('Info Base').item.json[\"n8n_url\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}&organization={{ $('Info Base').item.json[\"organization\"] }}\"]\n }\n ],\n \"conditions\": \n [\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"start:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"query_operator\": \"or\",\n \"values\": [\"+123456\"]\n },\n {\n \"attribute_key\": \"content\",\n \"filter_operator\": \"contains\",\n \"query_operator\": \"and\",\n \"values\": [\"new_instance:\"]\n },\n {\n \"attribute_key\": \"phone_number\",\n \"filter_operator\": \"equal_to\",\n \"values\": [\"+123456\"]\n }\n ]\n}", "options": {} }, - "id": "fb5597d4-0af1-461b-912b-7671a88c8368", + "id": "e016a2af-b212-4e00-a3ff-8cd03530aa06", "name": "Cria Automação", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2960, - 840 + 3020, + 860 ] }, { @@ -318,13 +318,13 @@ "jsonBody": "={\n \"name\": \"Start {{ $('Info Base').item.json[\"organization\"] }}\",\n \"channel\": {\n \"type\": \"api\",\n \"website_url\": \"\"\n }\n}", "options": {} }, - "id": "a09bc90a-d643-422c-90ae-f8baa41ee532", + "id": "d3c42148-8920-4c98-a874-eb7113f2dd22", "name": "Cria Inbox Start", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ - 2560, - 840 + 2620, + 860 ] }, { @@ -333,13 +333,13 @@ "height": 304.02684563758396, "width": 1129.7777777777778 }, - "id": "f742f53d-58bc-4e26-bb82-1db352425eff", + "id": "d07516c0-4c8e-43ab-ba86-c8d063b09be5", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - 1360, - 500 + 1420, + 520 ] } ], @@ -447,8 +447,8 @@ }, "active": true, "settings": {}, - "versionId": "98d3de5d-b1b2-4e13-b6e6-07fa827f54fd", - "id": "mVLlfZvGjtR8SZLT", + "versionId": "3ffd6d3f-6966-4de4-af8f-1fda464bc1b8", + "id": "79R6qQDtfyCwgYjJ", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" }, diff --git a/Extras/chatwoot/_Evolution__Criador_de_Inbox.json b/Extras/chatwoot/criador_de_inbox.json similarity index 69% rename from Extras/chatwoot/_Evolution__Criador_de_Inbox.json rename to Extras/chatwoot/criador_de_inbox.json index 86ccc25a..ddf32ace 100644 --- a/Extras/chatwoot/_Evolution__Criador_de_Inbox.json +++ b/Extras/chatwoot/criador_de_inbox.json @@ -106,30 +106,6 @@ 300 ] }, - { - "parameters": { - "method": "DELETE", - "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.payload[0].id }}", - "sendHeaders": true, - "headerParameters": { - "parameters": [ - { - "name": "api_access_token", - "value": "={{ $('Info Base').item.json.chatwoot_token }}" - } - ] - }, - "options": {} - }, - "id": "e2e2cfe4-0afc-47f2-9176-5e14cb4c66c3", - "name": "Deleta Inbox Start", - "type": "n8n-nodes-base.httpRequest", - "typeVersion": 3, - "position": [ - 1620, - 300 - ] - }, { "parameters": { "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/", @@ -174,11 +150,11 @@ "string": [ { "name": "chatwoot_url", - "value": "https://CHATWOOT_URL" + "value": "CHATWOOT_URL" }, { "name": "evolution_url", - "value": "https://EVOLUTION_URL" + "value": "EVOLUTION_URL" }, { "name": "global_api_key", @@ -256,14 +232,35 @@ }, { "parameters": { - "operation": "limit" + "conditions": { + "string": [ + { + "value1": "={{ $json.name }}", + "value2": "=Start {{ $('Info Base').item.json[\"organization\"] }}" + } + ] + } }, - "id": "9ed7331d-f2fd-4ee0-8730-2ae7f444aa1e", - "name": "Recupera Primeira Inbox", - "type": "n8n-nodes-base.itemLists", - "typeVersion": 2.2, + "id": "a8d955e6-ac51-4316-aeec-09d4d65e943a", + "name": "é Start Inbox?", + "type": "n8n-nodes-base.if", + "typeVersion": 1, "position": [ - 1200, + 1660, + 200 + ] + }, + { + "parameters": { + "batchSize": 1, + "options": {} + }, + "id": "0d2d2194-aa4a-4241-9022-217d88bb581f", + "name": "Split In Batches", + "type": "n8n-nodes-base.splitInBatches", + "typeVersion": 2, + "position": [ + 1420, 300 ] }, @@ -272,18 +269,98 @@ "conditions": { "string": [ { - "value1": "={{ $json.payload[0].name }}", - "value2": "=Start {{ $('Info Base').item.json[\"organization\"] }}" + "value1": "={{ $json.name }}", + "value2": "={{ $('Webhook').item.json[\"body\"][\"messages\"][0][\"content\"].split(':')[1] }}" } ] } }, - "id": "40f705df-b9ff-4645-94ec-e7a5a0ca4777", - "name": "é Start Inbox?", + "id": "0bfbc2cb-eff5-423c-bd3a-b266aaf6a943", + "name": "é_pre-existente?", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [ - 1400, + 1900, + 340 + ] + }, + { + "parameters": { + "method": "PATCH", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.id }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json.chatwoot_token }}" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={\n\"channel\": {\n\"webhook_url\": \"{{ $('Info Base').item.json[\"evolution_url\"] }}/chatwoot/webhook/{{ encodeURIComponent($('Info Base').item.json[\"instance_name\"]) }}\"\n}\n}", + "options": {} + }, + "id": "fb589456-5566-4a45-96a7-75986d0aa1d5", + "name": "Update_webhook_url", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 2120, + 340 + ] + }, + { + "parameters": { + "method": "DELETE", + "url": "={{ $('Info Base').item.json[\"chatwoot_url\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\"chatwoot_account_id\"] }}/inboxes/{{ $json.id }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "api_access_token", + "value": "={{ $('Info Base').item.json.chatwoot_token }}" + } + ] + }, + "options": {} + }, + "id": "e6094941-410f-496c-9c9c-7b95fd9349af", + "name": "Deleta Inbox Start", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 3, + "position": [ + 1900, + 100 + ] + }, + { + "parameters": {}, + "id": "8cf9a78f-9e8a-4288-9d7b-801790af68d5", + "name": "No Operation, do nothing", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1660, + 400 + ] + }, + { + "parameters": { + "fieldToSplitOut": "payload", + "options": {} + }, + "id": "9468896a-5f86-4598-9d20-e8f495cae859", + "name": "Ajusta lista", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 2.2, + "position": [ + 1200, 300 ] } @@ -305,7 +382,7 @@ "main": [ [ { - "node": "Recupera Primeira Inbox", + "node": "Ajusta lista", "type": "main", "index": 0 } @@ -334,7 +411,25 @@ ] ] }, - "Recupera Primeira Inbox": { + "é Start Inbox?": { + "main": [ + [ + { + "node": "Deleta Inbox Start", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "é_pre-existente?", + "type": "main", + "index": 0 + } + ] + ] + }, + "Split In Batches": { "main": [ [ { @@ -342,14 +437,61 @@ "type": "main", "index": 0 } + ], + [ + { + "node": "No Operation, do nothing", + "type": "main", + "index": 0 + } ] ] }, - "é Start Inbox?": { + "é_pre-existente?": { "main": [ [ { - "node": "Deleta Inbox Start", + "node": "Update_webhook_url", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Split In Batches", + "type": "main", + "index": 0 + } + ] + ] + }, + "Update_webhook_url": { + "main": [ + [ + { + "node": "Split In Batches", + "type": "main", + "index": 0 + } + ] + ] + }, + "Deleta Inbox Start": { + "main": [ + [ + { + "node": "Split In Batches", + "type": "main", + "index": 0 + } + ] + ] + }, + "Ajusta lista": { + "main": [ + [ + { + "node": "Split In Batches", "type": "main", "index": 0 } @@ -359,7 +501,7 @@ }, "active": true, "settings": {}, - "versionId": "6fcdaf0a-5bf9-4c3a-b518-364246bd92c2", + "versionId": "ab910349-b559-4738-9ac6-de6b06d6bbce", "id": "ByW2ccjR4XPrOyio", "meta": { "instanceId": "4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906" diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index b3117753..4dc9215c 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -244,10 +244,10 @@ export class ChatwootService { this.logger.verbose('create message for init instance in chatwoot'); - let contentMsg = '/init'; + let contentMsg = 'init'; if (number) { - contentMsg = `/init:${number}`; + contentMsg = `init:${number}`; } const message = await client.messages.create({ @@ -1459,7 +1459,7 @@ export class ChatwootService { this.logger.verbose('event qrcode.updated'); if (body.statusCode === 500) { this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the 'init' message again.`; this.logger.verbose('send message to chatwoot'); return await this.createBotMessage(instance, erroQRcode, 'incoming'); diff --git a/views/manager.hbs b/views/manager.hbs index 5dc10da1..4fa5f4e4 100644 --- a/views/manager.hbs +++ b/views/manager.hbs @@ -5,7 +5,7 @@ - + Instance Manager From 79864e97d61a1f35e0ac73776b4cbc7ab3573939 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 13:08:30 -0300 Subject: [PATCH 112/177] feat: Added websocket with lib socket.io --- CHANGELOG.md | 1 + package.json | 1 + src/{db => libs}/db.connect.ts | 0 src/{db => libs}/redis.client.ts | 0 src/libs/socket.ts | 40 +++++++++++++++++++ src/main.ts | 3 ++ src/utils/use-multi-file-auth-state-db.ts | 2 +- .../use-multi-file-auth-state-redis-db.ts | 2 +- .../controllers/instance.controller.ts | 2 +- src/whatsapp/guards/instance.guard.ts | 2 +- src/whatsapp/models/auth.model.ts | 2 +- src/whatsapp/models/chat.model.ts | 2 +- src/whatsapp/models/chatwoot.model.ts | 2 +- src/whatsapp/models/contact.model.ts | 2 +- src/whatsapp/models/message.model.ts | 2 +- src/whatsapp/models/settings.model.ts | 2 +- src/whatsapp/models/webhook.model.ts | 2 +- src/whatsapp/routers/instance.router.ts | 2 +- src/whatsapp/services/monitor.service.ts | 4 +- src/whatsapp/services/whatsapp.service.ts | 12 +++++- src/whatsapp/whatsapp.module.ts | 4 +- views/manager.hbs | 2 +- 22 files changed, 72 insertions(+), 19 deletions(-) rename src/{db => libs}/db.connect.ts (100%) rename src/{db => libs}/redis.client.ts (100%) create mode 100644 src/libs/socket.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5d940e..cbb4f5e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Added extra files for chatwoot and appsmith * Added Get Last Message and Archive for Chat * Added env var QRCODE_COLOR +* Added websocket with lib socket.io ### Fixed diff --git a/package.json b/package.json index 4d6b2389..b9386ca6 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "qrcode-terminal": "^0.12.0", "redis": "^4.6.5", "sharp": "^0.30.7", + "socket.io": "^4.7.1", "uuid": "^9.0.0" }, "devDependencies": { diff --git a/src/db/db.connect.ts b/src/libs/db.connect.ts similarity index 100% rename from src/db/db.connect.ts rename to src/libs/db.connect.ts diff --git a/src/db/redis.client.ts b/src/libs/redis.client.ts similarity index 100% rename from src/db/redis.client.ts rename to src/libs/redis.client.ts diff --git a/src/libs/socket.ts b/src/libs/socket.ts new file mode 100644 index 00000000..4be23d01 --- /dev/null +++ b/src/libs/socket.ts @@ -0,0 +1,40 @@ +import { Server } from 'http'; +import { Server as SocketIO } from 'socket.io'; + +import { configService, Cors } from '../config/env.config'; +import { Logger } from '../config/logger.config'; + +const logger = new Logger('Socket'); + +let io: SocketIO; + +const cors = configService.get('CORS').ORIGIN; + +export const initIO = (httpServer: Server) => { + logger.verbose('Initializing Socket.io'); + io = new SocketIO(httpServer, { + cors: { + origin: cors, + }, + }); + + io.on('connection', (socket) => { + logger.verbose('Client connected'); + socket.on('disconnect', () => { + logger.verbose('Client disconnected'); + }); + }); + + return io; +}; + +export const getIO = (): SocketIO => { + logger.verbose('Getting Socket.io'); + + if (!io) { + logger.error('Socket.io not initialized'); + throw new Error('Socket.io not initialized'); + } + + return io; +}; diff --git a/src/main.ts b/src/main.ts index 1077d64d..298f49f2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,6 +9,7 @@ import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; +import { initIO } from './libs/socket'; import { ServerUP } from './utils/server-up'; import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; @@ -83,6 +84,8 @@ function bootstrap() { initWA(); + initIO(server); + onUnexpectedError(); } diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index 8b0d76e4..a021372a 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -9,7 +9,7 @@ import { import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; -import { dbserver } from '../db/db.connect'; +import { dbserver } from '../libs/db.connect'; export async function useMultiFileAuthStateDb( coll: string, diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index 57439ced..8e685b54 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -7,7 +7,7 @@ import { } from '@whiskeysockets/baileys'; import { Logger } from '../config/logger.config'; -import { RedisCache } from '../db/redis.client'; +import { RedisCache } from '../libs/redis.client'; export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{ state: AuthenticationState; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 04f45a4a..e2b81695 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -4,8 +4,8 @@ import EventEmitter2 from 'eventemitter2'; import { ConfigService, HttpServer } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; -import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; +import { RedisCache } from '../../libs/redis.client'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 69d20414..144f4d40 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -4,8 +4,8 @@ import { join } from 'path'; import { configService, Database, Redis } from '../../config/env.config'; import { INSTANCE_DIR } from '../../config/path.config'; -import { dbserver } from '../../db/db.connect'; import { BadRequestException, ForbiddenException, NotFoundException } from '../../exceptions'; +import { dbserver } from '../../libs/db.connect'; import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index 5c5b6a41..0f7d5ec3 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class AuthRaw { _id?: string; diff --git a/src/whatsapp/models/chat.model.ts b/src/whatsapp/models/chat.model.ts index 20153603..053d100e 100644 --- a/src/whatsapp/models/chat.model.ts +++ b/src/whatsapp/models/chat.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class ChatRaw { _id?: string; diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index d72f6e74..18d6b6f0 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class ChatwootRaw { _id?: string; diff --git a/src/whatsapp/models/contact.model.ts b/src/whatsapp/models/contact.model.ts index d9b51e1e..f5936b61 100644 --- a/src/whatsapp/models/contact.model.ts +++ b/src/whatsapp/models/contact.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class ContactRaw { _id?: string; diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index 764b04d9..a5790be7 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; import { wa } from '../types/wa.types'; class Key { diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index c928be42..48593fbe 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class SettingsRaw { _id?: string; diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index fa91326c..05a222e0 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -1,6 +1,6 @@ import { Schema } from 'mongoose'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; export class WebhookRaw { _id?: string; diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 20aa434c..96a1a5da 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -2,7 +2,7 @@ import { RequestHandler, Router } from 'express'; import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; -import { dbserver } from '../../db/db.connect'; +import { dbserver } from '../../libs/db.connect'; import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index f64c9a54..039a5f29 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -7,9 +7,9 @@ import { join } from 'path'; import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; -import { dbserver } from '../../db/db.connect'; -import { RedisCache } from '../../db/redis.client'; import { NotFoundException } from '../../exceptions'; +import { dbserver } from '../../libs/db.connect'; +import { RedisCache } from '../../libs/redis.client'; import { AuthModel, ChatwootModel, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1116a835..1f1301d0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -63,9 +63,10 @@ import { } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; -import { dbserver } from '../../db/db.connect'; -import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; +import { dbserver } from '../../libs/db.connect'; +import { RedisCache } from '../../libs/redis.client'; +import { getIO } from '../../libs/socket'; import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import { @@ -416,6 +417,7 @@ export class WAStartupService { const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + const io = getIO(); const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); @@ -553,6 +555,12 @@ export class WAStartupService { } } } + + io.emit(event, { + event, + instance: this.instance.name, + data, + }); } private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index b742afa9..00a10c2d 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -1,8 +1,8 @@ import { configService } from '../config/env.config'; import { eventEmitter } from '../config/event.config'; import { Logger } from '../config/logger.config'; -import { dbserver } from '../db/db.connect'; -import { RedisCache } from '../db/redis.client'; +import { dbserver } from '../libs/db.connect'; +import { RedisCache } from '../libs/redis.client'; import { ChatController } from './controllers/chat.controller'; import { ChatwootController } from './controllers/chatwoot.controller'; import { GroupController } from './controllers/group.controller'; diff --git a/views/manager.hbs b/views/manager.hbs index 4fa5f4e4..5414bdf1 100644 --- a/views/manager.hbs +++ b/views/manager.hbs @@ -11,7 +11,7 @@ - + From 341148612f3086cb6d4cb3675742c630135d5f7c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 13:21:15 -0300 Subject: [PATCH 113/177] feat: Added websocket with lib socket.io --- src/whatsapp/services/whatsapp.service.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1f1301d0..c6638281 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -417,11 +417,18 @@ export class WAStartupService { const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - const io = getIO(); const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + const io = getIO(); + + this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); + io.of(`/${this.instance.name}`).emit(event, { + event, + instance: this.instance.name, + data, + }); const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; @@ -555,12 +562,6 @@ export class WAStartupService { } } } - - io.emit(event, { - event, - instance: this.instance.name, - data, - }); } private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { From d6194316e1e05f409e4b31c5ec241a622836d54a Mon Sep 17 00:00:00 2001 From: Helio Elias Date: Wed, 2 Aug 2023 13:25:00 -0300 Subject: [PATCH 114/177] Fix Dockers --- package.json | 2 ++ src/install-evolution-api-ws.ts | 15 +++++++++++++++ src/uninstall-evolution-api-ws.ts | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 src/install-evolution-api-ws.ts create mode 100644 src/uninstall-evolution-api-ws.ts diff --git a/package.json b/package.json index 5c182838..09df55a4 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "mongoose": "^6.10.5", "node-cache": "^5.1.2", "node-mime-types": "^1.1.0", + "node-windows": "^1.0.0-beta.8", "pino": "^8.11.0", "proxy-agent": "^6.2.1", "qrcode": "^1.5.1", @@ -81,6 +82,7 @@ "@types/js-yaml": "^4.0.5", "@types/jsonwebtoken": "^8.5.9", "@types/node": "^18.15.11", + "@types/node-windows": "^0.1.2", "@types/qrcode": "^1.5.0", "@types/qrcode-terminal": "^0.12.0", "@types/uuid": "^8.3.4", diff --git a/src/install-evolution-api-ws.ts b/src/install-evolution-api-ws.ts new file mode 100644 index 00000000..1faadbf9 --- /dev/null +++ b/src/install-evolution-api-ws.ts @@ -0,0 +1,15 @@ +import nodeWindows from 'node-windows'; +import path from 'path'; + +const svc = new nodeWindows.Service({ + name: 'EvolutionAPIServer', + description: + 'WhatsApp-Api-NodeJs - This project is based on the CodeChat. The original project is an implementation of Baileys', + script: path.join(__dirname, 'main.js'), +}); + +svc.on('install', () => { + svc.start(); +}); + +svc.install(); diff --git a/src/uninstall-evolution-api-ws.ts b/src/uninstall-evolution-api-ws.ts new file mode 100644 index 00000000..4311f503 --- /dev/null +++ b/src/uninstall-evolution-api-ws.ts @@ -0,0 +1,16 @@ +import nodeWindows from 'node-windows'; +import path from 'path'; + +const svc = new nodeWindows.Service({ + name: 'EvolutionAPIServer', + description: + 'WhatsApp-Api-NodeJs - This project is based on the CodeChat. The original project is an implementation of Baileys', + script: path.join(__dirname, 'main.js'), +}); + +svc.on('uninstall', () => { + console.log('Uninstall complete.'); + console.log('The service exists: ', svc.exists); +}); + +svc.uninstall(); From b3b4ee7a288dc9d64b9d61f62620f3eb72366dc4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 14:48:02 -0300 Subject: [PATCH 115/177] fix: If you pass empty events in create instance and set webhook it is understood as all --- CHANGELOG.md | 1 + .../controllers/instance.controller.ts | 30 ++++++++++++++++++- .../controllers/webhook.controller.ts | 27 +++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbb4f5e7..b5d9ac9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Encoded spaces in chatwoot webhook * Adjustment in the saving of contacts, saving the information of the number and Jid * Update Dockerfile +* If you pass empty events in create instance and set webhook it is understood as all ### Integrations diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e2b81695..8acb2a80 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -86,10 +86,38 @@ export class InstanceController { this.logger.verbose('creating webhook'); try { + let newEvents: string[] = []; + if (events.length === 0) { + newEvents = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } else { + newEvents = events; + } this.webhookService.create(instance, { enabled: true, url: webhook, - events, + events: newEvents, webhook_by_events, }); diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index 281147db..b1d9b415 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -24,6 +24,33 @@ export class WebhookController { data.events = []; } + if (data.events.length === 0) { + logger.verbose('webhook events empty'); + data.events = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } + return this.webhookService.create(instance, data); } From 24c880343b2a981e40c242ffc8226a5da08cfdf6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 16:11:19 -0300 Subject: [PATCH 116/177] feat: Added websocket with lib socket.io --- src/validate/validate.schema.ts | 44 ++++++++++- .../controllers/instance.controller.ts | 76 +++++++++++++++++-- .../controllers/webhook.controller.ts | 8 +- .../controllers/websocket.controller.ts | 53 +++++++++++++ src/whatsapp/dto/instance.dto.ts | 2 + src/whatsapp/dto/websocket.dto.ts | 4 + src/whatsapp/models/index.ts | 1 + src/whatsapp/models/websocket.model.ts | 18 +++++ src/whatsapp/repository/repository.manager.ts | 7 ++ .../repository/websocket.repository.ts | 62 +++++++++++++++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/routers/websocket.router.ts | 52 +++++++++++++ src/whatsapp/services/websocket.service.ts | 33 ++++++++ src/whatsapp/services/whatsapp.service.ts | 61 ++++++++++++--- src/whatsapp/types/wa.types.ts | 5 ++ src/whatsapp/whatsapp.module.ts | 11 +++ 16 files changed, 416 insertions(+), 25 deletions(-) create mode 100644 src/whatsapp/controllers/websocket.controller.ts create mode 100644 src/whatsapp/dto/websocket.dto.ts create mode 100644 src/whatsapp/models/websocket.model.ts create mode 100644 src/whatsapp/repository/websocket.repository.ts create mode 100644 src/whatsapp/routers/websocket.router.ts create mode 100644 src/whatsapp/services/websocket.service.ts diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index feb5da59..1dbdafd4 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -824,13 +824,11 @@ export const updateGroupDescriptionSchema: JSONSchema7 = { ...isNotEmpty('groupJid', 'description'), }; -// Webhook Schema export const webhookSchema: JSONSchema7 = { $id: v4(), type: 'object', properties: { url: { type: 'string' }, - enabled: { type: 'boolean', enum: [true, false] }, events: { type: 'array', minItems: 0, @@ -862,7 +860,7 @@ export const webhookSchema: JSONSchema7 = { }, }, }, - required: ['url', 'enabled'], + required: ['url'], ...isNotEmpty('url'), }; @@ -896,3 +894,43 @@ export const settingsSchema: JSONSchema7 = { required: ['reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'], ...isNotEmpty('reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'), }; + +export const websocketSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, + }, + }, + required: ['enabled'], + ...isNotEmpty('enabled'), +}; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 8acb2a80..098efbbb 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -13,6 +13,7 @@ import { ChatwootService } from '../services/chatwoot.service'; import { WAMonitoringService } from '../services/monitor.service'; import { SettingsService } from '../services/settings.service'; import { WebhookService } from '../services/webhook.service'; +import { WebsocketService } from '../services/websocket.service'; import { WAStartupService } from '../services/whatsapp.service'; import { wa } from '../types/wa.types'; @@ -26,6 +27,7 @@ export class InstanceController { private readonly webhookService: WebhookService, private readonly chatwootService: ChatwootService, private readonly settingsService: SettingsService, + private readonly websocketService: WebsocketService, private readonly cache: RedisCache, ) {} @@ -51,6 +53,8 @@ export class InstanceController { always_online, read_messages, read_status, + websocket_enabled, + websocket_events, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -77,7 +81,7 @@ export class InstanceController { this.logger.verbose('hash: ' + hash + ' generated'); - let getEvents: string[]; + let webhookEvents: string[]; if (webhook) { if (!isURL(webhook, { require_tld: false })) { @@ -121,7 +125,51 @@ export class InstanceController { webhook_by_events, }); - getEvents = (await this.webhookService.find(instance)).events; + webhookEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + let websocketEvents: string[]; + + if (websocket_enabled) { + this.logger.verbose('creating websocket'); + try { + let newEvents: string[] = []; + if (websocket_events.length === 0) { + newEvents = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } else { + newEvents = events; + } + this.websocketService.create(instance, { + enabled: true, + events: newEvents, + }); + + websocketEvents = (await this.websocketService.find(instance)).events; } catch (error) { this.logger.log(error); } @@ -157,9 +205,15 @@ export class InstanceController { status: 'created', }, hash, - webhook, - webhook_by_events, - events: getEvents, + webhook: { + webhook, + webhook_by_events, + events: webhookEvents, + }, + websocker: { + enabled: websocket_enabled, + events: websocketEvents, + }, settings, qrcode: getQrcode, }; @@ -230,9 +284,15 @@ export class InstanceController { status: 'created', }, hash, - webhook, - webhook_by_events, - events: getEvents, + webhook: { + webhook, + webhook_by_events, + events: webhookEvents, + }, + websocker: { + enabled: websocket_enabled, + events: websocketEvents, + }, settings, chatwoot: { enabled: true, diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index b1d9b415..5515b8cc 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -14,17 +14,17 @@ export class WebhookController { public async createWebhook(instance: InstanceDto, data: WebhookDto) { logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance'); - if (data.enabled && !isURL(data.url, { require_tld: false })) { + if (!isURL(data.url, { require_tld: false })) { throw new BadRequestException('Invalid "url" property'); } + data.enabled = data.enabled ?? true; + if (!data.enabled) { logger.verbose('webhook disabled'); data.url = ''; data.events = []; - } - - if (data.events.length === 0) { + } else if (data.events.length === 0) { logger.verbose('webhook events empty'); data.events = [ 'APPLICATION_STARTUP', diff --git a/src/whatsapp/controllers/websocket.controller.ts b/src/whatsapp/controllers/websocket.controller.ts new file mode 100644 index 00000000..fb6bea0f --- /dev/null +++ b/src/whatsapp/controllers/websocket.controller.ts @@ -0,0 +1,53 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { WebsocketDto } from '../dto/websocket.dto'; +import { WebsocketService } from '../services/websocket.service'; + +const logger = new Logger('WebsocketController'); + +export class WebsocketController { + constructor(private readonly websocketService: WebsocketService) {} + + public async createWebsocket(instance: InstanceDto, data: WebsocketDto) { + logger.verbose('requested createWebsocket from ' + instance.instanceName + ' instance'); + + if (!data.enabled) { + logger.verbose('websocket disabled'); + data.events = []; + } + + if (data.events.length === 0) { + logger.verbose('websocket events empty'); + data.events = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } + + return this.websocketService.create(instance, data); + } + + public async findWebsocket(instance: InstanceDto) { + logger.verbose('requested findWebsocket from ' + instance.instanceName + ' instance'); + return this.websocketService.find(instance); + } +} diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index c317060f..b729cff5 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -18,4 +18,6 @@ export class InstanceDto { chatwoot_sign_msg?: boolean; chatwoot_reopen_conversation?: boolean; chatwoot_conversation_pending?: boolean; + websocket_enabled?: boolean; + websocket_events?: string[]; } diff --git a/src/whatsapp/dto/websocket.dto.ts b/src/whatsapp/dto/websocket.dto.ts new file mode 100644 index 00000000..27f6d785 --- /dev/null +++ b/src/whatsapp/dto/websocket.dto.ts @@ -0,0 +1,4 @@ +export class WebsocketDto { + enabled: boolean; + events?: string[]; +} diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index ee472de6..3fc981e0 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -5,3 +5,4 @@ export * from './contact.model'; export * from './message.model'; export * from './settings.model'; export * from './webhook.model'; +export * from './websocket.model'; diff --git a/src/whatsapp/models/websocket.model.ts b/src/whatsapp/models/websocket.model.ts new file mode 100644 index 00000000..e96332b1 --- /dev/null +++ b/src/whatsapp/models/websocket.model.ts @@ -0,0 +1,18 @@ +import { Schema } from 'mongoose'; + +import { dbserver } from '../../libs/db.connect'; + +export class WebsocketRaw { + _id?: string; + enabled?: boolean; + events?: string[]; +} + +const websocketSchema = new Schema({ + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + events: { type: [String], required: true }, +}); + +export const WebsocketModel = dbserver?.model(WebsocketRaw.name, websocketSchema, 'websocket'); +export type IWebsocketModel = typeof WebsocketModel; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index e1292329..5724d216 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -12,6 +12,7 @@ import { MessageRepository } from './message.repository'; import { MessageUpRepository } from './messageUp.repository'; import { SettingsRepository } from './settings.repository'; import { WebhookRepository } from './webhook.repository'; +import { WebsocketRepository } from './websocket.repository'; export class RepositoryBroker { constructor( public readonly message: MessageRepository, @@ -21,6 +22,7 @@ export class RepositoryBroker { public readonly webhook: WebhookRepository, public readonly chatwoot: ChatwootRepository, public readonly settings: SettingsRepository, + public readonly websocket: WebsocketRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -51,6 +53,7 @@ export class RepositoryBroker { const webhookDir = join(storePath, 'webhook'); const chatwootDir = join(storePath, 'chatwoot'); const settingsDir = join(storePath, 'settings'); + const websocketDir = join(storePath, 'websocket'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -85,6 +88,10 @@ export class RepositoryBroker { this.logger.verbose('creating settings dir: ' + settingsDir); fs.mkdirSync(settingsDir, { recursive: true }); } + if (!fs.existsSync(websocketDir)) { + this.logger.verbose('creating websocket dir: ' + websocketDir); + fs.mkdirSync(websocketDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/repository/websocket.repository.ts b/src/whatsapp/repository/websocket.repository.ts new file mode 100644 index 00000000..19823194 --- /dev/null +++ b/src/whatsapp/repository/websocket.repository.ts @@ -0,0 +1,62 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IWebsocketModel, WebsocketRaw } from '../models'; + +export class WebsocketRepository extends Repository { + constructor(private readonly websocketModel: IWebsocketModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('WebsocketRepository'); + + public async create(data: WebsocketRaw, instance: string): Promise { + try { + this.logger.verbose('creating websocket'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving websocket to db'); + const insert = await this.websocketModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('websocket saved to db: ' + insert.modifiedCount + ' websocket'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving websocket to store'); + + this.writeStore({ + path: join(this.storePath, 'websocket'), + fileName: instance, + data, + }); + + this.logger.verbose('websocket saved to store in path: ' + join(this.storePath, 'websocket') + '/' + instance); + + this.logger.verbose('websocket created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding websocket'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding websocket in db'); + return await this.websocketModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding websocket in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'websocket', instance + '.json'), { + encoding: 'utf-8', + }), + ) as WebsocketRaw; + } catch (error) { + return {}; + } + } +} diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 3de9b71d..70daa292 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -12,6 +12,7 @@ import { MessageRouter } from './sendMessage.router'; import { SettingsRouter } from './settings.router'; import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; +import { WebsocketRouter } from './websocket.router'; enum HttpStatus { OK = 200, @@ -44,6 +45,7 @@ router .use('/group', new GroupRouter(...guards).router) .use('/webhook', new WebhookRouter(...guards).router) .use('/chatwoot', new ChatwootRouter(...guards).router) - .use('/settings', new SettingsRouter(...guards).router); + .use('/settings', new SettingsRouter(...guards).router) + .use('/websocket', new WebsocketRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/websocket.router.ts b/src/whatsapp/routers/websocket.router.ts new file mode 100644 index 00000000..f04cad0d --- /dev/null +++ b/src/whatsapp/routers/websocket.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; +import { instanceNameSchema, websocketSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { WebsocketDto } from '../dto/websocket.dto'; +import { websocketController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; + +const logger = new Logger('WebsocketRouter'); + +export class WebsocketRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setWebsocket'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: websocketSchema, + ClassRef: WebsocketDto, + execute: (instance, data) => websocketController.createWebsocket(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findWebsocket'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => websocketController.findWebsocket(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/services/websocket.service.ts b/src/whatsapp/services/websocket.service.ts new file mode 100644 index 00000000..20663bbf --- /dev/null +++ b/src/whatsapp/services/websocket.service.ts @@ -0,0 +1,33 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { WebsocketDto } from '../dto/websocket.dto'; +import { WebsocketRaw } from '../models'; +import { WAMonitoringService } from './monitor.service'; + +export class WebsocketService { + constructor(private readonly waMonitor: WAMonitoringService) {} + + private readonly logger = new Logger(WebsocketService.name); + + public create(instance: InstanceDto, data: WebsocketDto) { + this.logger.verbose('create websocket: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setWebsocket(data); + + return { websocket: { ...instance, websocket: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find websocket: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findWebsocket(); + + if (Object.keys(result).length === 0) { + throw new Error('Websocket not found'); + } + + return result; + } catch (error) { + return { enabled: false, events: [] }; + } + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c6638281..84d48c52 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -116,6 +116,7 @@ import { ChatwootRaw } from '../models/chatwoot.model'; import { ContactRaw } from '../models/contact.model'; import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; import { WebhookRaw } from '../models/webhook.model'; +import { WebsocketRaw } from '../models/websocket.model'; import { ContactQuery } from '../repository/contact.repository'; import { MessageQuery } from '../repository/message.repository'; import { MessageUpQuery } from '../repository/messageUp.repository'; @@ -142,6 +143,7 @@ export class WAStartupService { private readonly localWebhook: wa.LocalWebHook = {}; private readonly localChatwoot: wa.LocalChatwoot = {}; private readonly localSettings: wa.LocalSettings = {}; + private readonly localWebsocket: wa.LocalWebsocket = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -411,9 +413,44 @@ export class WAStartupService { return data; } + private async loadWebsocket() { + this.logger.verbose('Loading websocket'); + const data = await this.repository.websocket.find(this.instanceName); + + this.localWebsocket.enabled = data?.enabled; + this.logger.verbose(`Websocket enabled: ${this.localWebsocket.enabled}`); + + this.localWebsocket.events = data?.events; + this.logger.verbose(`Websocket events: ${this.localWebsocket.events}`); + + this.logger.verbose('Websocket loaded'); + } + + public async setWebsocket(data: WebsocketRaw) { + this.logger.verbose('Setting websocket'); + await this.repository.websocket.create(data, this.instanceName); + this.logger.verbose(`Websocket events: ${data.events}`); + Object.assign(this.localWebsocket, data); + this.logger.verbose('Websocket set'); + } + + public async findWebsocket() { + this.logger.verbose('Finding websocket'); + const data = await this.repository.websocket.find(this.instanceName); + + if (!data) { + this.logger.verbose('Websocket not found'); + throw new NotFoundException('Websocket not found'); + } + + this.logger.verbose(`Websocket events: ${data.events}`); + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; + const websocketLocal = this.localWebsocket.events; const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); @@ -421,14 +458,21 @@ export class WAStartupService { const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); const instanceApikey = tokenStore?.apikey || 'Apikey not found'; - const io = getIO(); - this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); - io.of(`/${this.instance.name}`).emit(event, { - event, - instance: this.instance.name, - data, - }); + if (this.localWebsocket.enabled) { + this.logger.verbose('Sending data to websocket on channel: ' + this.instance.name); + if (Array.isArray(websocketLocal) && websocketLocal.includes(we)) { + this.logger.verbose('Sending data to websocket on event: ' + event); + const io = getIO(); + + this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); + io.of(`/${this.instance.name}`).emit(event, { + event, + instance: this.instance.name, + data, + }); + } + } const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; @@ -568,7 +612,6 @@ export class WAStartupService { this.logger.verbose('Connection update'); if (qr) { this.logger.verbose('QR code found'); - console.log('this.instance.qrcode', this.instance.qrcode); if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { this.logger.verbose('QR code limit reached'); @@ -823,6 +866,7 @@ export class WAStartupService { this.loadWebhook(); this.loadChatwoot(); this.loadSettings(); + this.loadWebsocket(); this.instance.authState = await this.defineAuthState(); @@ -2380,7 +2424,6 @@ export class WAStartupService { if (!last_message || Object.keys(last_message).length === 0) { throw new NotFoundException('Last message not found'); } - console.log(last_message); await this.client.chatModify( { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d4769a49..da2918fb 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -70,6 +70,11 @@ export declare namespace wa { read_status?: boolean; }; + export type LocalWebsocket = { + enabled?: boolean; + events?: string[]; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 00a10c2d..8d2606f2 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -11,6 +11,7 @@ import { SendMessageController } from './controllers/sendMessage.controller'; import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; import { WebhookController } from './controllers/webhook.controller'; +import { WebsocketController } from './controllers/websocket.controller'; import { AuthModel, ChatModel, @@ -20,6 +21,7 @@ import { MessageUpModel, SettingsModel, WebhookModel, + WebsocketModel, } from './models'; import { AuthRepository } from './repository/auth.repository'; import { ChatRepository } from './repository/chat.repository'; @@ -30,11 +32,13 @@ import { MessageUpRepository } from './repository/messageUp.repository'; import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; import { WebhookRepository } from './repository/webhook.repository'; +import { WebsocketRepository } from './repository/websocket.repository'; import { AuthService } from './services/auth.service'; import { ChatwootService } from './services/chatwoot.service'; import { WAMonitoringService } from './services/monitor.service'; import { SettingsService } from './services/settings.service'; import { WebhookService } from './services/webhook.service'; +import { WebsocketService } from './services/websocket.service'; const logger = new Logger('WA MODULE'); @@ -43,6 +47,7 @@ const chatRepository = new ChatRepository(ChatModel, configService); const contactRepository = new ContactRepository(ContactModel, configService); const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); +const websocketRepository = new WebsocketRepository(WebsocketModel, configService); const chatwootRepository = new ChatwootRepository(ChatwootModel, configService); const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); @@ -55,6 +60,7 @@ export const repository = new RepositoryBroker( webhookRepository, chatwootRepository, settingsRepository, + websocketRepository, authRepository, configService, dbserver?.getClient(), @@ -70,6 +76,10 @@ const webhookService = new WebhookService(waMonitor); export const webhookController = new WebhookController(webhookService); +const websocketService = new WebsocketService(waMonitor); + +export const websocketController = new WebsocketController(websocketService); + const chatwootService = new ChatwootService(waMonitor, configService); export const chatwootController = new ChatwootController(chatwootService, configService); @@ -87,6 +97,7 @@ export const instanceController = new InstanceController( webhookService, chatwootService, settingsService, + websocketService, cache, ); export const viewsController = new ViewsController(waMonitor, configService); From e05c48979d59f7c1a012b08d19830bb50e462933 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 17:28:52 -0300 Subject: [PATCH 117/177] feat: Added rabbitmq to send events --- package.json | 1 + src/libs/amqp.server.ts | 37 ++++++++ src/libs/{socket.ts => socket.server.ts} | 0 src/main.ts | 5 +- src/validate/validate.schema.ts | 40 +++++++++ .../controllers/instance.controller.ts | 2 + .../controllers/rabbitmq.controller.ts | 53 ++++++++++++ src/whatsapp/dto/rabbitmq.dto.ts | 4 + src/whatsapp/models/index.ts | 1 + src/whatsapp/models/rabbitmq.model.ts | 18 ++++ .../repository/rabbitmq.repository.ts | 62 +++++++++++++ src/whatsapp/repository/repository.manager.ts | 7 ++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/routers/rabbitmq.router.ts | 52 +++++++++++ src/whatsapp/services/rabbitmq.service.ts | 33 +++++++ src/whatsapp/services/whatsapp.service.ts | 86 +++++++++++++++++-- src/whatsapp/types/wa.types.ts | 5 ++ src/whatsapp/whatsapp.module.ts | 11 +++ 18 files changed, 414 insertions(+), 7 deletions(-) create mode 100644 src/libs/amqp.server.ts rename src/libs/{socket.ts => socket.server.ts} (100%) create mode 100644 src/whatsapp/controllers/rabbitmq.controller.ts create mode 100644 src/whatsapp/dto/rabbitmq.dto.ts create mode 100644 src/whatsapp/models/rabbitmq.model.ts create mode 100644 src/whatsapp/repository/rabbitmq.repository.ts create mode 100644 src/whatsapp/routers/rabbitmq.router.ts create mode 100644 src/whatsapp/services/rabbitmq.service.ts diff --git a/package.json b/package.json index b9386ca6..bb469865 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", "@whiskeysockets/baileys": "github:EvolutionAPI/Baileys", + "amqplib": "^0.10.3", "axios": "^1.3.5", "class-validator": "^0.13.2", "compression": "^1.7.4", diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts new file mode 100644 index 00000000..55ec4193 --- /dev/null +++ b/src/libs/amqp.server.ts @@ -0,0 +1,37 @@ +import * as amqp from 'amqplib/callback_api'; + +import { Logger } from '../config/logger.config'; + +const logger = new Logger('AMQP'); + +let amqpChannel: amqp.Channel | null = null; + +export const initAMQP = () => { + return new Promise((resolve, reject) => { + amqp.connect('amqp://admin:admin@localhost:5672', (error, connection) => { + if (error) { + reject(error); + return; + } + + connection.createChannel((channelError, channel) => { + if (channelError) { + reject(channelError); + return; + } + + const exchangeName = 'evolution_exchange'; + + channel.assertExchange(exchangeName, 'topic', { durable: false }); + amqpChannel = channel; + + logger.log('Serviço do RabbitMQ inicializado com sucesso.'); + resolve(); + }); + }); + }); +}; + +export const getAMQP = (): amqp.Channel | null => { + return amqpChannel; +}; diff --git a/src/libs/socket.ts b/src/libs/socket.server.ts similarity index 100% rename from src/libs/socket.ts rename to src/libs/socket.server.ts diff --git a/src/main.ts b/src/main.ts index 298f49f2..ddc17cbc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,8 @@ import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; -import { initIO } from './libs/socket'; +import { initAMQP } from './libs/amqp.server'; +import { initIO } from './libs/socket.server'; import { ServerUP } from './utils/server-up'; import { HttpStatus, router } from './whatsapp/routers/index.router'; import { waMonitor } from './whatsapp/whatsapp.module'; @@ -86,6 +87,8 @@ function bootstrap() { initIO(server); + initAMQP(); + onUnexpectedError(); } diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 1dbdafd4..cd6a1b52 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -934,3 +934,43 @@ export const websocketSchema: JSONSchema7 = { required: ['enabled'], ...isNotEmpty('enabled'), }; + +export const rabbitmqSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + events: { + type: 'array', + minItems: 0, + items: { + type: 'string', + enum: [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ], + }, + }, + }, + required: ['enabled'], + ...isNotEmpty('enabled'), +}; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 098efbbb..ceb1d455 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -11,6 +11,7 @@ import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; import { ChatwootService } from '../services/chatwoot.service'; import { WAMonitoringService } from '../services/monitor.service'; +import { RabbitmqService } from '../services/rabbitmq.service'; import { SettingsService } from '../services/settings.service'; import { WebhookService } from '../services/webhook.service'; import { WebsocketService } from '../services/websocket.service'; @@ -28,6 +29,7 @@ export class InstanceController { private readonly chatwootService: ChatwootService, private readonly settingsService: SettingsService, private readonly websocketService: WebsocketService, + private readonly rebbitmqService: RabbitmqService, private readonly cache: RedisCache, ) {} diff --git a/src/whatsapp/controllers/rabbitmq.controller.ts b/src/whatsapp/controllers/rabbitmq.controller.ts new file mode 100644 index 00000000..4efd1c3f --- /dev/null +++ b/src/whatsapp/controllers/rabbitmq.controller.ts @@ -0,0 +1,53 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { RabbitmqDto } from '../dto/rabbitmq.dto'; +import { RabbitmqService } from '../services/rabbitmq.service'; + +const logger = new Logger('RabbitmqController'); + +export class RabbitmqController { + constructor(private readonly rabbitmqService: RabbitmqService) {} + + public async createRabbitmq(instance: InstanceDto, data: RabbitmqDto) { + logger.verbose('requested createRabbitmq from ' + instance.instanceName + ' instance'); + + if (!data.enabled) { + logger.verbose('rabbitmq disabled'); + data.events = []; + } + + if (data.events.length === 0) { + logger.verbose('rabbitmq events empty'); + data.events = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } + + return this.rabbitmqService.create(instance, data); + } + + public async findRabbitmq(instance: InstanceDto) { + logger.verbose('requested findRabbitmq from ' + instance.instanceName + ' instance'); + return this.rabbitmqService.find(instance); + } +} diff --git a/src/whatsapp/dto/rabbitmq.dto.ts b/src/whatsapp/dto/rabbitmq.dto.ts new file mode 100644 index 00000000..9bfd5b42 --- /dev/null +++ b/src/whatsapp/dto/rabbitmq.dto.ts @@ -0,0 +1,4 @@ +export class RabbitmqDto { + enabled: boolean; + events?: string[]; +} diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index 3fc981e0..7462af2a 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -3,6 +3,7 @@ export * from './chat.model'; export * from './chatwoot.model'; export * from './contact.model'; export * from './message.model'; +export * from './rabbitmq.model'; export * from './settings.model'; export * from './webhook.model'; export * from './websocket.model'; diff --git a/src/whatsapp/models/rabbitmq.model.ts b/src/whatsapp/models/rabbitmq.model.ts new file mode 100644 index 00000000..e89ee3b1 --- /dev/null +++ b/src/whatsapp/models/rabbitmq.model.ts @@ -0,0 +1,18 @@ +import { Schema } from 'mongoose'; + +import { dbserver } from '../../libs/db.connect'; + +export class RabbitmqRaw { + _id?: string; + enabled?: boolean; + events?: string[]; +} + +const rabbitmqSchema = new Schema({ + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + events: { type: [String], required: true }, +}); + +export const RabbitmqModel = dbserver?.model(RabbitmqRaw.name, rabbitmqSchema, 'rabbitmq'); +export type IRabbitmqModel = typeof RabbitmqModel; diff --git a/src/whatsapp/repository/rabbitmq.repository.ts b/src/whatsapp/repository/rabbitmq.repository.ts new file mode 100644 index 00000000..3dfb5ec2 --- /dev/null +++ b/src/whatsapp/repository/rabbitmq.repository.ts @@ -0,0 +1,62 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IRabbitmqModel, RabbitmqRaw } from '../models'; + +export class RabbitmqRepository extends Repository { + constructor(private readonly rabbitmqModel: IRabbitmqModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('RabbitmqRepository'); + + public async create(data: RabbitmqRaw, instance: string): Promise { + try { + this.logger.verbose('creating rabbitmq'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving rabbitmq to db'); + const insert = await this.rabbitmqModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('rabbitmq saved to db: ' + insert.modifiedCount + ' rabbitmq'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving rabbitmq to store'); + + this.writeStore({ + path: join(this.storePath, 'rabbitmq'), + fileName: instance, + data, + }); + + this.logger.verbose('rabbitmq saved to store in path: ' + join(this.storePath, 'rabbitmq') + '/' + instance); + + this.logger.verbose('rabbitmq created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding rabbitmq'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding rabbitmq in db'); + return await this.rabbitmqModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding rabbitmq in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'rabbitmq', instance + '.json'), { + encoding: 'utf-8', + }), + ) as RabbitmqRaw; + } catch (error) { + return {}; + } + } +} diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 5724d216..25cc83f0 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -10,6 +10,7 @@ import { ChatwootRepository } from './chatwoot.repository'; import { ContactRepository } from './contact.repository'; import { MessageRepository } from './message.repository'; import { MessageUpRepository } from './messageUp.repository'; +import { RabbitmqRepository } from './rabbitmq.repository'; import { SettingsRepository } from './settings.repository'; import { WebhookRepository } from './webhook.repository'; import { WebsocketRepository } from './websocket.repository'; @@ -23,6 +24,7 @@ export class RepositoryBroker { public readonly chatwoot: ChatwootRepository, public readonly settings: SettingsRepository, public readonly websocket: WebsocketRepository, + public readonly rabbitmq: RabbitmqRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -54,6 +56,7 @@ export class RepositoryBroker { const chatwootDir = join(storePath, 'chatwoot'); const settingsDir = join(storePath, 'settings'); const websocketDir = join(storePath, 'websocket'); + const rabbitmqDir = join(storePath, 'rabbitmq'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -92,6 +95,10 @@ export class RepositoryBroker { this.logger.verbose('creating websocket dir: ' + websocketDir); fs.mkdirSync(websocketDir, { recursive: true }); } + if (!fs.existsSync(rabbitmqDir)) { + this.logger.verbose('creating rabbitmq dir: ' + rabbitmqDir); + fs.mkdirSync(rabbitmqDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 70daa292..1bc2fbae 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -8,6 +8,7 @@ import { ChatRouter } from './chat.router'; import { ChatwootRouter } from './chatwoot.router'; import { GroupRouter } from './group.router'; import { InstanceRouter } from './instance.router'; +import { RabbitmqRouter } from './rabbitmq.router'; import { MessageRouter } from './sendMessage.router'; import { SettingsRouter } from './settings.router'; import { ViewsRouter } from './view.router'; @@ -46,6 +47,7 @@ router .use('/webhook', new WebhookRouter(...guards).router) .use('/chatwoot', new ChatwootRouter(...guards).router) .use('/settings', new SettingsRouter(...guards).router) - .use('/websocket', new WebsocketRouter(...guards).router); + .use('/websocket', new WebsocketRouter(...guards).router) + .use('/rabbitmq', new RabbitmqRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/rabbitmq.router.ts b/src/whatsapp/routers/rabbitmq.router.ts new file mode 100644 index 00000000..e3f65283 --- /dev/null +++ b/src/whatsapp/routers/rabbitmq.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; +import { instanceNameSchema, rabbitmqSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { RabbitmqDto } from '../dto/rabbitmq.dto'; +import { rabbitmqController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; + +const logger = new Logger('RabbitmqRouter'); + +export class RabbitmqRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setRabbitmq'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: rabbitmqSchema, + ClassRef: RabbitmqDto, + execute: (instance, data) => rabbitmqController.createRabbitmq(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findRabbitmq'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => rabbitmqController.findRabbitmq(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/services/rabbitmq.service.ts b/src/whatsapp/services/rabbitmq.service.ts new file mode 100644 index 00000000..383ad07a --- /dev/null +++ b/src/whatsapp/services/rabbitmq.service.ts @@ -0,0 +1,33 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { RabbitmqDto } from '../dto/rabbitmq.dto'; +import { RabbitmqRaw } from '../models'; +import { WAMonitoringService } from './monitor.service'; + +export class RabbitmqService { + constructor(private readonly waMonitor: WAMonitoringService) {} + + private readonly logger = new Logger(RabbitmqService.name); + + public create(instance: InstanceDto, data: RabbitmqDto) { + this.logger.verbose('create rabbitmq: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setRabbitmq(data); + + return { rabbitmq: { ...instance, rabbitmq: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find rabbitmq: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findRabbitmq(); + + if (Object.keys(result).length === 0) { + throw new Error('Rabbitmq not found'); + } + + return result; + } catch (error) { + return { enabled: false, events: [] }; + } + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 84d48c52..59eacd39 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -64,9 +64,10 @@ import { import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; +import { getAMQP } from '../../libs/amqp.server'; import { dbserver } from '../../libs/db.connect'; import { RedisCache } from '../../libs/redis.client'; -import { getIO } from '../../libs/socket'; +import { getIO } from '../../libs/socket.server'; import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import { @@ -110,7 +111,7 @@ import { SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { SettingsRaw } from '../models'; +import { RabbitmqRaw, SettingsRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; import { ChatwootRaw } from '../models/chatwoot.model'; import { ContactRaw } from '../models/contact.model'; @@ -144,6 +145,7 @@ export class WAStartupService { private readonly localChatwoot: wa.LocalChatwoot = {}; private readonly localSettings: wa.LocalSettings = {}; private readonly localWebsocket: wa.LocalWebsocket = {}; + private readonly localRabbitmq: wa.LocalRabbitmq = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -447,10 +449,45 @@ export class WAStartupService { return data; } + private async loadRabbitmq() { + this.logger.verbose('Loading rabbitmq'); + const data = await this.repository.rabbitmq.find(this.instanceName); + + this.localRabbitmq.enabled = data?.enabled; + this.logger.verbose(`Rabbitmq enabled: ${this.localRabbitmq.enabled}`); + + this.localRabbitmq.events = data?.events; + this.logger.verbose(`Rabbitmq events: ${this.localRabbitmq.events}`); + + this.logger.verbose('Rabbitmq loaded'); + } + + public async setRabbitmq(data: RabbitmqRaw) { + this.logger.verbose('Setting rabbitmq'); + await this.repository.rabbitmq.create(data, this.instanceName); + this.logger.verbose(`Rabbitmq events: ${data.events}`); + Object.assign(this.localRabbitmq, data); + this.logger.verbose('Rabbitmq set'); + } + + public async findRabbitmq() { + this.logger.verbose('Finding rabbitmq'); + const data = await this.repository.rabbitmq.find(this.instanceName); + + if (!data) { + this.logger.verbose('Rabbitmq not found'); + throw new NotFoundException('Rabbitmq not found'); + } + + this.logger.verbose(`Rabbitmq events: ${data.events}`); + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; const websocketLocal = this.localWebsocket.events; + const rabbitmqLocal = this.localRabbitmq.events; const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); @@ -459,18 +496,56 @@ export class WAStartupService { const tokenStore = await this.repository.auth.find(this.instanceName); const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + if (this.localRabbitmq.enabled) { + const amqp = getAMQP(); + + if (amqp) { + if (Array.isArray(rabbitmqLocal) && rabbitmqLocal.includes(we)) { + const exchangeName = 'evolution_exchange'; + + amqp.assertExchange(exchangeName, 'topic', { durable: false }); + + const queueName = `${this.instanceName}.${event}`; + + amqp.assertQueue(queueName, { durable: false }); + + amqp.bindQueue(queueName, exchangeName, event); + + const message = { + event, + instance: this.instance.name, + data, + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + message['apikey'] = instanceApikey; + } + + amqp.publish(exchangeName, event, Buffer.from(JSON.stringify(message))); + } + } + } + if (this.localWebsocket.enabled) { this.logger.verbose('Sending data to websocket on channel: ' + this.instance.name); if (Array.isArray(websocketLocal) && websocketLocal.includes(we)) { this.logger.verbose('Sending data to websocket on event: ' + event); const io = getIO(); - this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); - io.of(`/${this.instance.name}`).emit(event, { + const message = { event, instance: this.instance.name, data, - }); + server_url: serverUrl, + }; + + if (expose && instanceApikey) { + message['apikey'] = instanceApikey; + } + + this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); + io.of(`/${this.instance.name}`).emit(event, message); } } @@ -867,6 +942,7 @@ export class WAStartupService { this.loadChatwoot(); this.loadSettings(); this.loadWebsocket(); + this.loadRabbitmq(); this.instance.authState = await this.defineAuthState(); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index da2918fb..bf70ebfa 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -75,6 +75,11 @@ export declare namespace wa { events?: string[]; }; + export type LocalRabbitmq = { + enabled?: boolean; + events?: string[]; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 8d2606f2..7000431a 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -7,6 +7,7 @@ import { ChatController } from './controllers/chat.controller'; import { ChatwootController } from './controllers/chatwoot.controller'; import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; +import { RabbitmqController } from './controllers/rabbitmq.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; @@ -19,6 +20,7 @@ import { ContactModel, MessageModel, MessageUpModel, + RabbitmqModel, SettingsModel, WebhookModel, WebsocketModel, @@ -29,6 +31,7 @@ import { ChatwootRepository } from './repository/chatwoot.repository'; import { ContactRepository } from './repository/contact.repository'; import { MessageRepository } from './repository/message.repository'; import { MessageUpRepository } from './repository/messageUp.repository'; +import { RabbitmqRepository } from './repository/rabbitmq.repository'; import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; import { WebhookRepository } from './repository/webhook.repository'; @@ -36,6 +39,7 @@ import { WebsocketRepository } from './repository/websocket.repository'; import { AuthService } from './services/auth.service'; import { ChatwootService } from './services/chatwoot.service'; import { WAMonitoringService } from './services/monitor.service'; +import { RabbitmqService } from './services/rabbitmq.service'; import { SettingsService } from './services/settings.service'; import { WebhookService } from './services/webhook.service'; import { WebsocketService } from './services/websocket.service'; @@ -48,6 +52,7 @@ const contactRepository = new ContactRepository(ContactModel, configService); const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); const websocketRepository = new WebsocketRepository(WebsocketModel, configService); +const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService); const chatwootRepository = new ChatwootRepository(ChatwootModel, configService); const settingsRepository = new SettingsRepository(SettingsModel, configService); const authRepository = new AuthRepository(AuthModel, configService); @@ -61,6 +66,7 @@ export const repository = new RepositoryBroker( chatwootRepository, settingsRepository, websocketRepository, + rabbitmqRepository, authRepository, configService, dbserver?.getClient(), @@ -80,6 +86,10 @@ const websocketService = new WebsocketService(waMonitor); export const websocketController = new WebsocketController(websocketService); +const rabbitmqService = new RabbitmqService(waMonitor); + +export const rabbitmqController = new RabbitmqController(rabbitmqService); + const chatwootService = new ChatwootService(waMonitor, configService); export const chatwootController = new ChatwootController(chatwootService, configService); @@ -98,6 +108,7 @@ export const instanceController = new InstanceController( chatwootService, settingsService, websocketService, + rabbitmqService, cache, ); export const viewsController = new ViewsController(waMonitor, configService); From ab5289a136c8780d40d646e4ece42941655f0adb Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 17:29:09 -0300 Subject: [PATCH 118/177] feat: Added rabbitmq to send events --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d9ac9d..40a5aca7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ * Added extra files for chatwoot and appsmith * Added Get Last Message and Archive for Chat * Added env var QRCODE_COLOR -* Added websocket with lib socket.io +* Added websocket to send events +* Added rabbitmq to send events ### Fixed From 55f8e179af99ba2b4cbc5e034c07b5566fddc76b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 17:39:07 -0300 Subject: [PATCH 119/177] feat: Added rabbitmq to send events --- Docker/.env.example | 3 +++ Dockerfile | 3 +++ src/config/env.config.ts | 10 ++++++++++ src/dev-env.yml | 4 ++++ src/libs/amqp.server.ts | 6 ++++-- 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index 6c62b8bc..0f4f2972 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -46,6 +46,9 @@ REDIS_ENABLED=true REDIS_URI=redis://redis:6379 REDIS_PREFIX_KEY=evdocker +RABBITMQ_ENABLED=true +RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created ## Define a global webhook that will listen for enabled events from all instances diff --git a/Dockerfile b/Dockerfile index 94f885a4..4484b8b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,6 +51,9 @@ ENV REDIS_ENABLED=false ENV REDIS_URI=redis://redis:6379 ENV REDIS_PREFIX_KEY=evolution +ENV RABBITMQ_ENABLED=false +ENV RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 + ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index a7638435..8ddb4e2c 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -61,6 +61,11 @@ export type Redis = { PREFIX_KEY: string; }; +export type Rabbitmq = { + ENABLED: boolean; + URI: string; +}; + export type EventsWebhook = { APPLICATION_STARTUP: boolean; QRCODE_UPDATED: boolean; @@ -116,6 +121,7 @@ export interface Env { CLEAN_STORE: CleanStoreConf; DATABASE: Database; REDIS: Redis; + RABBITMQ: Rabbitmq; LOG: Log; DEL_INSTANCE: DelInstance; WEBHOOK: Webhook; @@ -201,6 +207,10 @@ export class ConfigService { URI: process.env.REDIS_URI, PREFIX_KEY: process.env.REDIS_PREFIX_KEY, }, + RABBITMQ: { + ENABLED: process.env?.RABBITMQ_ENABLED === 'true', + URI: process.env.RABBITMQ_URI, + }, LOG: { LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], COLOR: process.env?.LOG_COLOR === 'true', diff --git a/src/dev-env.yml b/src/dev-env.yml index ed2df448..02cb0730 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -79,6 +79,10 @@ REDIS: URI: "redis://localhost:6379" PREFIX_KEY: "evolution" +RABBITMQ: + ENABLED: false + URI: "amqp://guest:guest@localhost:5672" + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created WEBHOOK: diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 55ec4193..9b3e7f7c 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -1,5 +1,6 @@ import * as amqp from 'amqplib/callback_api'; +import { configService, Rabbitmq } from '../config/env.config'; import { Logger } from '../config/logger.config'; const logger = new Logger('AMQP'); @@ -8,7 +9,8 @@ let amqpChannel: amqp.Channel | null = null; export const initAMQP = () => { return new Promise((resolve, reject) => { - amqp.connect('amqp://admin:admin@localhost:5672', (error, connection) => { + const uri = configService.get('RABBITMQ').URI; + amqp.connect(uri, (error, connection) => { if (error) { reject(error); return; @@ -25,7 +27,7 @@ export const initAMQP = () => { channel.assertExchange(exchangeName, 'topic', { durable: false }); amqpChannel = channel; - logger.log('Serviço do RabbitMQ inicializado com sucesso.'); + logger.log('AMQP initialized'); resolve(); }); }); From f1571b5f668237dc137f43be8a31d916cac57e3d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 17:41:15 -0300 Subject: [PATCH 120/177] feat: Added rabbitmq to send events --- .../controllers/instance.controller.ts | 56 ++++++++++++++++++- src/whatsapp/dto/instance.dto.ts | 2 + 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index ceb1d455..9c4a65df 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -29,7 +29,7 @@ export class InstanceController { private readonly chatwootService: ChatwootService, private readonly settingsService: SettingsService, private readonly websocketService: WebsocketService, - private readonly rebbitmqService: RabbitmqService, + private readonly rabbitmqService: RabbitmqService, private readonly cache: RedisCache, ) {} @@ -57,6 +57,8 @@ export class InstanceController { read_status, websocket_enabled, websocket_events, + rabbitmq_enabled, + rabbitmq_events, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -177,6 +179,50 @@ export class InstanceController { } } + let rabbitmqEvents: string[]; + + if (rabbitmq_enabled) { + this.logger.verbose('creating rabbitmq'); + try { + let newEvents: string[] = []; + if (rabbitmq_events.length === 0) { + newEvents = [ + 'APPLICATION_STARTUP', + 'QRCODE_UPDATED', + 'MESSAGES_SET', + 'MESSAGES_UPSERT', + 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', + 'SEND_MESSAGE', + 'CONTACTS_SET', + 'CONTACTS_UPSERT', + 'CONTACTS_UPDATE', + 'PRESENCE_UPDATE', + 'CHATS_SET', + 'CHATS_UPSERT', + 'CHATS_UPDATE', + 'CHATS_DELETE', + 'GROUPS_UPSERT', + 'GROUP_UPDATE', + 'GROUP_PARTICIPANTS_UPDATE', + 'CONNECTION_UPDATE', + 'CALL', + 'NEW_JWT_TOKEN', + ]; + } else { + newEvents = events; + } + this.rabbitmqService.create(instance, { + enabled: true, + events: newEvents, + }); + + rabbitmqEvents = (await this.rabbitmqService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + this.logger.verbose('creating settings'); const settings: wa.LocalSettings = { reject_call: reject_call || false, @@ -216,6 +262,10 @@ export class InstanceController { enabled: websocket_enabled, events: websocketEvents, }, + rabbitmq: { + enabled: rabbitmq_enabled, + events: rabbitmqEvents, + }, settings, qrcode: getQrcode, }; @@ -295,6 +345,10 @@ export class InstanceController { enabled: websocket_enabled, events: websocketEvents, }, + rabbitmq: { + enabled: rabbitmq_enabled, + events: rabbitmqEvents, + }, settings, chatwoot: { enabled: true, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index b729cff5..0788b9a7 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -20,4 +20,6 @@ export class InstanceDto { chatwoot_conversation_pending?: boolean; websocket_enabled?: boolean; websocket_events?: string[]; + rabbitmq_enabled?: boolean; + rabbitmq_events?: string[]; } From 56d621bab8d446ed6111037282f04d569da07b47 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 21:14:21 -0300 Subject: [PATCH 121/177] feat: Added rabbitmq to send events --- src/libs/amqp.server.ts | 2 +- src/libs/socket.server.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 9b3e7f7c..86819c80 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -27,7 +27,7 @@ export const initAMQP = () => { channel.assertExchange(exchangeName, 'topic', { durable: false }); amqpChannel = channel; - logger.log('AMQP initialized'); + logger.info('AMQP initialized'); resolve(); }); }); diff --git a/src/libs/socket.server.ts b/src/libs/socket.server.ts index 4be23d01..367a3933 100644 --- a/src/libs/socket.server.ts +++ b/src/libs/socket.server.ts @@ -11,7 +11,6 @@ let io: SocketIO; const cors = configService.get('CORS').ORIGIN; export const initIO = (httpServer: Server) => { - logger.verbose('Initializing Socket.io'); io = new SocketIO(httpServer, { cors: { origin: cors, @@ -19,12 +18,14 @@ export const initIO = (httpServer: Server) => { }); io.on('connection', (socket) => { - logger.verbose('Client connected'); + logger.info('User connected'); + socket.on('disconnect', () => { - logger.verbose('Client disconnected'); + logger.info('User disconnected'); }); }); + logger.info('Socket.io initialized'); return io; }; From 0da3d100b31d10c83fbcd31431df0f340c0e8f79 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 2 Aug 2023 21:33:59 -0300 Subject: [PATCH 122/177] feat: Added rabbitmq to send events --- src/main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index ddc17cbc..adc868af 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,7 +5,7 @@ import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; -import { configService, Cors, HttpServer } from './config/env.config'; +import { configService, Cors, HttpServer, Rabbitmq } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; @@ -87,7 +87,7 @@ function bootstrap() { initIO(server); - initAMQP(); + if (configService.get('RABBITMQ').ENABLED) initAMQP(); onUnexpectedError(); } From 84386847e2e553a44b476ae85308fdb5f8e9d32d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 3 Aug 2023 07:32:29 -0300 Subject: [PATCH 123/177] readme buy me coffe --- README.md | 13 +++++++++++-- public/images/bmc_qr.png | Bin 0 -> 53709 bytes public/images/picpay-qr.jpeg | Bin 0 -> 113707 bytes 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 public/images/bmc_qr.png create mode 100644 public/images/picpay-qr.jpeg diff --git a/README.md b/README.md index 351ec3ce..c5c4bc37 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ [![Postman Collection](https://img.shields.io/badge/Postman-Collection-orange)](https://evolution-api.com/postman) [![Documentation](https://img.shields.io/badge/Documentation-Official-green)](https://doc.evolution-api.com) [![License](https://img.shields.io/badge/license-GPL--3.0-orange)](./LICENSE) -[![Support](https://img.shields.io/badge/Buy%20me-coffe-orange)](https://app.picpay.com/user/davidsongomes1998) +[![Support](https://img.shields.io/badge/Donation-picpay-green)](https://app.picpay.com/user/davidsongomes1998) +[![Support](https://img.shields.io/badge/Buy%20me-coffe-orange)](https://bmc.link/evolutionapi) @@ -34,7 +35,15 @@ This code was produced based on the baileys library and it is still under develo + +#### Buy me coffe + +
+ +
diff --git a/public/images/bmc_qr.png b/public/images/bmc_qr.png new file mode 100644 index 0000000000000000000000000000000000000000..1024d760ac6440755f564c6c4ed986f49d231e91 GIT binary patch literal 53709 zcmeFZc|6qZ_di~_OAAS552>_SCVLU0Lbvq$ut;W4nqP$Gprf49ITul;ZR#A~DTMMVyfIBL18{a6mfCZZ76{f;0nZ5Y*A?%92G zOI$>?@MMUDh`7jfj^lKJ?bU>gcFE!&RdXdvFi+XRsTF9V=Nvw-e>h9eirV#TCCN2s zXmV=m%l%?wbS;$NCuPpY%ks}3*Ak@fO4s#gem6G$=h2@Z$n9&IHx~K#A2Od7$+5st z{l-x37T!zyLU&tL|NRFWrt3ew)kMZTs1!X`{OezS1%3=($^QRdxnt=6!j>ns>bz!( z$(G*U8(-HJh8KdL^Pt5g@vEa05mJ@r&6^I}rrX;g(NW7N3~u2&MebOa&bO7JO0Q$C zt%S~&M3? zJ8%X^l)@u$(f+-A34WUUdg!@=t*1X6x0CmMpYq;6R`uG95!VY64%2_IB!)Vl8afKh|>=b2~j@vk($-8kJzBEa>!C34a(Rp;5xp!(b`7PFLxFVo^w zU)OcKf%mlw7rh*DpB!kso#KPxesC7<>o_=<%}>huD?L43ca)p}l}~zL-rd9d#Ck{a ziOGebkIl&|e#*nu8~#c)Gou^_9Z~4FgNL4-R#(F3xZ2!mlC-kF17hK2Ey1<9wNHRW z@{h?585$MYEXHUwsmxkz`L#Nou~W4NTN-YT4ODp~%qJxCw$mohnObF5MunJAG* zgqNs1;t1frr6iM5>D!QHAVOCt5z;te)+D?t>=Hc1anJ?`-sE|@DHy!v6kfv(FS%hE zsrG`Q@jdOZBAY4Obyk+Xbxpg?FtlbQ8-@{pAO@aV3#jFVij5;eo~6?S1q4VCzY}v! z-hMZz>3pQqfk$f&>BpSVu5~gc`YmsXqz3&M?(sZs<1OX;b~yiG#>89CI{3?vW+Kiw zEZg%`pKSEQi<6uwYG>NZ&AZf$pE#1hs+zM-0gr2*ba8Q~KtOrLrI@ zW)j!ec@sBxSy0n9{lB%4=iQ{h&hmRZhJYBm7V^gKit<5P(K<_UPz<9zv?4U<$kb6* zm|)+#eN@dE0(iNFHh+iV$MJ|SaqclmBJkeVyPMt9JHXqib6OgY^OJ(~$HiYfIjiat zem4AA&bYs*?gmna#@9Bas!nxAD9h%J$oZ!D4zx{iJmiCpM_*jiPE$T5URy56lNrZx zWW>SS`yss$4c_AgUI+=a%{&?A~uZrmm1y?pnMlcc%;%1)H{|;>UxvlR%p%RK zuJM|avB;}4U$6|)X>d@_@@FTK_&3z@g2=(WdKP1EzNCKk8HdOmUO4&2)$_qeRSFl&v}boXIXD8h-7*d#c{d4LHzMU%zV{3Nf}uKb>rFS0R)mPLxP&HAl^2|Z zm9@@u=V*^- zKCK5~9}$u0tenJPIb1Q$p*tqUQ%CBN7j?XKBVp@YqQACR6|PT|ah_xt%FmrmOuW!m zey;@L$W|)FVgM<>7=UIKh-i*pUhQGX*UI?*Odh+tsWu*@fN{Ul2RpGDv-C#km;S&r zSD}@Wdl-!&DO)2RBqoY4-?Lqx6QSILLX;E{i7lm^NsIvTM=A^<5k|lrc4r}B{aF7- z^6GfKFEb}Sgi6_}{^%7vy)PH)*0slkLtZFBVun_*=oo0bb@EVj!tiMhN&+1#|DY~m ztfDmcO;hQ^s6l0FZHuQpi`CDfwOa-cH1K^>8Zn;#B9jlu%#9t|P??$Lke0zo&Y4HO z_vibtim;KZwniTi!{ml}dXG)tJ_|N_M}Dw?X{`a7t9)u+-qYR!BXOz?FUG7_%)4xI zDqxcw(o(okk9@RNRF&tS3R19zZ%})Ra<-oyI>KLi^8twZhUM)Q9$=0!b$Vx_dDX)Gz{+@B=?~Z6RtCG?(s=6gc zP&lC~3^l#cEWE0pJHJ((H9}{ES2yKV)h-+Tz`GyXJgx4l-=5R}oXyRK3X+-Iq=|4C zgQc<$!EF?|=}#7AZ>q_G?h=M)2OD{Ar7i3Kz!zH)W|Rzkr}&;e2KybA{?P1>P|o1c zBsNySep+2MpD@Xg!;N!17L%@8ZYpo?=zk`I!w*$5c-8JYy#8l-zadrW}yZG;ZXE^W82VG=U`QZ?1bi?;&^ZeTC*V;Q;$odn5Z=`sg zL;Fg@L&NP@Y?q6p$%1I;g5}U~KoNf1fo$mIt@5RA!=J+dOB9b+owr2I44N#zoS=q> z)_lE(P>GRi*nB*?tjsc_Emo(~>er?1IqO|yO|2nVP2?)8!0_W7v54`IvHPV78nYzf z-;SdGW!U56DEb9hYquyk`uL2rkUu$Y-}5V&Ww6MtRS zSYU;+VIm^LrcaOmdfDI*2|MZJK9?K%i7oG_@5j#Q!r*K!h2@nE-h9u-i1nKuFs5+q zCuNnJKsc}XRL%K!s^>#T=yLVwEQFh8?Q@6@m-I<$^3RVyi<^l z^=$tn{7;~l{i4>*$E!ZM_pQ?L-iAL1Ads9e`%eTNPoJb_mYm({X*D1JbwEj8p=+ZQrW_D5%JCZ<=h}(! zr~AZyyCpVgs>!%JM(YoJwP};3B;?7zE3yO|(0&(UN=@F~Ne;7e+=x?s(it^qj2)qm za2&Ki8Kr3z#E$3;+w=@DpfUm;`54=89(N{tA&m)LP>k*<;OrH9VNa!0^DfmT;H|W@m;1zo_X^tlzW+*v^7KKJsVF7a4Szq&@7*nx0j3D8ujCJk81#mu7zj3afs|yWMyC`=FjtOn-vcFnn5F9j^5XY z9ngRus|^bs!QV3q;v(^{6t8g|(mm5IB`^MBD6=kcwK?I*$xa zckPSw9SHA&Uv+pynOtzhZZn^nw=C9Fk@$v~=6|s!A9Q9TZe(nk$53{8(XbK^Lz!yd z^jL2@7=Ps_)?4oQMR#Yh!6{wq_#q&>mnfr|U?n3XeV~N(dGg*^5@dEo^_AF6m#^=v%a5 z`i56*dyBA=nS2tBC*qzAj)wX^^@S;NDEFdR)_R~pn}B_IMYs-|vl6e_45N^8h&@6% z)NUdo5hBpKs!jOJH)QS2!0$vW*+XM2RM=RJ+$p$X@o+e^fr=`gAcX_3UA~)^sEWiR zu2LXZ(qX75*Kw?d-BvXlrq$uTpP;dt=KHK?yc&)ncAo#=1%hBfCv7}Oe`f*a_Wc(E zz#V1^Z+f`7{kY|SDh~Qbt=8}9fSv0a*(M#!367i!tiDK9;xDqKoL z;G)M8DhyV%*FFBMggBbY!n6KSP?;&ubs}AKoi7V&rexo&$v0U87V}{tk)9f{V_iuQ zC46Kg=S1(ir%y4Zpp?{^$EswutcBPplln4rr1utFcTWy*C`=T7O5ha?WrT&CLU6KS zmO<_DX2iT{NOR4BXeDrM#xsA>hNF#;ERa6M9?1ti=ifzz2a#`?(ZibOGh?($E(!<; zXmh+((;jE((Zo-$2HuYz30sDChZ6HtcNTl7QCh?9(SsU*tm-McTpcw7vqne-!6z7Q zdWm_!#Bn{Pq~$HrI5;mQl^Oa8e&1>DVk!x=${XzznL3iBh$(6(P7X_`Al>s>?ZAr} zo#8z3LZDPyD_j>)!ndtjP2`xG&CqMdBl0l77Y|ISYwt^F`U6 zC?QDY9{L2KI~yIQs&KPQ;MBrmbC|?7)9*_p;!|((iXN&#!I1=Xx-5 z3oM|8RxO1}f6b|?Se`KP%q+CePE_^uE(uadsQpfr1g62bSQ5`&m4R6VU#bx3de1z? zmqA1!rJ_Y*OH7#U#wXh!Y|cBii>mL=0siAJXY=>7>LPM4#k_jL{deG`{afG=KksCc zTg3ZFv^ua)hDb%<_c7g6E;r>yd!gG#v8rY-Q$Ni5Y;<9E=I;P>D$b=JcxKfwCCmh7{`tqA)-<1K z)1p_gBVW}$W1n2n3xn(4E&e|eVmt$c)L3Z*zr0sY@db#K6NbNfl+a@V=?)Vl8Ss1TqJhH-R5n- z%1$9*qB_+Et}FLF*1UHIUYYo4X+TR)7~}b(@0$$WW?qq26sh1^Hb{Vm&`qWg2nPA^ z6v*ZmH5yKSmgOitpL;5PsBNJ+C9rReyN~)(P*@;B{{#rmJ5Qeg`@>LI+|#*5!Dhq) ziPhF&v%i0T?i38R_PkCa-+Bapysn-!zEu+*5k?djk-;(htDQxI@SAe#c6-srYNpdR38oAwmR3Ta!gS>)kQ+Hr#J7-i7CbqO)c zvV7mRf<*iHcplsHPVd&udP7kKz+fs5terK=o*`D7(hpLCeq`%qbjF zB+5R{F}fT`AWJ1zY0R@u*`m-X=#)WTySZ*jfhK2b0x@1$em!-J#H^D*whGr<%lBry z-|1b?eFXjD1;-$AnCeuirRZ@nI|Vgao}!4|U18|aVwlRMUY};x1YrJvy0@2@4v44G zT;iD>=Ox>sX5p_ZzuGo-`+$11Z5sWqXYSIVb_-+=HYF|qYwZ{mldhbe8Iqx4$9VeX z%;V!s(ZEr1Pb{+j?I><_BzX-OYA{%_=mpX$Cl<};(?UdqL*#*X@kFHlbinW+y%ASo ziI*&MB8Z@fR0M%a4~kJ<{DxYg8d&z0z_^Q+JtlgkbEr;|97mV0pFRXrCn+4#?Pm!6 zE^nO*DwW3*&=UjPR24W>Q8i9 zJ=BPgH6A2ysEGx|Z=1?^sBG*WoL}pSf5Es5ODI|T6s@Ceptj!DrKx6H_hqQ!weG^* zH?Dn0v1ViST6T=_de@2p!#_@5*6klLvETKCjPF}r3*mB51H09UxfO&E4l0^*O4|~9 zNqn&dpKP;yOm1>0HeQmhTA-N~Wzhlr+<%eLw%{m6d#ZKw?^kKTwyIw$JDGF`KHBM` zOy2)0`_wsPH?0<2x%`D|U7E@lSLMlaep|1}tfNk+2ZbJOU7w4d>&rW30C{GZ*0PRW zXBE&p1_uCLcFmhl=eMduM(72)uda|tk(W;#7Zx_Own0(4)4m-et`^dY3?s+-ABp7f z%zQ}D@t)qQA&`PzT6?@nusZs1k@Z&3DAeSP?_J(Hv7-fo7I_}?4K`Z`w})48b%IY!EHM+2!_>DqAG?nPem(y^Jztkh^=cC>aLSV>a*QIIF=s@(E+jd7t@MT+;1)T4xItEtWX>1RzR#I|myVbciOO>F>hPqa~Ir zpr+)EmGiy(*9ZBCg4bKs2_sxzyuA??bEAdS^SS;gt8Xgo5bUw<2|1t|+RqVc$T^f- z!05zp@+l3sO}%V~1P5BsYafs{c1Mt|z777(f#Zjo1s<=t{Og`ylh;~D%LI|@ovMse zw#>8Y`YYc=4zFl@Hj(%3V}~%;i|P)RcFGw*uFAzd?$*=~bcrTfs%YVh7H4+eBW&{e zo57E*gM(R4Dz+ZIK?;2yA8b%Q9eehuW1bODsmfuFGZfT z#;iCf(mfT4sGOgoj#WIb1c=jLjOUs^wI79jZKB(UEs!jCEnM-FmR%f7HMO!{Pf4JRen)kA z>cS+CVmIT_Ci+uCGp2I`-6f^chZs&U%&bI&B{D5~Q#IZ3)2Q|d!UrR+rx_aE!f=^| z9A6?cplpCkzf}KMm;NqUw@Pdr+^88Bmzt6aKm2T!iNHqRh^HwR|0*0eJJm3i9vs$N z{;Th|;5h-vtlwL*d$hCnI2t+W3WQ%T*urM4i>K(l!CmHF05DVsL}fm0k$rEt%1A#m99ba(ve)2E4$3*Y;OJ&&Cm zUj7iXQFVD-(uLzz&q>TDw&vPUp);JC3rc;+J6jTPd=#z+b!#?}SR9S%(iU=37V`2+DW8zwVt{C#xl51Avj<6>|^nnw}cd4HOMJU{-Y9j#11kY)=S znV;Q#Q>|fDVd&ymsFOj^S+-x398YC%?=CO?;1?4WWcyVhX^U;59RB!B!o6U1V5)mn zW-Cn(zJQ`Q&?gLh6N=@1e@67<-Yzb)mhnSnDxZBwOkN*1Z3;DdAwKLw@Od;Y=jB8z zqaUNRuJ$+hg+Uq}YVSBp<7LgzHNwA~P#P&$d9vY>Z`0~C?FXIsv7EHT`sPJ+o+Avt-%3M>= zTr-iaw`FW!N}CJaN?J-nD#z@WVDdIx4(QKid!t3;qbbh@s$w`^Um6_8cPly!kA zOFFule#f-%%~zk<`)7PpJa5$z-sSJ5_IkWK#f8nU+lVE-5-D6AaOeRR9c5Zn@laNu8};OMo#`_YFp zLT!ANAEZyGLkNN)fLgUjeL6Ee_%S*B-VgOW+kk@b=85T``U!&yurYG*ZfX^pw{K%k zh2a_^4uvnW(onZO^#P%4!R~zK{qg11Rg`1vL$6P^DZgJnPQF4B#7Fe1j*Az8Ll|c6 zZpO}@qHR20=xn>?SNE)9HK0~t$n(mKscGS8voGTE&3@=fG3ok+kQPT;8CN8T zIytNAHB7$;U*XSIv}Y%Xptqr=$R$=s8x+;nXKWaGij=)~C|qM8S0GDD!|3obw^`wC z6r~F&Tp9@!KF8ZWq&o0L!3Qn{@N51>^6XZM1p6GpX!!HjF^`ASlNH(p#y9th-z%lu zaT1ezhs$YQurS&l7oQc737LCXtTSw&Y`$0};7c(3c1?&9BCtM-rZxjwd3imPVm3+SIMD!E8=1o?w65E^s*R7RGmx^OdkX^rP3=vLM0akwjEL zd?xgr9nXYuiIB@|+^_hyQL70OK|3wc6!@_Pz>T;?#lzJv9q}-Iykt{tK!^z=o{a=6 zDJVC#R_XffSUps3@S~ZcCfl84CYkm_LiI%tWP%AoxYtO`No1$aKVabi=uITuU#sn zzfLyAiCqt2!eEdj2jmB-l!V^I@8g$F!re4AH4{%|D@Y-(W>xdc!oa#lt_6F~ zUe7bFPK(^B^-So1*iD`f^~do7Or2*DIb3_`BrK*NKoblWj5QIgjx~n2&Uaim-lbjM z-E2}o&tL73`U$_t%;gueFvb8 z4SQl|9;QC#`TQav+o*A9XU~${Pyaz0f3;nRbo2-puAo5b;(FiW2kW?hR^iwGD_QSv zi+1%Eke@lU8W!^kyqYm^E$eyWeueYOnAWht`c$9fqnEUWf*`{`#wlPIH8Bf;_~A00-_ zOa}faYS=)W_Bp=SB;r@EAN*|Hf6+rG73PiIl4lP)NKu-06K>1V1M*Wi{1J zOnX4^`?w&=QGPkgr(TK`sAtLynKE^kDUAv|cX9&0Z=KbIITTT74XhoF=&$Sx^8a0P z=77eyLLW?P%dA7@cP|Q&)=T3Pa!^9t7=EE=4C$j6uMRAA4XOUI!d{k_ayV%ccU+if z9cNrvMt^obt?-Cmr?NVQ8Cnsh0(}%_=vx6CLC7Rx2YE2z07doRPh+?-Pl6O?%P&ab zq~RUkK_Ay~@ZJw(Ds3mg@=h~pcNwD&_Rmw-da?H-VPZFxFKBFa zyv_NF@5j>T1uYhAD67|XLLq=cU^x8!RG0;GDM%rVms3q+ zfICbRggJiR*>pVmahZqyRS2m z!(uW}bY_i^%{W8OXIPO#kT}qm-EyoiGw|9hpxaF3D63GbTs+kl;ec!FuHZ<$#)fe_ zLO{3#5@%03JzaBd{tquI^kPd;MONAo522yzIjSZ2>8(uW8=RESp05*dyho76y-<*s zAJ4p2V=TiOdupE8V)(23G0+6C9ETF09#4L5Se-*6&9CJ(}q++XwR>0(b z8CHM|3o3nhvA{KRRD=2=J0-XV%p5U^3KKA@^N0AiV*ZYpB?u|6N!1uNK!?5 zPqAZ`BmOGV8^In5Lce0-$`0H6-+&gG0#fm>OU}^VzN1v0^Pu;R0qtrFLnrP1y~+8}tPP zKue6N@AT@FoD}xT5Q_!-D0vkfP9Z!y0QurbC&l7;5U6gJCgzh z!~k%&KTpMRwY)<`nWd4vVGY`+7hovyd%-V`F`12C)O30Ke;;-Gps8$_GvZkf-&}Ih z%?Y;B?M1QO3l8M`dwJjgu-p(=%Qtj>L@T!8FVdV{zZAoxL#Ch?l~;Ql?PIsGlWeG( z%#j>14AyfQ5(+fi%kBY-c~VL?0P4_AXL88SHbNV1lzO8Vt-x)Rnc$T$O8qm zOFdezw86|6>uut})4B4OCKFaPqfRxf97N(%N5*oX)Cw%!&PTJtQf6P#A0-G55}_kH zr=4z~I7>yb-W0IVaJ$53+B4itkny;&ML`zl{V>GWutbP9hcJ}4yjCGJy$Z?_bcZ@G z)F@p^QE}>pJuAbCvLMy288*xu2Cyt4db=BtLm+fp zt41g1?(VM>g8?GQcsT7TmKO`~yq?Www7RY%8j$!Pp2OZd7eH^7!b&0?7gnK zQ#rFrVE@<;5RDYDe~{fg4V+P?@{fjk%6|DvsxFM3C6I{xdL)HP=}bVZovI_v0upM5 z<;$Nl;Mq|^;2s!?`H$99``26;&t-L>Zu(?2CgGyU)Xoc#zOFfMADF=Z975_OI7Wc) zQGnTiRRG{iVD3MUhaO~j6qXy1og8LEY1a_(zSp|o{-B;&#c@`EfOdV*4XFPm^9ib% zNU2g_G)BN=%LGmi5KKm1-44#Gx-P;7p_ty^L_{klshz5KG!R{PGg+T~bIxAhFxm2>GVbHIFla2Qd}Z(Lz;IXohbLUW6SO63#wCDH(ZtOZ_A!f> z2?Bn*J9Vv>OoLDl@1pEO z4g@xo%J$BbNuR}tCv+QPf#w*wItG-J$uckMW9Wm|Nu_e98PL=}##lfH9rJ+Xj&!M; zV=r5CD@s$^5pG2`uVQJq(m8XmF)J$Q?WMjjF$bVUOY-vShS)FUtF~1pxeM}$NpWId zJU9|u5tu^JAw7;lx{$kGk2Ke9HFPK{4%Y_RY4y>6FjBJ|@MlxB$54M3;|ATP3q%Iv#2Sl{lD499?ai1%bQ=#0Q zI}?l#3PhZ#bKwmE^!Cg~nau=qV5NvSvExgGWM*+uKpXfHW`$H(6ky&K;$TMQXzY8r za^|qQmWs~K?vA;z^P6}(g*r^MN+^LV0SvsW>>RA@7U)rcl_v}wL7;(T8PN#D?@6#k zrb9Bzs`Yd9W5#v*nIv6Ij*uP_bX>j{V1<%9J*&9>Sa`UhVLumSa@hsFYCZv{6X)B2_L{Nuakj z77`T7kv_c}b~{XTs{-@dUS0$f5tRKko*ri`RxjAAP@s zio?YGF2byHCWbZg#K~eR^{sJTCi5_PKqtwp;FY&PZFfTC_NRBJYa5$;si z3lJj0PD1=o#{l5Nrui?-(XNCW(-9AQ9;|}P&(|6h0u@5304FlpEG=1EY;{TUXv>2n z2<(ia%rFQ{VBk5v_uW1sXRS@ZSXk*Y7?luA{uaCB76UuZBl3S|FHXaQK@3Zx!p@+T zM#GM1;Y4V| zF@w4T{QX^z+Xa4MFgkH3zIri2vlH2}32~rVE^B)q>W7Xz< z3BIBN=msG`HkT`l-2~``JX`$Bd-@X3_7lsUy8 z0(1XaNVlO(nrA;d-nSqD+Fos_^5(PLs4i$=>NjR113jQz>Y2*`M80i=FHml3S$}P+x`-TYHX#?Y258whwW&A$ZbzwyrxSEQUjjHuptt z_@CmAKY3=KVf>_f8s=_TFHlJAcpP^wQ2*mMzcAJr(<2CcfcoNcGWw-2N=+w-(x)MNT|{yT(6rK9Of?00)=d>t-mok z_vWa2n6lUKwpH))@^19@1p$uF!W_;;pS|0XEL|maJ~TQ0qhLtp~A0o@EwO zUy~DPJNhikYNhqzq|}BocI{T0i9<^%vp3BX`Py52L$nXdg9ScCh9WSwr*D$)IGNl| zFu8B(X>%Y@dJ#@hbK;6@3Hd%52hx^4XQUBzw`EB7)Cjw54+YwQ5Misq8cwWH_d;~Mac5rz+&m+vXjfl zKu1%<9HU}Zt9Il%iHdz_XTD-|{qGF^lP`DgC7tM@_>Z7<%p0}OV&1K>+&1m<2R~Z~ zBl>xO<3l$p&<@HPl zU$hL15WXSP2WP7a0W+z@2LKSqJ6RnBqX0vKw~Q@cXYAs`)^iF~n2QfD?d46wPp@gW zJ`ad4q4R#wWqDA&t9Qvkc&@iqd*)Aj8jb0XP3xP#=`~jX;P0?7m#TUavzs!J;!y(t zRGE|kxeuRlGrhy_z0^r1g@&W7wc6__$OY--7%=ZZ$p#>~S*b4gaNyJZMu}6c=w9k` zakJJJqJd<9VBrIoWbp&h(q}RY?(dF{_8+q`&)(DEOKSao@UD@Bh5Kffv4n*U{fATm zHvJ&qMI}Xp_V#-kwzgcRiJv#$SNP>grc}UZhR39L4c0kWZb>^{d)%7igKK?nxL3g{ zA`3vw-h;s{Y#0IG{KKPKC(Fu~cl!$pzf>{#?$@PnenmR>!_kXkf{%>%aL4#D_L{pG zZ4LU@e`@KQ>*f2|!*)rI|CE=w9E{mRSRG z=+rkUbBA()&Q8%gC&Vm_L#H3}z-%inNg36)-}?CzxbfMuq{~lpIUaN-KFYRM80%{n z*@xQOUm|Wnoj-+iGO2Hwsm>FuE+zT?*y=sL^S4}RRJ zkS`nT%Ttwv%(N;rHb={57(S}N10^a;I^H?$+y}A2yu6G^h=LSUg)MR{0UCFNZo~0t zve(R+uVFe*T;b89i(R2Jsp+C8R64@Uw#oyOHx91Wht*wn`x+WoR@^(lsMi%2NB)Qw zwexMf|9U71m=0~8!qFrBupTs5l-mAg%8Nxmnbyzd6D0>roOiFS8Mb$_yCLmbzd!H} zG=k1hl-HkS3q~j>IgrTm4k6 z_H*1sDc{+bPhn>68zhfPDD~~}pW8<8%3u?9m+YOzVXL`=i(iR}<1X!jUoKDNYJ9Bp z;_^a5C`*F+OUn+e)z`hlvA8~>*Ye_hC4gddQ%`74nILALw5f7eya?JUF+tLLB5>hw-Vd_MTi8p8mFk;G<6TW@MsYvsWnQ z^eEy&u^xs`N|l;_md@(em_i=cmU$Vp_g5_MEk6kbJ7;FfMzL06R`I>#eRQps?r{nA z@8l2wU}=9zMi<|by!6j30O;%v1u+}A1$Qd|w`CW?J9|xg>CBA~*P^YM|wl9e-j}Gr{Ve9pkK3=aLQ~CMKu<3DN^r5{P+@)4Arr6xYpnrb6AzyP(j% zZj5bs!|4FTdq!wuHKwvy+1&?cec@VmQOS`0kmL<2l)SawCrCd0_Om)nZ>;n&WP5Iv zzxQIk@m>Q1C5KFJ8=D#PgHqG&c}Etu;fuKoUYosk<_c4c=wU&-Pf6h+TOBK0f2_&VhFqet(T;U=G(CEU!P<8xqX zre*;wTvwMzG->fXE#|1#yMFV(ZC%bV8cMr5+(Y>QhVCXG;b%t3;2T$Il0aOiU5P@U z<@F|~jv4tP3K$gz{0C?lnY|toA2(Xu`!r~qagTLtwFB$&Tg&hw|JeINM-%P>*Y(>o z*I2JKS&+k@P4^hrlt@&EOH{X=ymTr5#Zc10H7~NBQdCsS_s=tqVpU@q*mnWL(Q)>1 zlOG^Mjg3xEJNjR2hzFO=eA`gxflVk%$+6!NVhO(!{lqRU^!h8WC)R0!b;qh}PTSnk ziGlCC9M2W59n8C_G~~qT{H#lDU@l49C4p;Ev2X+w=ZLE%T1>uD05F&Ucr{kW2@HLu zntz)oNP*$Nj)U#Fg8yMtl;V-6L9O1|Jdm#r9y5OxWk9YJjc}%8zs_%1ef@p-(AQ2z zb+0Wq6$O=QR2cYc#^RIHQ|ZbzF`fM*+VBR%h)4X@6Wq*P z$!G}q@Myyg*Q8%0caN&hJ^1;p1gXo_Ew}lS>I(NQuhtT*WYA28ipg04%6SRQ`r7P# zNAMt&o@uC*^dOC$A27pA^pZ*NP9%sy6VSt4lFm53Rf_h?&k6F%mAST)N*58sg`u4# z5*F*+<|wV_UwEf6<|)1hu5Vs5OZLuo1anxHuStXYZX~^!*irrW6$WkX1?70{y7&t! zlV`9OPnz9`it%pLMcO_xnyl`4YCEHiAbmI*&8;147TP_x=jn}wY3~D_t~PgC-7H|4 zfsOX&mIq@$auWyr6Z$DQJ)jUn%pW4=Cg1Mh|8(v-puZLGF3_rr$@Ichg7&ly}STnCXlUJf_AonSUx zU_t4&?l5;$2paE?YBaF(z}M{=T8uYwsbRoZBB0V@8)KN2pJg%0P?OI7Y4ZJJN}#6d4_3yP@jXAPErkCcdP*1>t{0iX9NO$*_np_f~^*S~3( zCmM?ZroMo(Q`&<=23+~pQJS)g=p`48w6hvzt36Ub8 zXocD^UE{u!q%+UgNRn4)K2^{<&FHe9?DBp0`fj{VM^SUa(T44+I{9o>;mZOQ zaJEYLHT3g=r|_~8*^}R5rjKpB9ZveTz70z&nNHhsC)McU=H*Oi5VDiwZ5>dtR=LkT z^PUo1Z|@x7DP=7_!0v2E;Zhnd;n(X=Va=y^ZEff~qS7m$fzL)*hk70@M0}H{o@?6k zo{3?vUsf`E6JZ4DV`yh+3gitB#%_(*1& z^+xB0F8Sk!qMXIOR`DxyUi0xetq%P6Y&E%7zAo-jS;#bbGCs@3(n>KX%utJ#|K|Nt z9t!?Og&dkJtl179`nNrzb=QzVuL1t9|O!*C*%z~ zzOOnl@MO{du=fZ_d3CCEpUWm*=!8n&8!MSawWhVh%b3wy5m$oAkL6!JWmpIOx)cK6 z#tKAihhQCu{0g4#@BI$7Boiz06#cvgdONQ)7aSrlzWg`)@aZYX*ci+Mw8{lbt!Kle ztGlT+%`0B4b!_R55is3TiKGAn+vmzx zjvJKRh}wLyGHpyaEiC)0%6rY)alPm!Cc$~8dJ)50Tjjf1lzAbkAm@dl^2+|CrB^Z< zsUoHy|2B`=Ol!KE#=`*vgio=m?x-A2z5gqKmN<94*eg?0d0~(->+f&d3}F zeZFGulzO_<$Rf@zst#hkj@=rvVOwUY3xKNz1c>npJtizmh<&9B#>{)AAJS>g%TSf- z^7nXdx665>Ixn-xaoD)VH3{_>q%5PE-MJRssJ;_+&8T>{>U*95v6*Q#>k2YdB(APr z27enubqIbx@rx~N_igZj=A&mfF9X(wo|XtMs@M_7+xjz?hsKJp3vqKR<$wL*Z}mWQ zT9vIK=4bew#<|^~o3nDt`%8-S^m|;>e(j3-vEQ;qk`FJ6J~Ze)9QC$N&^q(cRwYgU zqQ1zh#|@rFaj735!Hu_^OcTX^&)%H5p}-gvQ&on)dd$X-HeZhxMf4Z?b(ZYT`ae{? zc_5VS8#Y`C71D+fo>Hl7WzF7`q7o{VeeC-(c4M8CCD}p@*(xE4$-d2uWwP(d&Wy2( zF^gr4nK9oz_58l~eg7DLy7ucluJb&O<0c#k@Z{v+Fg|bfbPZqjsR_P4)G3$6n1G5j zZ(1Qw>**yV#io{aiPDJq5E@^HEzHD5_ThIU?Z3xc(2&b~U4pZJ)R?vj^Mphhv^Tun z6X5``ms=i7Lkg52fr^Y8)`ECw{Ns5pkbr9?vU%&=b$QNS>2K1oFCyEGChfNPs;d6? zq_q4Oi*Yt&LIOPTeG6Z{WczaiC-b{j1i9dDzAef#H;H~!+Ryu%0};3t^%hjo9*7rz0zW#YoIc_ zS$j2C5c6<#G+f@a)q7Yv2eSWc>c&nUS|2@Ak9?_@7kXqMh-`s}EYyTuQb1_7JMHXt zjQ-#MeiaAkeMQa)We#7NP`KzA+i|MR7}!k!V`sHz34RqMECezYmK5ugm4$sbvox3c z$7=oey2V{%iANiURa-S}Aj4!;xyP--*s+*EOJAMgHTwk8-9U@xH5s+|5X-8k=0*=O z1=lKNzON>n+W0l=7V4M;b@u`2O8`Sdot5Q}76tLZ4__$)-JkO|XqxQJ*69KiwXdHf zwXhsdg#U2ha=@1%9#xkzdkyyYmJI0RXwP-6!w=7`wa?jdE@)FkC)z%M1<~37`Z`?W zZrU~qn6`*~vxOX~HtLxC`Mu!Er`Y0CnC&4=1P@LHo^_A*9*96 zGF9RBMQpsrgS|1Z-;R@tg#TjOG0F~{qL&`%FN`e;8=1YLT8ygfswUA%XhnT( z{!0H9@Y;k%>2^IT+0zPh*W;l7ZkN*}7EAATLwTzo8bM}|z9(zdoY(_Z!N&s|jo2wD z=YzE>jb`%*qAVxc{N1v!dH#nEBc;q^01Fi0Dn3ci#HE>HIsoC zx^)1=Igo04gt+Wi8XghJd$dj0w_v=AEsJfcSTL-z-Gm(AFV(>ENJ3MDO*h9JFlLWQ)P|C@p)ES zkET?myYw(;*C)&4Ik8ZoBzn%>Y03uIcun zA*%tUpBmjfv@9k9zU@?Y1>4@&efUjk%%rT-eZ8UBa^r`OgGW|n!D2Nd0>(eK!?Zjh z-UzWZS5P@)7f>c#>6??0NBDw29okAvzg{~S6;)u+>D?1=99aK`YryIUGid9KDD#V{ zyWr(Ftw*jO)e#oPJZy(uv;fzovr;eTtE2S+l3<73=JK265n?-EzGm#rHHc;E@oEio zUY13jDrgx!z3bOg;j<0$ot25`yWPYJ; zNjMriMrI*@TSB{Cr2C#5~n_MCpRx97a?iR*cN7MdD4_Ao1u+66UtG2fcAR*1*-nnX+NQ=mT`4FGQwDaU3 z(NPukW3hfim31Yax#}?)DFV=8l%P`TveCw)D~XATs%_4NW3i}Ip-NU0cKy7kvYOH# z^Zz0mh_K~S$)#s$aF6PwEqp<0gr(ZGx`kL>;<908v4`dJPUF_$QHA9U>Tb$gZr1;g zT&+T61OFe99=QMk+;spVSih2eDY?v*x?c9|LpQS@I6S#NDz0D-dAu0AB7(V>CYS3= zWg)x`rzuzXc;9>~BbeY1Q$aAuY<0vP_P&AyZt&8)-t8{dMRKZenC!#ik(nfWv;ZKRFsOhdAfA3n3Z4!tQTnfH+H-OJEtx+;hoJREAV0YbJCdM7V}1iOrD#6-s@OwZy`gIKa1FeS5NrO` z1F5LOPM-^&jcNJ~$4^Pp21GNZY=B&N#pbJZL$%sRU-6;ezmFF?F0<{JTvofLh8`VI z#=wE}tlsP%*q988z>TS)T<;$*wik}QX#XCk5hX1)V70R=@vnTIu5`!nMMd_(baFKumQ1qAmv>0+)Uk~b$zj5 z*f?9E_jX#0_hjOTeiC;&(vA0AdfxGKnd@!8-kr6wb}futosdiH3$SrLbyF^Ol9_jN zG{R0Enel%06W)BSk?fHEeCISqt}3!ryQkV{p{9EPNEA5pq1p7RvDM1G$J|Kq> zi8n79N3pL=**|}NynMG?xd$?m6@YUZqbNPR>-dTgv>ap+Hgev=3)B|a5K7mud$B(H zh-l0@2B>k;B}7jeMlNCE@zRG)F}q-^^0^i=HEm9*j61^b&S*YmC7@elAT3#>HC zveK_aBTTtRUvEG__o=AUoHiFV&TljW&t04bdUv*{RymB#hvo|-?!l(taB5lKH!g}h zogj#bma0ByHRoj>$P+@>gV54pG3j8v+owRyOR_k;Imkd6v7RI~E_S2J{&Sy<_1gKZ z>sq&M=Uw0eHKNj+(qC}MbvP%fd>}WvKB_&s)}m}qp0KaD5oo9~(Q8$dcDm1=ie8`I zJBj3Kp0m}(Uq7NkeV9nL1evLw*N+F|ofw}LZXn2uYESDGFj|J7VkO3v1fSJNzA>sH=Vc&T}3;TiCWq8;^%YD7Q9hGxDc zosv=l>9KVlnLhZcRJSLT%NZis(@f9|Q$}r~_Y2hyvj7t*2^;C#Z!zJg^6J&o@~k%> zOPR^1hd+t%Derqa2ah$SN|dy?YMC%a7?eH2_`#sMN8AkKrioV_P1c5eE6Ty!l+xK7 zyqP~5%ic?240!(Q;;0Zn2^!$VQ(c#3ZGx&17S*`4n4qdhjSiOs{?%qN3bxLQi4_Tg z#Qq37{&o&L%}K||_qXWNdh|oK!PEYy@*08+M0zPzSfM~58C)XZ&KCnYh|T~%@~OR4;6{rt?I391*j%Sr6psQD$c z!|tw8HQ#pmauL@A-Q&H^K^{U=e45uP-|{T+&Sv#7Lt4Ht>9>Hio%7~Qh0l{Z4KS@q zYqbSz_ulzOaoq9RJ*w#mPw~_86pN0B=!CA+TOQ zn~xU$a5G_zjwHBnp@QlrWO>jDLP7aUVwkZW`dX?mi#%#wmRFmVl+BZ8mqUU9f`+UQc~iV+*6Z=}(6s!lPaROCkJ*@4j3(DHk3@@VtOWm#4`SJ^^4znj!w z>uNwm&0~y*W_UU^Yj)=3{*iCgy{rbjEYe6jyx_;k}M50ImIZLCf?kV{;7DWW+P z4H(|BqD4ph{LW>Rm@O;U%L0NkM4f{=cXV1v{E%&fhSt2S&t!0N`)FI|gI zl%O4{S3ckvNpQA-@WuL@etw%g0R+g@UG=R9`I~`B*+LxLym0F&;%)pF3l$f4$dN0` z*p>4FIf~e)$2&5z*e)j>)J;nB+I3dm5tEvC8uQ1MV1KtU>5vbLCwl`CGlwu+Z?Z@) zXwLmr|GH0=9jK`$$ahZd-cHG6J@Vcyd7ovWo^g6XTMuCK!}Hx#EmJYE*H*!x_g7+y;`ikomI!dQ+dAw`yZi zJG4?m%ebYnMkX>JaB1gcpqu=mvqn?4f~AgWmtt;m^L(4F!u#IzSaa=L?;ap}@v$)~ z&}g|mpv<(Lmy5Z^K{LMotLZfcWc?kAzgUR^{n|G#IiK#pxyj|G<-0l50Q%gC|Py6RaLnMsxD?GLc^`5Gyn>hrE5V@l>+&U#y`EpStM=&>7ytsgFf?BDoD z;sK` zwtu8GA6~XcNXhSQ@Tz&QVuo2+W!r)_De%uad!5=MCwAnFpC-_{)g>OP#$wepTSoFy6r_WTKId$C61Rds&~Mu0-(&qmjQd zyOW>2DO}augQKP*;3;YD!uO{K`S~NFF5OC0;WtuKvud5bt?anmlaaIbqqQM3P5f;e zv0vuhbv23T+W2~Ezgb9&nT1TLoxiP1@#%`li0$9&-{w38dU4gVnord>>b>A+{+5Ww zg#Zu4L_i_|_-$Qsssad!33Vq$5*`BhS7ke^_75c-IA~nb*g`trFX9{T5L!$$sm!eg z+#n{~==mPkKfUAPT&oY8dOngz zJp=x>{%*hlthMy?QGlE{{T^reO&(zz;HH&Ry?8XJDZssCwitRdqA9ff1~<==i2fUz z#NR3i>}7<0*8k~jfnC*!|DHgFJzmIX$W@2`U+uz5q=B5Np50de^1v7T&?o~0m0?ay zvJwg~n`|zFUxX;48#i>-)C@8#Ti!C?j9vjM{{3~AV~4gUKSmrA-D$R~ThAP>n?-b! zLM^@JJ@T4~3Bp%V|KkEwu&R7n%74#v`5&J%{?lHyLK$xcl{mmo0HWPnBLgWsIRQtMT zWQWonz!ORaFr)`k^3<9il6ANQvUxTq>iTFLJgi7yY-T);!Knr$yicbNJIFUn$2Bt! znWnR7JOF&eeVZw{NtnJg&CKP3jI%A5`*w8cDNYm8*=|2%oy_&1cc8Tk>I1`0V|5PB zERRm$XyW^N{%RR@Mj}lI?{>l-hXX6t7-g^C}-X17Nz!{@eg^s48x2PP^l z zartuPD9KNMg4p9a`$Z~hH!g}&UfbQId~@}fcu78A?*Ma#{QGBCezH#?_(BjrbAdPy z0F1F$mQcU_uifI@`m=-N0s#f8%Qr+wRUurThu|376J9-B*<5aF9b5Gzq9$#@kZ#90bLYLuKs5^f-<&r-*IgAYFHgPl7)vAdj^FOruW1{-Dtnd%4TFI zJ>5Ol%2S)XBsibm=`ifnL{>9`8($>;oJ1kz@`Xggq?j^+rHrNx^0gmt0|Jc)$10yp zahV)%e!atyo}V5AkhL6~PfkTkR@i|?~M}ZpXj=P&R1t=w)5I9S$h|A>Gk+LFg>c*;}&gfpmQ2+PNV#u zgc?5|eYmZIHkWUb^mp1we^F*&nq9tAAbX=p5j|z<RurES9{c#*m+GxrKU71KD=w&=<3lJyG6QSbJO8cqxV9Nrxgs8Mv1 zY6OP3&1>RfpJ@pLsE>D*mBVMLcs?#RUWFbM!W3VfmBeneZ7auSO5$V!Gujv%_3_t07!*%#Hn&=mNn9y?Z?}FF*_3k5&Cf>uXKfkL78@Sl)GHJW4tr*iKAHXCZB6S-BIqp zkm~+_nM0QO>wq)B-2c3Mq2k-b4CKWDVOiwizk;{FT>u;HA9{~ttjcynW|*~n%$@Cn zy?y>=@OVqRrEfD_5S;vF(t=ioc3`0Jxp%XJHvIg0yA+@-uL7TpvXftozE{zM?gaPG ziDAP^&^gC`DMa9^mmkYnRzm(a0hdbNu9wLG8dSATh2QQckuG;I+)2{H{}ri#*s8Q3 z`wyD7!+U&|hcGqaXI_r2bLJNdp8q$yK16ZF6hn;)SW zJ2~~|81Ov%K)oEuQ67LeJ=c}7xT#!4%4OMofTHX}o&h4_N8;vnudjR8_{6eA#O_oU zSBzDJxZOiJvwuhqF#zehu1OP9`;M3%|Ivl2$_rf%pI-LVTX7CO+DLyo*LD6}-tP22 zG9iqzLW!R|JWq*{x?(L@RH%-_@vRR}&VoWjJ<4v24qyk{Ls)#LU@iZ{QrST8N{Ec* z5TS~A7+qju>LNe#8M-3?$H~1wR(A9=)jllDnJT)h3=I680MC40M}T$x&+)$Q0IM;C zx0YxC$--j|{>UoTNCZMrWP>n50u&2?^5L=E?OkyQb+eb)UVNGr&*M_HQ`}guL%mjg z(J>(?$pld3v5FPztYSs_S=)e342zdT>J|qW-@q;>$#*S308=^aAx!dDo6vP%wfEr< zWxG-MG#cr1NB_ui@D+MVjSXS-R)^>Z1@3oyqedyIijEN@`OUvIKgbDsY@5>>&uNk- z1CP(X%JcMu1bP6@8v{3A>gBpeD;wlM0J8y4&#~-Q;K>BYUbiKrz!8q%Q~Xl+wY4UU3ox@m#v>niVrp~i92vYhamlZ1Z; z%h|6GIJzku-L>qhoG%hRZmlYOP&n}JQ|hoi8XNRMmFJu2q34A!(vE&0i(9XTj6-`A zWJ3Jet#-*Zg`^yy)QyCOA2x)<3jzY*EeuqJ?+iB}wFUZkp4CSSD$8X8klS4K9z9u~ za<+O5aH%)6q6$Gv`5ssd92CR^LjBGfBkees_}>d-v=|HqWWHp{RU)+*>fbr!8pz&F z_BH>Y7anlXGVrkKz!&+tQn_UL#G;5a;TMZmv+crV=wVrENa$K)U*Eb)NIIzjc8*n? zA3KK7*w3|P5jWBTKC&#@3;Bke zsfff~GEkS@7(NxdAjJ<4Q zb{DB0f$OVc@}~`O&$B*G(DU}q(^^(WK`-rTsty2j=VxxeYfJ*D(WD!3cfXHQ|1gp; zv|m8Lm#)QfbrSc9PR)51!N)yS#;1wh`;A)rO=EVH)gT~IanLW1%@51Ff;zCGDYhbb zP?d7vN_h|d3?eG(ZYU{^8BxSo-OR$2ROY`4!8jZg3+a)*X^99t0?z>6Wc$_YP3OG` zZ^g}dLqrP%wCQO9`+rP8*pr81a3i8tdt?CS=fJs5;wM6^_FR|Yi)@?ekF9ZL0YcYE zJ2Qv=_RTC5gbCu};CT9=kM~+3z_o-*(`2=VYi`@G*#HlN#q;|Q z)S!SWeB!ISySo(f6OWmkT6WUzm##zA6DH~ZChR9^_$Ws^e;4>z|Ns&h6q zc>AJhIAx0@T@CvY0`7Fq%&jr@TU7NAYv(?M4o$k3^{$IzHRCNUOG$~MIX|W_dzy&t zK7vcIcfCbh8zl!Vfek+(Qie@-6G=&w{DaL2{;!ACkA;ZVUp*rPJW#;*QF0GM%g0E7 zlgvF!o;NIB1>h*MJ5I0e1-4UT#i4lheJT2ifQHG8ee8xCXfkS^*wY7P}&m zFe#_m6>MP|Fm=?=ihHXQHqg(ZI$)u8_I7~D7irT@tcIvMdS>W2a%lY+Ia$Ta;0Z1jlQb9ocW4_^xi0qV)q{GIJR6YO>(KlI-Y z?z&}yZ$%qlTP`1%iE?AQok)AIsoV`ycRLJ6(IZwiGT5FUKTx8~CK>Z$WTlzoMl08? zXEh67511SrZ){!WHGNk!pS#!Cd zZl}izEHqOi-2)jteSDU0!175(MA6$`V(^7gSt%N|C$VO6w-;q|8!@;GK&%O)4QZ`I z1}4`h=k+oSShrR;kH>v&y-8uvi8b+|W^O{MSNnjtTtA18&uXAc>*z(X< zqvo&Ykdj3yT@MMT9$8LX2P`sscC0J-jT40T;sX zSDrJ>qc88aP@vOQT^l)Zkj2d%oFVi2an~%1)5FAy4y~QdFZ#b;=Ku-C5Ye{6{dZh( z-|sv|;`}F?A^8`|xo_V_R(HUz=cL0bH~IAcU~X+I9gFR=?)zq%*8xLr!tQnAm@$@P zldBKLJH3VpL@%R=kGYTUC@0sB>_kmFJYN@bi>_^Gcq7K#U50e0%CyNsgS3aIavPma zf*V7{bO?FR?2l~#y>Y}q`5xt~9Ig@FQGWoh@hZys1Cn2@Sl$aZHT3LS_tKoRTNK27 z-xOhG&M_ybZl(i3MMst{Ok8hj;Bj06A`q7h5I3lCW7ZumQzP*EPCM8K1uqHV%bbus zBdZr#o(%<8xA5S~*MTgV6A9d%JG&qOnyN+hS z7^Em0^&xi|2wi2DdpaUc3&)KYq}rbpYaC`lVb;$f9SnTXu;JMBHl@E^pVpWqDvR)- zJrA8rCA5WY_y+pDMsqDFYBjwWfNofkUTQ%vEiEkxJI>4?-(c&R3Yw%Hbj0_HT*pJK zxL?hJ4%LUHU} z+hxRvwl#t@`eXuU04NL)uXG!ZF6#n5C=(EReEnc|DhIB9E|ndbdGpV&0|U3cv$m zt)s~4Hk8qyEcSU@$W+U21#55hm5R|hTujEURW z@Fbjau5Xc67Hjr3J0}^sBglu?sX#-vw0nuJL;6PN081Jp&jec=V7h>BK-TO6ejxMw zdKz6p-{u`+ds+LaTfWuiPcq#~8*zY#pcQI!LN>I|pto0%d3zEqs`(}# z2Z3BD;0mwMZhRJu`^gO;Suu*;= zueE;=i9}}JPo^Z4(MI5;?=hOF)sLq|M4nBP0=NKq@~gUm86m>l+rZJFwwLa|L}| z@&!!z^@E&}il|46~`{=A2cdo(8qdccX$ zCHXUZ0|*;eN$Vs9i6}d4I&0$wTnNBjZX)>Pwu% zvZP4H4YiH9CgvC>v)SdzGbiTOI{JXzI{HHVyNTuMHh|LN@M$@Z1ybm!}?kM6{>am)8|_pIwtD2*EYh%E%c{265* zJW@=_rZ_Q!KdIC z2fPdyD-g)=6tV6mMwfP9mXLTRc_*OGR@SzgxHQWW)R-u28k_Y3jV9tR@Iu>9lCfIm zQp3Zq1XU?`r|wNFBKK+8Jd;|_SJ}S(jf>)9dyNs1QkHVkNjc*e#WVsFB1MEBhD{S4 zl@TgsVtxs(O`!-2!AT5bBSw&y+jm^GK(t0|e$+bBd-HH6Uoh*YhnbyCDupe~_k$4LH8XO}R~^ zwV3@}bFPoUXgz4#2ZrQ9RqP|4_f08dtVHsIkjBU85KPQ+kD3gk(S1f~cky%+g_HNK zEOgPR!f(}C)`Ul(%dL!>rcS*-0CR(qN+K@#j-Q`eST`<9F%mU0dzK&gLKtNA^B+0d z3*{i>I(^&jM{q+hI;+BF)1tKDd-Usm<%M&iqvDz>fRhlbNquG7a?x|b@rk6UzrWW1B z%Nuccy>l9xZh2mxHu3ar@d`B;4@Y2s^gmbcEO>UJ0v#1vR9Fbuz`pu>1gjDggfIkp zQRh`zGnK9FR^4;;w^8JgfzD)I(Zc+^*8T4=4f4u@;}+^}-iSb+dfk9!#=%b9ioDg61bb(i%z@;3`f zE=jtZ$_lxU(T%~?our~~@1~TF=i)RL-o9Gcw5l`N*i>suh`*8W+ic!`s>TD>)dlWe z9e}2}k9(~(r&H7%vn;&3u9>P&N~-TI6QTpHEeGda5`KCtK2o((1xbF6@4T;O1Bq=c zlbN>USG>z=)Ge>QNJF$QPZ*;iI9_kLkfAGf$!$#f?7acQf7TBntvSrM_k|5yhwjJIaRiU#9?f7oj>95HR-*$y+}nbDMGCRD z=p=PG9)3Dn`9#JO1xpC-$Ml7dn+1TOm;U^)XwnkcT0I{Kux=HcIX)Q{jGh8E%A945 zd$EOI7j5BW5~TBXNM+biqJDShy6z&M;XFVSN`5({*EUk zrotep$m5>Ha<(7J520GWTOKGkD2Ntz3vP4{FmeozSri^#eZP%ij zvaw4U71-R2gb2u3{3EvCNhKFa0f-GXH^YNBcSiH)q}40o54glIyC; z{qnSd1IkZIJaT{VfUnZFAZEd>>AW9+QB^-QlrY3zMGK!jZXO-kT3q3OFV#^Rwg>b` zT@@^pw*ygthWwCshcM~eJqu#8T6Y50*O}zl?=>4agy7Wdz4f9_I(4&BZ)o(WXZ@m5 z5H>{X8eun!i{rLQcx{f)-tcI*o7F;et#nR<7bsYLBv(F1R>V*ZI!W~JC-NWWk21=b zC90`sJXde~!pNEN=ZffuB^oQ|Rm{5p-=aw)on!=}qbcwKtIL2c_Si?=QB;ph0D_p%Pry>(_kZj95`F_M z?C8MdYu4Mp^M1IdcIpEu2r;Al5AL+5rUe#fnOg=^>vtR{qL_0IiMe7Eg#Hrl+2B%&pcg=;VPP&rw!60HNt~|Rz0D#K zF<_{&=}qg=wZ9wEtY1%F*HO?+8f!XZiQPvGZdY`e)`VLwM8}SkJ`Uq$knWk;q$O?p z;q;bhink%;vxOfi#D3^gR8GJD*ZhStT`_sW(7e0Qcs6U}X!)uo2>O{Tk)i%VRS?chx~bDh;SWpF3lERy#bx7FdhU!LSI%G zut~n!jpQ9g*Zxn1KMXNt+`9m}4%G=K0AEbec7mseOe5LuFTNQ6gxg-z4g0sz zkMSjMhR8qqJ8D5T4#(qI+g)P=z+LY5=~vxM$bmw69dW0BY$wc@IzNlm0yZ#=DM|h; zASN>gs=ZUl`OqS|v@6_eq^WC2S4;&k5y7CsVnP{f*mqiLi$QF09=Ml+L4)2|i{i^= z>Ds&xO1k=MJco#T+u~)e*Ak#7Ke}jK_=nr$HtRxK;8jNan9)tPPHem>gaypy$?gGQ z)acyMREOzs?K`0HK)fnovrhM-b}8y{pgg3vkg}kiK=N!%_VpC7ITzTJMjN14vUap0 zv7sCQDe+p_uOn*y#|7}J45fpg_h{1I!eGbST)T*7!tj+f^VMDB%EK-I*DHVf!~75( z7Y%DLKjQx$P5ilgoAbP5Wn5@!TRzw1dsG2kPzhmP^ICnQKBk8^TyC0(qP(o_8qV|X zzK06Efbg5sAnd=+W+qa25nHmR>f%YkM92CSkrIdfm5qL->Afm@NNIxc)^@2My~G9b zf0`^-LfA-_bai#TzobU@s`wCxbhwIkyOFylY=ueNi?Kng$xHi?S0xv^3HVEF>G1v( z<{M+=BaGLQo-TRuv@#X}>JMd1Eez-F6-7kVxWiq7=3;AmLa-3u&>I2B#Up1yP2ryf z&f|IMd;IYG1#9Mg#5x?0+gv9v(jcZ?cggie`dU_D@TL7S2b#UmoTGUYv3HR?AuB7k z8;pCg6l)la2wiF2)L}J-futg4sql2krv1{0AB0+hK~T%EXSy=It|ju(V&mVajvv&6=Jti22|j)G@kbF=XRSx*sE|?mg_=)4lFq0J!WvNghLl z6}V5RjuSDAFX9VRSVo1Ed5v-K!E0}>YiNiYTZJWLZ$%n8Z2wkdOBV5737}5NL#2~~ zzg!^dYrFj2Go&hDaQW%Z|7XwW2|ZD|lWPuB8TA_6J=9M05+NNe|Mqv=r0oJxN22K} zdCU0QJAHEwVazLD%|~T)3N&5Y_?-F^?1}a1dcFNkt+JFNO)7hZ=S*~j_AiaZX&G2H z#jPG2_WJR+{2OL+h|zY*y}joy^peLZta%*@9wa&MKNZHjb-%G@n(r7R`hefBSy@pr zN)QxBvcT?kmrZMVW}G<63m2r*=gg8xMeui1%0Lw8ptive3u zJyh_&2biE8H5GJMMA(((ib~cSU^2SCd4pq8q*EFH?WC<>k!81dhE( zcny=8xMa9H@9%?~;*bscf~iyswU3Kd?%4i0x&69K{k;}`mlg8QKqt7t?h>A@+y%W` z$I$}f6&?8xf(CAmZk_F1h*pkuznAs6zv#(+XAv?uGZcqCo}8mb6UGE>E_DSF)b(=1 zCXF2S=`C(yo8k@wCr0rgA}XnCY9K6+dlCbzOkj6$(YNGUlq**Vx$Lgn1aYYjw6_a; z9;pCzai;I-5P=ZP@xn&0=+Vt*H36|^7 zZ}DmzO)utopxZt{izNnP#baD>D`*@7zaH2VqvhAtY!K8OuD0k-MF#xX`)MtgdyHBdL5<0T{mMyS5 z3)G;KyHga+Lr95 z2SKuvBp_3p8Zi*=U5r?embC8~1(42yk*I_i6)1;Uw;U1?IdJPFNa-XPBT%FFHq!$8M?;C%8?Tw}Z`9^hWTTGW?li9UlwouFQ_v`Pi!i|sL zv~GH$+URv_Jdi@eHa!q!yq4gdPLTqldqjulJKnrXo#R?nT&51KCc{KmFUL$mwx;+)$M9R@=a+^;B}e#(ll>TBvwfHedJE?P$JwX>Z}q%Souvh zxs{KM6ys4wh&Arc_>j9K5?NWDrm$2CzagiE-Z7+yb*$81#G+GA^l-E9O6g8h2hAMo zEPA%DTYk?;oHO#=_9qdm#bYA^3mEhRlkA<}t1qyWE|v)WtA?Y_(Ied3DsK zZF0j{jyRLJI>0NH97f4acgppN%ijFTlh)&Wk@p+P%mzPyFhO=jUl3yp50lFcfZhVy zwZhM{c|tl`ml9_?#z-&iuW=W!4o`_xu{Szow2{Au9d=F=NLO@d5h)8~c)06DkmgB{ zDyenYO5B*frp%Gvd60&G3)66_&L*wn|F&fVsZQbqf?BW}g%gPEn?oSv{+ge{N=BB3ssK5JpMf%=N5^3VQn3Tu9U_#NbpUNhQ#R!o^c#5TEh zR}Izu%zl~}PCb^qj0pIPlQt>`fOPOq&O-dhNg{`LT-1ijed0L& z#;xN=RDQDt+AXMzSR0F-W_n9H%rCV>1D6VwtW4N-3)^Lx^$Nry;fP?Z_z5QOV;7={yOuj5e0;09cpMkZ3i;RmAC|?Q{R&uZXkYG>L*U9 z_T4sVFZ{D1E!5frUC%;)xA=@O*QJ5nYG8`WTqk+~+q8Yx6h-$;a~TPkjpnKCt_O!C zg|4vWo!vFVh3#Oj7Ud#z`op(p1+6`T99oR*Vxs5h|J|&nzYlRg*yOw|FK{gmr_cD^ zVRh4{?072bn)@fv6OPi$#Ajd6&hwUOFsnnlmQlf9)~6N6iTznxhW){tR^4${^z44r ziwo<6L?^@0T>3(XF|Sk{A1D4@EpyQoIQ!s|r>f#XkNP-AgH;CqMy+8`o&pp&5N~9G zz@dnA?TvWergPS~_rst)>moN3Y9AwoFAVD~ZZE^%dQ8O-_`(POKJ6`FEn;*9qIXxjfLxAXMMg4DA=Hr)UI5I1x;~97az?tqE&@ zT#|~Adw-J0C#{~Ng-;zfe}DL6iMz+o&p|_1qV0ZK$>x+f0my@9ES*w>u#fsS_5D^f zUR`)}T4RTl^w!XVj4?n)+WtkisXpy-RQsJhej* zC%+~?C>{)cs_GKQ>91sk<}G7SrPc6Cy=`KQ&p31>l8ryef+|eHDF-QOfk>LPPZMpX zvCUOD{5OxVXL2BN?KX8mLMCl{4V-M*$RTTFQUQUfJBH?j5=(1)eqM4la^*1j!RGer z#nAjg5xC&(`GHRwR&Kk1|GBx#A9N(yLVOO`h0V7e8yX1!F3O;lP*l595WMN}!slV$ zZ61R|Ak0}}D>F;LYq`0*O8kY9a zVn0oC;dco(xpyd|jE<`@{roOt) zZ}rrK6Ewf?UU9eC~nsgq>?0ZeA5;6$BwC4Jp#tos>r+m718%QP?B zYcX7?net3c$WrPmOvrKolEB(d{&5yNQ-LsgTcu|@ET`r%zw|H6l-zvWI5be^La_RW zc?ZYqDu|uXQrvJZ*rz2b@J?^!Nkz0oG~$qs)^Ldih~wC^n9tjfa@^;H(|>8iyFg5} zzf?|nilvUB7@lN`)g*L<-@(^SPQ8~uoL|P`icJFH(_Joy)t?1Evn`yRDB6a2%b9^Z zEkk}8lPgn!>lq9hBB&9&t^~!z6-os(eioH>Po7*k}uKvvZ35sshJUu$0|09#zPqAj&lxOK)| z>2{SrJ8SLAB`;-nYG2t+C$OnyUD++liAmdl3V@Z?C>({>)^T~OtAd%ixw(w{R4Ge! z>7?)#9hK#gwT186g&ta8_+LM?=)aZ3>4$h{=JKiZzuuUp0=>E3_^jr##it#$2u%E`&vA(wR$QBY!`{P`Qe-WJ3qT=9W8WuMIP+)xjhxu zRn4p3pV3pO*e_9^cj1y}pPT&6xy(fi*RuBs{IMFvW8Bl&Q|KPNQV=Sj;W;&&>Qin> zT)tbP*(Ld?kIPSPgH{dS;8P8L7bExDo=7UN==QuOvF`Ak)A=LGeJbo&F5V`F{Oh?- zzlH(onZ073J)R#G`E0$)&3N+AFr)vLcjmRQBZba_=a#peo)g>}F5N(1?ddtik|8cz zd0H!5;i)4!S-p}o1Bu+2U~Fh;sI_v6Ik9pR|8zrL&-p<{($C=T9P`H&k*-s>M-&74 zOJchRe#dz7aca1Yyr0*gR;HGy2{U%&s(N zt!%p;b9KA}mHUf66)o1I_^R7ocjt6wpYKxWnb^?z_FS`5#e}gSQ7D;|X^w&8RM(-XYeT?jd8ZOv1Z<5gx^dE0Y^uPK_ZBouH}Y*BEZVddruT;V z9`Bmigq|9xt%zH1AHL8zbz*L5;ZilnScYb>iqmTmulE({1#b02eEFvuJd37STP@wY zCXx*9&#+pA3SG{P3#l!!qq-j(EWF6iI*8AEW9>Oi!YlP`;KYZy@3g)}l^fl7LRorW zbN*R3UvHhqJ?81I0Tu1+=rdx+U}bRh)a~l* zbs5Y%7Fs9lqxT=*#?4mxqkKMC=UcpcW6fxNQ(68GhlSCQd}jW+P0Dv)i@1HNxN`Vx zu*%ijMN7qnh0@2p3o9PZNoVlJ&v95wxW;~#KC>lS>{p5j!D@Mk@mLmQg*UcW8#rWR zAv>shePbskgjkhZ2xE88#>ksD0Hw12Y$518?ao8N<=XnO@Kc?0+t$?81g=9X+B$f6 z)kbzJE_;u2v!ab>AosPlt|d6Awt{@DZD~r_oFV;Lwtr37@$Hrg6ps1%0lIZ^sNQG^K-oCMq?M559#huN8%A=BOSb7H>y$I6Ecc=13c7|L1!szJe7Wi;;z#Ra zpI^Y*@Q5=>ndo}Q5@AkGGf}PaZSUIYt-_x9-ZHQusMq`eY%(+aEj_t<)yaJ0s7Nv1 zA*|~`n|UleqEP~mK%}c=2$=RA{op>M&m#Soee9nJD~KEG9#syG3nRN?UaPE$62Pv`hD#8$Nx+h?gn&8)$z|mOgGv>nw*xD6Du$IJZMW|CHBPulP8E@hmoF}$C)w{hi0n; zDy-a=aJuSVSw*(uIx9y?)<+>PT`-L(;t!+k*^oyJ9#o$3Xg4@_*XTP>Ne_1=w-qUv-s5Bk-^H_MM_%+24>_RL z=~36w;%f+F8-M#v$}Te!n@kRRDxNepD!%#n``GP^NNbT7CSX6Cd z6%khb>D5VmFV8uy=e6_8ePNUPrHx!_E1h$s@YlZwo z6<*1_7r&8vZK$wHb&p~1P1RB%j%lpI3JBnIsYq?m*j@2k`g~I`WY{H+Sv`>M|j4+ zeG_Om!Hc3UzRSD0;=CStI1`DM`*Qt&zIdio*1F4bIU^E`HK%Y&iOxw&oY5qCytGUC z-7+hFflIU!iQ_B4jAlX+Zpw`6Uj3pXY&9x#;#KbmKHK$nnxtVw9CK;y8DW(|dqd-@ zh?6Mgn5KlrnWuF$5fvtYTifNk)RatxeowH>jIdpopI}mr@we*Fv>&0lEniR45@w`R z3VsnUjdE&!)wvUn%z@VYbH7>KTeehA!Y+8(2CnonytWN3)O~#Y?|MWcv09d21n+V> zNu46R`?}}RFv zSTiv&A?#9^DZa8WJfbfQbDq;3Y+E=9S1L6S^h@rL>-T#nIqJR)Nka>u534~4toC!G z9BCnRhr=;$m{*~z5p_UcvRBHM{?2`pV=pZHMamv$o-`4(Qhc-&`NQr7uKj&n3CWVz zIDPja-gN57*yrfgmS4nHK8@euh<6NhE1xKj?A}+SDZ=hPB*$^g=X5Ait%Ijh;YzjJ ze}6l9r0-kJO}K>B zYM$xrmvf%9IZx_quRB(Xh#d*>(r{5WTC%d|wj%K}XETR~u`oAZ1O-Z0!Q!#3`bE&P z>cZfr>t{>7D;u>V$rJOHIYmiACar{~U=nU$Yj6TYob{^T&R>yHv1NUfHesH(U2L4w zH_x5FLY=r?or9CmRcsRSb^$j;FZto3#vM7b9_`gyBp6>Eh!Q0v83JhzIAnx!OUan5 zd3fa4Z6!?98bhKp>Q5Oj`=+WYh?$^1u+oLPKmK6vJ7(7#eBkwo{A=n_AXhEnk!;s9C%{0@C@piHWqa@9$pzGY5h9!D_GdH&mnH- z-cE@i0%3nW-_P>+oWl_5XEm0c8?@C%E5O^dLpZ9bcdEvsf2etn3rJ&u_sPOc92G$Y zhHy_Ti@Y^EC$74SuXYevRdWAa4Ie+tN^J;?ESIkhb4JbK@X(}EUQ8A(ma#>(?*~A` zjB_5p?&7W4DF`;z$lhA-wVnr)c24jP_6)hQ^1_QVPN!-g@M`njFx`6hdW+l-ZE6PK zD+{mPmI2^}NvUU_&wp!GWZDGHH;NI)imY3+Ep73B?sj&8<^JV|sq3z(Ax55V%sCO@ zh>6$2J7(6)L)g^ywN^$-Oq>-ZynH!^h^&fLnT8?=fQ&I>5GL|Gn}5g>jx2qe)*6*+ znOD?y^~_mFql7+!^Gnel_Kwwe>KsiMG2|l*qMbKpvhEmmOJnATdlhI=&_)`POxk`$S#*(9WAmD5#mO6 zO2P6C!tAp=F1j=k+}+;Urjb{v{Kyi(Jp1^`g{*`WyEl^}WaIqzqQ1yaT)D^RID{t- zYr=D+F*D0ahyWo{?yTIDdSIGeVpPz;)}X|*&nIUq8`Gu9z1vF_^1Jgr6~r#>{*)?9 z8Rd+&+(MxG1Zxax(=+($+3)M`6TI2-!Y!vgyy?fgM4!~rSgn>jEq^7l6X~s%$+>*j zVSnPMDRx|-#1FUrcZna74rwkz8c(j*cb0@G-6~bzQZM0=d>q$~wEv{N;V zl$+=C#PX)!uv^6luuJtAB2ZMT>%QKH*UM&Y2>gd1<>WUH>ECOtc;6B*gG*vvPj+6J zgvQth+2#DSGvQ(`-oWHQ%Ie~;L)qINp;nV|JVNM?0@RLX9F{!!)F!>?WxOD9PbRI$ zD$OJ&2xjm~s0O^EBcx*F5vjTceWFA-)b813{v7ts(oZ5FOor7oBYRsKjs3pv)HYiD zh?P41JaY-Y&--Y#d;tG9JitAqQ4DqP3Pvg4=W!w~EsT`4m6l3kT#0=UMT?)e%IiAq z@#~WxA$4D*>Q*#giExePOZ$qdtpGy2Qa{G2Q%F0K=^R4qsvbF)dn#&51RDzGA1!j8He zR}f=Dn7txRVOOvl64xs)1ILgiuDskh3*L6_LIY3ns%;zgS_C+k#jkrZzT9PJO*GA< zNrUt8tHHD$Houdv=(r!ap(Y=(UzwD620`qX6&^w!X*v7vV4X`}M@0pWr*&^NPTl&x zCJy7DoC}1h4616yYE=#8d@+_!Dq~B%N#j+IUkxfTuy3*MQ^U)Fr<<0RHf`D%w?UtF z@aop<$^1`qQcKgQs+qJ5MqKjXXApo-etxN{xWy7y?UyaXkFxl8YQ@gDID#{_ZvW+b zr)-zbctHJm3W1C`OdnY=dZ&>p<_7EwOc=eKeU*kjFO7j=NY5J&k#w!3O zykRbBd%UKn85&CN=QNp1zvqI&VFW~6n-byY(UFnG2#`=_VlaRCru3RNHK(EEg5NWN z3~7sM-GBi42CoUuN?Zrdhowfkcn~m+;_y%4EyTv+E?WYB&z*wAGF+o+J)HS^m!>o* z&dRWnOyP9JwR4Oc*rTiw+8K;84Wmq6M_m5|Xi^e4yrlAd^J!v)?WJZ%nDYvS^LlL^ z-i(|vH!ctudpAbByYh&0Scb2ga!PM}R?^%a1fySl^I}uMxa5B7vdk93_A;|0wrn#= zw5=@B1Wk)q;6RvQdaZllwQSqjk0bi*laWOq2PGAcu0Y>QoZ;J>J8qMYr!Rqw`Va5b z9%0N@9mYn8^%FH18<_0lMt0$rbleN)mLFT%*&yZAm;u6C z(`T?BiVZO&cqbs7>P>9TnZY?K!)ZaKA@U7}2NtGxuDs6{@yteT@}-hZA{NZt^06CG z5es=8_J#p8y{@e9;9i=f z!-n3E0%%*-P5Bz%DcrIBxgQ_FgY4R2Gk8(7ciGZ>M=XDy>CkeRP(2UkkdHDmnNM^4 z;8NV-%d6;dDXp=Nxvhz$f@Q1XOgMI{cKl?FM~gJFuhw}@X?*VWJxMqi*4LtK=MgU| zzSpNss-2z4dbPvIx-Szbqmd_o`Iej-f=0113q~fj76g|Pt_e}<&?POcz2`=lrPMx& zErUUp?x)gpy^rP|<;zP@YL{=Gq0`t{p6lm_Km&2zj^F9g+d9nWaMp! z&Bf)3Q_u}(TlOIPZ89^gdje+gKIvhp;xQOJy6#wa^OB^Bq8wSq zJ%d$VUY=f>wKdaF?v4anK?mvTX@kpP{jfD?P^!6Qnp$^Ch{MHO^Gt@NEogtmd*1uj zYi-7NTDSFM?1{@{(@C0cw6qmTHP1A2&{#uJl`8l~@Xdm75UlU+_~ji2kPCcx2NV6E z)RLy9i8RopWum7X0MiHtUZI*Cy6JKjZX9>mM@PjvYEtjBjg+9Ypon5;?)k80Ib&Hl3rDl)Jo730i`Uf!W)zF3oAVThR~vHr{D zBiF87i|A#ZCikT(T;a^9CAP-W0#dKi{x+RK;=E3?9C<}$mVB*$e{S1@|irt1u^{od<+2+2~>yZ3eF`bV$V;H*P#+`fiTE68^Lf2Ncj`LiIaYD#(Qd5+ zCrqLWZa~1Ux^w-EA-&$H(1q2oc)bMS_-7=c5E8QbBnt|_ z?)^UsJcR<=L&Ye9?<-CrB;I3JSVPN?*^!W+{(P(bn>5+wlzz?d&9$+zEA`vXH_bJ% z&Uky`sUdwcn(@foVZ@JKC%$>!T~!hMrTDm@Z%@al6PCmCz@{BLCRQ&fQ2gcFw}^vY zPhHE6LgC5mTJQ^p^Wx{4Q&B;PCt#_KnA2h=-jG(~3qAYp_j42H(CUDrN9WgQ(BtPa z!T^@7jdk<1#v^$?Fl&pAa8Lnz?C=j()M|8-RQ0LZr?JabVMmWL(Oa6JLk0jH(89}+ z?!+&wuSGgEs3|mbXcAj@Um8BI^6PXy$nAF={306oMcC>4IzQTk;o2w}kTsxSAm;(X zu^d`fLu_@}Y6VU6C|D)Sn;STO+~2|ZC)xt{9#$k~9r$ai$NtMyUoKvib}7X@_dXJ~ zFJ2L62H~ILoKWb1y>LP~O#1SJ)nwZXEx|X^q9T=G|@9s*lg;dbU!_1*YD9_|2Z1|WYUEa;R@ak z$LYGKY@r~-;~h4%d{?d6pR=>GN4DD z&`&!%Eopr;iujVQiM+9F-R4Nt7U=dW`*P*I;?-N^r-H?K>RRq@weiV$M-NVjoJ7%$ zJ;(!ssqX5C1{>%U3=pzcDv0>20v1t&I>E=-otzT%!@5;CP0CD#;|4nZqmL%$ws%E} zO1+-3VKY!n^jvKjCz*@ZAo%Ktogw&sQsn%-7h___0Ibw@C^(&>z;zupVkIUjeUe{m z_JkQ;d!-z?*zPP+jPmi>%v1J0En(tgS;#E=fZcNod+llH?sSG@@y@N(V!ZhqD-qs=FUlO9%pS|^ zb&ap)e_TI5R%tDjU)mG_eoou>b~;P1OueNJHlUO|yo@cbVXo=v$wC=*xX3xoq?;No zLw0bP;ydTxT?%owjPt4-j&de%4p=l^vkY)9PtISuu290>ZP>gA&*)=cC8^_pnDAuq zC`I-@)klmZg2orP#NBxZFHd$^XjWNz|vch<4p8 zC^f)Jy+9P&2%Yy!p)hkkel9?xS*yBEz*H{3cKg|)jJ0${dHFW6`+W6Un;OdItssTa z|DB1YE$&g%PuvsnRbaxh-%v!Ta(dpkQV!YZDf z2dRQ`cR#+r2Hk#|z$tvMK<2y~*Soju#03&v^YF&VA{m)EW4N)~!EK8FRG0J*Lz*7{ znNUhIhfC-;^SVUORhdZ|h>)>x*3X#(_2(FxKfwsr--hsGCv)^|v6Upg$!04Cw|wD9 zQ`OGvkLAO5uI;WMk%vhetWCfcVQ5mOa8F2g1L&)}yocwV@hoJ0m@5+3E1Sv}&f?AZIO6x6@OQN=$dG8KTlW=;^C6lr$i5o8x*9sEI+CGE_NB)Qwrf3Ed5d-NnlK)Hk3aLb4Q}0ufv7fay z>R2IXn&r6_(KS1z?S$o+EE&fh-T*f^0;g~XEx%BF6y@J8Xvi=88I~z-BnpAhm>hV9 z6VT|I_QUKgK4p04@TWr_e6T0#EDaE-h{)F(oGOquYWAti5$ovJP%Lx`_7jam^ktSx z6zq=3->>3Hi12xENF7DF_d4)8fI(5dbCTJAaQz~VDOP1sY@c^TI9nrXC&2UC&Rm;U z0c~{nuR+s|a?G$bnfQnZOO5WRuRns}@`cKeK?_Xi(qT6;6jMe>&}8K6bTyK2pvL9kDq_-@F> zJP~$0Fmm|f!M7&@$KOwgOMl*OG?#t*_`)0X=;4>IzoQb-u4$4)4SxCaU$v$n(Ql)H ziQNhoooUnkzSrK#&0RN8Ke*VseHIRJ4##+^F#*s=+21&t7{pv*%)r`Z!9hxIP6g{L zQ|vamoEuXmdLjBz*O0zt@(1CNRNK=mT>)<<>!ZQttUbhj_X~@M1F6rvd55x zT;Z8I`&S*)ZjNC&waW4Gcak;UVlHM*X$%@i54!~?uQ2a$Sc%7rYtnrXo_m% zK`DQk2|LHn^I|5w&eP{@!I_%Y{gz8MDeH_@nzU)jA^jX+ywtjF#5;&Gh6;#y#CZWy(Hl%i9AhL@YdCMm0^?*Fr65H~@)diYZfgNmh0^ENE z=8rMX>b*eb|6sRMSsctj-^;2-?_pLMTh!i@*s3|mO;SzZ>sign-irz@7#wR)=PaK6 z+5H~K(>a%_f^)(!g5vhSqN(vre58shp!Qhpsg9XBMDfra^E`^)CrVzM%lp)ioj_ka zJ2>)Fk32(CflKqcg=PEHcUvmuRe?1Rh!NzDt)vhGqu&iUF2Ca_K7l|$A26!>o{^t0 z-DfD4J%QOX*w&Bn5LTKb)@dnfG~qHs&v{rT&H-ayIjKWF13}bn zHL@l%AdWUa>W~|e8(eX$x+CijPg;_@Vazcf{ZPQ@)5B1;02c#`XC;{!tV^UPE0H7K z-KKnh_I|4qrObcW@Q&rk+g=`dUkqxExL&t~u7n1YRppYh;BGrd?SD5+w^oiU@0pnc z6P9B8dOWF~glrv=)Z|fo^f9u@!bWo7Z0b^UOh0oz(DPWs_I)Q8k7f&Q{FS<}35UcB zvi^Ht2;Z>Rxk(nzXUzj73O~5D1f34PZo1L<+KmAvo$onP^<|@uX%d&E>g_SSKW3X+ z-pyt3p@Nnci9i@Cl~Ez&csz`c=(O^{XX~TV=K3H%hQs!U6Q>;6G4XlH#PhuJJFQ;H zAIW~Jvv}x?*(RGu;KGn)W~OqI*l)HpL(ZtTZ@W+|$b(HGgfD++y%Fx7eIA#aoL(*~ zMqCclLx~lu*Io-Cx&n6@s@n0lL*c>|B6k(Gj>nbPO zFd#(^MiDnzEuW4(oc%%bOg6k^M~O$>{SZ}aufxzB)TFO)z#;NMvNYn21i#s3-N672 zp^I|l;lAhm2_n)zf>GM$kws?IlRT|s)H2h!7Z2*TptSBT; zuG&~2G6-c~J~GWMV{#t|;ERp3z#>8*$wja)%B+{08eB-SCiOBLzXyXXG%(VZSIP>T z<~@8-R>Ear$6Xsz{`g__=0GvHKtco^IfR&ad9=t>%gEJ6;6)*^y)0}d9JK8W-+_7_ zl!;nZU++4)pWKC8^N07&9~P&C?;RiIu!s!jZa}v+fnHp?=3Gzx-KY^7X*7!_O+-QF z|4O6ICCQqboosVNY_Xzf2%Rmi3o0qGDBWM$Bt|IwvW3hpf5Qg9iUqG~tORzUEO^3y zD?9n{?D);C5l#@^JU#V0Sa%s5#~r-Ii625pvP1wr;BbXFx&}kjARAdXaGMQ6(gA0E z`NtaNlW-G4&dsNWw0?;ErG~2lafsCvQQZ?cKv+=#_Kqs~k4h8o6 z8N?naHE|7Y>w0()>|kl|nfnscVvA(qAde^?WQ`nt;fzluSYWxB^Uvq|@c-}D2nBDfKDl~aupo-LCg?hQ;{`tWF$``fp027^~X9@!{+Y*|m^8uL7JUcdV7 z;sH5wzliJn201dWKS1zyq=*(w6cdo0fbep!Woo9Fj2WP{hYj9WvT{YV3-)9(j8U(b zHS&8U40T0Hct~cBXDxC*ZRF5?Nla-MKngGYyRdM|Wnp?o7VbhV4S|xYI`VtO6$ z@`;fGKP-E@FZW>&8#S7%2}OP-LLfu|qkyLHQ%Wo5*W+I3yVuei z2Fg@hj-0{W;1|UAD0mR=-@oGYDj(nb>kjz-*b`} z1ocr(AuFV#T$dMCX*cV@mN|v3J0%J%m^XE~$t!EK(#u17CuRkhi-~u_i(~=m`o@E* zeV>kXS#2Z!#(I93B*LLmi@pFJ;Kq^St$#4l@;2iba1;t*d;VoJsIxGuHTAb?afWxN z&sTBwIM<7CUzz=bS7Wm{A-w$Ux#diBNajyD!0BL3RQLTbEYV~nFU_mb(Bw!5tfk-^ z%LCSGL$Iqf3rMU_krL3-*1qLOqbFM1J}WZgQwYk%!;=149R2#1QbS$r3}b!mO6jhN zHLYiQq#FE0&N~t|pRFs%SPzMV7wgcTbvWZ65d{~|$b8P4Symg=28acMa~a;i{v;U0 zE)5vXKKC2=?9i{38Mjx#7_~*FP-O4645|NA(0)8ZB*TEMmqLZ$@B6TG?D!#ka_mM? z5&WuETU0NcRnyIFe-=y<((ws?3$_<3h)70MqCbZ{lo^+4h4t}2=%ZD{Q>$#sPVHS} zu??b^+=5%WRju@gAPVKm=>$2zV{O)+S(M~DuMCa6Ui+}|^7;Y4@OUMQ5Wy1>II@#{ zR1x^9jKruVHv)23N#p3>6<%7$R*rlRtGBI{2X*+|x2s3Ex%IO7l8-xoXK^yfRiH7h>qZb;Ys^waAgxEvFbcrHC(;b;!Xh9g}?Ty zA?%@mcW2%}nmZ*vF%Dq+e9U(<3O};*4dJr+2&w#$MTS6YHh;x9ugE~|21&T!CinA#fg!kG!@_XcR|5566gPc~R{1>;@j+d6I@Jo@U=sTB;F zuk0`23(jh4iII|#W2EXvI3}N7NOU|R)cr}_-OOzFg=ePCu*t3&2(lC(YD@v_Ijr-4 zDYq5MA?6j7yXp7QPFR1R!BAdb%w4N*Ju`(m%@mtBf>nAF2P6+2E% zY4pL-n*KqGPx-x#ce9YA`}GO|i+d|kylo!z)-DIlTNko6UI3yM*banLOA5{A=SXMe zFfMKZ_EqXUNw~Ytm4&-c6f_+fJN`+88zXS}Nn77;G375U$$n$v5GiKDA+JHppfkM0 z?T>RH(GwuyWG%z|S9Z4*=Yn+_YHD{y9j>(mpYym_NKRC={eJd_7dFAjw8zo|#$Tw2 zl{y<_CNQoe3A!0nZ(xf5lyBXVB4~=MTqk+-w=d2_Aa-bLaJFgtyE)A>%>`5!Wp}~@ znNqN*aNlR)K8KNQV#1oqA;DRG{X1xK#8pPcH$t3pfZ%&%yk+_StNGApa)z+6i(@wae$mjjFx9vVC;h znWpP4sU*bIiAO~QqY4OyPfyXfy1cU}FkHtH&2C5EU_hzuXPfM>&H|^LR&i(jzBnN- ztocy{`&$x3ZmfAK z;wM)sAv0E{P6;shV(g{{i_|yUH2(|%!u}?}2x}w}vHE3lD+NuBI&S!de`!+`Mo#?} z@DxC-4qsZ?-oE$Dv<%u^=E{p9meF5)6MZs3D1FyG(Uj!>d12?e3ef<_igDU8Z;=#U z{o)dhmtPc>GZrrvyP|G7pl$}y52EO%uG`~X_pV50D@bN9+!}l4ZGyFPi7;A0#y!_k z-b|tEQ@|Ecl<6NBLB-I91Q1G4BK98S9HA9}Sp_ovw0Ut0&{ba3FL+G`N1U*Kv_and zvK*JZORYVYgS6Ux2&>nfq?cGXgq6?A+5CE?2iKqnauE*>{SSrjoZvi_`C;$+jY7sB zSLJqG^9whvJ5}Eq&N6f%7q5NXQqQ}k=NJA20#7i4Et@R8P=TY@Z!qZy2-HU>R(<4oK8n90b|xDmfe5HL)ToP zXrY0H2Dbv$PbCUA>;Q5TljV{|64$om#=LnBB>AEvd7B3!(lBOA4y|85hBNnJQV;q4SG0!r*lU?RT_GsdDv^x*)vgXD!qSF2 z>`q*wtqys4i&fi{$PsVRthAT=zn zjRM*bdB8(0-!g%nn9=yp-u6h!v>`}Zlhj6Mp=S;k!o?*USqpJB%K4hFrf+CkA^q(q z;Y}>T)5!SONPm}ovx}0>8QX84`sIDFD!=2U63xhI5jg{yLU?)N4}~qUA+UY9<`DK^ zt))4E+vp91wswdKu0Wc-ba7%xDi-))M@wFm_zyi#^pwfXtcH%4M#tA#;ctCGWnb4M zMj~}&-qP$p;_i_L%7WS=z*TW9CA+Ws?)v;Zn`XLY{0JJ}WcQk`A^Bg!{dX!(z zzrR<-Nm*C*hIUO=GsjNlFAcNjm-06UfFjiWzsm<-f0~<+H>{1y=(LdAX?J@6JhJia z6+(a4o7%b-;;tIF`byykzlUMv`X88ya#%sE%NsHcDYm5(12O$Pd*zOKyf>*a#A^?Q znk(BC;VW-A-ArPw3yhn2qT`%}A0<{Zz5q zT;Sn83-^+_N<315He$ZX{Q$F@b<^ZVmOE+3p9}lc_@4_KBxss0_4rDJx&Ec_+ai%k zGS;}6XhYh|j9^5r9F^Y)KeO^2PWiVUaA}+S<$So_eK+Q&ez8~Rw4HiRf@om&!FXdU zHSZv!B#vija4*-$A%cB;NrO2K8m#&+4bJyXx>BOK{i-OgYqt9(F=>w1vff(caqH=e zsoFK?n`cwXlBG8V7Nw)h=p9X_IZ)qFCH;d`; zFW?$8&9EGzMp`6O>%4%JpjS;vZHFuxJTOvEg%cyz?<1Dk8j-Fj0)0qE6(O{TBUE2l z9=IN_omDo_5!uUgzcMGGbnADfA*YkWVA<}V0DZPPaimGmmeptYQ-2)?$aRfT3BoHt z@El<1HiDXjM`Ds8+==;!&uh$=A4U7=+VWV76d#G?5q$T096SS@jo2{xGs z6d#BaD!`SAZg}0oLvTmhdciQc*?0Nef$41$BN?=5qX1ghN9u#9RDOlSwzHrzz&iq{ z2IyR{6;$B$1iC{ut0`OvquYfa$aPG#6sM8hAnxEghD0>v#ZQuM% zSFpQy+K;_g&vg5#&EJpp2?(&)w`|mZpWm|?C7|mR`{QV7JZi|XwY^IpF{=zqV1u#6 zS&ctIDj2$YBf7WtmW<1lZciEgnxnZk|OhwoF$tfyq%`9%7%0icb^&qR&y$# zM8Jggguo^Oegjo=ko~+IQi+TcG`w0v)L#`)`GOpR^BBcjANB1Eg@`!1ZR_W}?LHzu zorZ4l#Lg@uFEM!n0fKQZybr+TbG@@1_O*N=cQS+{_Jy~uE!pC==3VJKE*72#6WR2) zsYzh_EfR-uGq_69^=N4q*zun{J9qu@5lxDbT%Np*Gj&Vp2yN) zG1lh%56Qb-7%fX)_s6Y({gX$Z?#m1soAMhEtg(ew%B+aE$d-TC57a{fnWd%5T z^hS_&2b*bR>~L$LEFpu41j|Qa7;lqA#zOp zCHnq&ji!mZXtv~0zFs+Y*x`qZ`^>g;%0*RMIyDQDrX)}A$hakGnztr<4=^w@tPxEe zM$#Op02jf1OlX_JJs9l57Tt*MPcu2RRqn0a{5tb9DlA166)#G%-L-(yj`7M<$E2pa z&n9->Fbo)!eObQB1O=h-pAbN}!Hb;TD|?JFvd7pqO_V?HXRc)C+~xf9pFGNa;qEc( z0e>Wm2=br){Mkn8yI&6Hb+7j;8ACwaLGqF6PW==B6iK;OB<-I+^Kf=fPa+S7=e__FUXwwf?TW%lr!u=BJEv=|6v#g%*u{j;OZ$-@ZZR zZ#=j^_cCKFg1`OqXHIC*Hl+Wt0>|HLaUrahBX>2|Y*GBj&n-8hMV|D<%YPqu)Pu2O zFm#Vdd9#21ECekQ)xyL_kcs$nKJH65D8ta*bfh&#|MBx>A81jwV)D#CXZ8QnWG|~4 Y;1<#fEhtA;!JiA~E}cz1ee>b}0ox>NPXGV_ literal 0 HcmV?d00001 diff --git a/public/images/picpay-qr.jpeg b/public/images/picpay-qr.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..de911657321e50f78f875612fba1c6c157ba205f GIT binary patch literal 113707 zcmb5V1z1$u+c&%kDUk*NX@(XA6r_hxU}%Q!1_41D=@wAByO9nlNkKqbKuSvKZlv?w z)yo90Z~5;tRrOe(iy=EaUitAHnUYz0j~)APymhq9FPLU5&DC_ z!Q)j90Pr0H07}$9&y14+;A0Q~kWT;e43Y%^xPbsrH}uc5e{5oBlOI10A2!S01W^GYylI11H9t~H~}tz_jU%5 z08o$-2jYwZ9;j%jhyw!+?G73y1{M}31|}vJHZC^SU7Wj^nD_AS;o#!o;p1Up6A%*M z5rX%42qH*`H&IYAz!&lEV%`Ox{{K8~+W>qFB(XrLv?vp;@6<2q3%Kq?qpA7Q&DLih3flg!14HN&-g#%_& z=a?K8Db;}7ymqs|pf?E}AUg_B5TrZ*mIgpZ0xgDq2Lmh>#|M9bqM)IJCPe=&GWZi8 z^$sl>Isq3Uv6!-bH1}g3UKJxhB09M0htDK2+281&I4s6Q&K5LUK-g^Lk0b>lBP{1Ff&qI_<@x=h1D5_QYK@Irj z1PlJq#}h;LLj_ClgIvRnMW^(ZG=G->Ak8F@3F6v7B?_L)5p1kL!4Uj7%MTz(dP{g> z#2`P>fR=WUQMforbZkWo6~8pu2tg80jF7IKvwWYe*%*~n4Ao3H3rRSaQ|vzRHb~{| zCNf5QQx|O^clkjGO(+eX7^*7x1^`~=5Lf)-rZ%u73WFxBpax*7vH452&&5q$^sIZN z23aWyl6t4D@7yP2A;E90_kA^scOeWrKgJ(P=QjOQd zKe+(>xD!9&TrLM8U+_IWM8u4t8tKhzyzcyMn(qilAV_k8SEQd)b!PC3;_`4Q7rl=G z-j=HEadB}0J$Go*ejS9~d!RRlT%HSs(S!x8l_K2&i=>M?g^*41>RVv_ZSR=_o#@0@ z-KLj1#rpALx=}_B+2g_5kYiI{2O?ntG%l(-^6)zn1%(ZQl#Uh-58seseXZ8)z25Tr zeo4ik1ClQFuz`4rT&-OqbGDSv?Zn*zkt6&f6%DsQ2iF(Dh_Ra}jUxvKBA6G2 z$DPP`GvQX;og+_DWs-))p3&+q7~)}2V0%U$cZ9mD&XvB18&`ipBPXu{-)iCS zRu*L<3p^0Q=YE@`i*;caf{kMS#!K7Gs8?vFb-P(WK^ zRQhAknf>Eaum#b8ZTnvl|HttE;Tb%!d!k~X=Q`yb(A0i%{cZ#Q(cI|Oeg^`bG`;Cb z7}!dX3s^B|!e2E1N4v{eb^{RY|G6_5ni5KX1rO+VJTU@M`pPV&&5xAQ@WMl5bHl89 zJY5+a^s5{ZuJ4`MAH}{GZr6QM-X2`0`WYP^>|dnLnaJp&BbcZ%@QYkiyJC0D#X{v0 z)5>y%x4qKs7U1|!wsy^o6Kds4wNqJ&_Nq+=@DNsO z!{Dtgj(qj22SB+Zj1XJmny-DVZ0=0rt)F%MurJwsEX*x%*_2vIaIH?5ZpZzo0LDCh zLG^yrh8LE!yoLGZIMd}q=VH>x`W9FPuH0=pbWC3+S`Eg5en^p(uaDbg^1 z$8+4HFZa2X<)=jCGg5wz%1&<;&{aIkA`3N(iK@I%>ERP%kyxP2+@>w+t}U)Oet!#0 zzd?EFM=w7~x_#;E8LTS%TFN&1oPIhtakS_T<9Y7-!*|XN<`#+YFJo!3Df0Q&y3+dJ zbZ0ceV%kQ{+=%4YsI|2sWi3^DpBDoS+>!;Z4!M1*9-`-?uH{iz@m0rd zkd2Y7n&~)041*vhJE5}d{szv;uUo#(GocTw$9N@<6E7>;Ubj9pCjTKj{J?!N(ZPMj zD8=SEP3%h8lj=Dv>1~DA^qWC0MKXoT7IXPyD{1EDde7M;0?@b49A`~N@z=h0DB>J1 z4?=4NDU)7y-U44H9>taAN)doVn2A!$ajic%Ncw^&uoL)a4Ea5rBF0s4Fr@jc!@AT-@Qc(W_1^ba@nMlA*ht;e)8}^2jY}`ndrN7c2m=(!%nZu; zYnqUAvqsIYDpVh2CKy%qB_+NHipc?JVh@hqNauIPKZ-||LaFD&C)rhU+UQ>qDX*)@ za1Zo2wtKRFu)*?6%5A`fjb&<bd@?3w8-7W#W=pZ1;%l_a?4KieqNZF z7RVCH&U10zwPsq$!0m_(l)jgd9VJlR%QU(|JU<=RU+7huZNtKVCDtC3?}G_(z}TRO z4C9|>aQmuHVp@7Erj?usGy9e1UvrR|A&EO7=bnUZ-RU*;OG`GNg0nOnC=%aA?mnBK4smbx??HdM8UcG9JW!LgtXZ--TDd<0X z5Tx0N7evuN+_a3#FXa7Pa=rQq-o9y}?Ai5|#m&b)q8GR{1;eM*q?uYOXBOojWBuRX z>>}UYxan{$ir55W;tm*VF`rEqw?h%$&S zt}ZT(B-4dnF-0|`_@ruajK942wGIJ>hU{p0fj=LFhPs_zc!)CRi_Bs#WkE15c$W@B`)bFGgu z65P(4S|r}kvw<|s$ETdyDk#-@TrpAU<8r1L#d*wzQulJm#PN(*uDY2D?~G(LFSn?5 zLgYkj+a(u%NrFsDvtB=0!nz|i50eI_n!=BSYH#EMbQ4G6vFwbLKu8 ztIHiKCwk^_?9p}$bfIr02$1tmul0 z;Y6N6;n%9WTkfi;S;3ezhQFdjD5Q+jCuR!v%P!t}k9pUJostlx%O=URFlbS0ybd!V zsbkD1YqWEbedgFa_sUT|qid|6Q=Zl7M~o$J47t|5k*QIfH*0wXrl~_5jbYhPZYiia zomQ4^jYmq_+i+H!h6Hu=Pt$&9u2j(mYqWY20b%A4VeIAtcAXLZ=O6n_iz65kr+YtZ z*UR|sq=gaAA#*5o%lArpwG@1)Y8v~p$Ti$yjwwShvY|cT1fQ`GS;aNBn z7L(9yN`~p6b5DUN%$Ym)Oo}S&;sOPm4GV{xg1TcZa_=ybspu%7#D&KkW=PQ|7#4O& z7=5k0{{3x{{CnpgCH*WG{Li%?!|GBEp4$`4G`4J?p1JIhh0j=*)(tc|sEdo+p~*x@ z!Hyvr-62UYz3OJ;mwBGr59XwElrldF3=+t4>ph~z#tpO{TbFtDMrbIeDm|myqV^{> z3OZwYs%Jvp(=<=1fs?R6cB_7y_{=D!n=pxF(P4JJtUMM~^)&+&21hN|%qV`8ZT#(J z8yVC9F9Ihw^%!A-9>pW$#|w!v-(v;5Q5-dUzX+*mc7N*I7JYmF7RaTEm=D6e1>QVC zb!QX$HE3u2IV}fnz)(>1^&$Rbmf>|$B(?L4{2<3Fr5!Z5)^?iULlm})!>Gr{6d`F< zm+X{Nj`tf%x$br$ZIdEJix{u?NT(#P#oh*isF%yvKFv^k~p$iz+zi5o3wEn zrMRyyh^ydjzqC&5%IsVukb_5(tP!)ADpG_VrC2U@Q}{WaMI{qELL;n~i_BJV`}NAV z7Q$Bv70KU^m@~@b=TDHZmX^IHiGpz4H6nv${HVF@r>U)og0S-C5(@iex$EX$@C6yN z(fIn*iHuHM)0xY!h70Hh<>eJ*Id-3NWm2Fe%5CAz9<9mn6fGvQ76B$W8G|))Eb?{e&T}om*Df=_-}%-TkQePN@Qf!Jj-Ct>`GsDgBf8M@t7EHffthvwm&F9B6bEw{Bj)X`q03NhF1S}7E=A6XE~UE$GV zhpfOkb#`%pY-T>|*e}=I-b=x7j{tU+9ImV!7r*W4v`_kOO2ySH!DsUP7|(0m1Srf5 zrXvrp?D;hQW+{R84p8e9&-eiyufkH}kcdF6A>2PX<^R(Lr3kYvU=YaJB0 zf(U3`Y3|^qMRyT-y+)&u?^qBpQ|@-qzDXp&Ju>yGOk-opW?7<%5HU5mG`UYLFIffC z(j0cpOPw zSdLFZ%cU-dL!KG4u7T@E>{9iVmV2Lf?V~3t4Cg&f>Kbf|cYdfk6zOH^cC={PFwr~_ zoM)=CkDY1tUhY<^xCKI~XQ*6QYpm52C?XW=QWYgE9f`HWIY_&oT^f9iNbu*YwG3xq zUCOUTI(8wiboTB|w?ObJzRj?5Pg3t#uxzrCsR}$`2{w_zk}qYQ7ADAenf=M2NxU zb<)6Nq4tz;#+(#ec`Yp$!sZkK2KY2qC9$vL+|o6FM9#SzcS5`xxbjJUT0K-D=lV4; zzY^IFX@P0<^7PV}dzQWHEn}uUH`Thk&y`js4sOfrwJ+((mdx1Hv7~dz8@>4P5_TfP zTR`k75==?O3du+`FH@8seS3)-!?A|k|vrTh5WOP$ZJ)Y%@&MvSspynSx-9geH0;?NKGVTJ{v zd3)PdJh3QN86|wxuy@~_Vv}jKvC4~nUQZ^nc^+b)k$aKLs=4v>b=kev2Q61!dDCs* zWS*|>dEgRP7oP|(@oXPi^>fG}-N>!n?e1kofyM|2$VI3VdEH2Qgp{8!X2g0G^-7KP z?-0D#6OZWE@_B+FRGjvo&)hw+>C~p>zO-tm=R*5ds8uY4 zR)92%E!5|Md<1#XpL^)}&c)@+t9JUWob}its1<$6ZCwu2j@Qc8l!|Xz^}3oqQ8b2C zI(13&GcRWvWEw)Nni$mh4t#ydKHrWmhw+SM45%HyR8^mUM;L{|s zx>uK{=h&Z60+B5}Hbh6C&#Z_+IvU`|P}CL=LI1vU3#`rUyqlCsXW%*H{V{97_O#dX z{mn77@y7pKqqW=z)tJVWq;@K*fs2?lGreKOW%|vKyDZ&JGoKX8-EP8`wu58U%gk-J zSaTKNSU>K$4a_?v;`d3P5zf%z4UBP{Vc-qD|}A};%58m zq~4uJLe zKivd#L={F8y3YJo_vjox@XkwcZx>lZmPk==0a)9m5k`gj`*QMu72B7Yyv{2^Sqjp< zJ=BJ6)BtVf?Db@dd>;FWE|s%fAdy9r;fk&&4z2PKQ;gfLN2X?X*VwCFa>ldA`5|2r zYz2K-hX+Qec#=eJ6l(g@U~+?i?N2g372L)Eb9OLr`ZCR#@hyoM%xw4D7sO^oXt^l(90*OcHfWt1TE)5r%0u4dm`#7*J8?YsZ{5n_ zuGDXN5V3c?*nSHX-2|u;RRW4_l97G=U!UkCTXH}S;aNEL)4Xd%BI{k~{GHC<@AXU8 z=6#AO8=_O!WMSrbco5rmlQffWMyXi7DT5afukqq!F8b6qSXR2-lnh0<5q&c<$C7B7 z;{9{KV~A8Z`Ah-*{%#RbT6E-N$_PPH;<9P0=&_P=S?WHEi=6M29I)JOt@qM3YAhAS z!tGjSX$;IV_A{6}$o)2voDt}SC`s=&n}SDSkRo|qj1+ZFybdd^s{%j#pp}M{py!FE zWis{&;*p9qe3i9Ji};hS@0_`uEIHgWY%S}~8I_;+si|1UXwUUW(`{uG^-mK8!C7LF z)L_d_PlrG0pwkyd&rA^IJ2S`gmBtsQUBtkcptf>e7EDa6Dhfl21N>Z^hmC3W?J{xR zZa0PJlC5E#{e*%i^s6l&rWOb5YhSa{^1?xf+r{HwEcDDu zk=v-;0>=jVa*W-Dd2uDEkfpVrNa&MS`S18AP9Ii>z)qx2DJk#9nH$KnVA|9ey*#Es z@>hjHuDw6dvS1E10yM5Dq@-LF>)4x2P9rJsELk!65~@JvgL8~fe9t>2Oh4~HEqADX z;Hoy`>{Z(c6<}|ieDU^otxrCEf6Q%DK$OFvY5D#$6F?MWzu&7I(#iCm;p>31Zq%on zSWIPG2R(ZFN^J*dAx0?XX=Fdj1*&y@h3-(C%TFGoj74IFDb4^s>QPiu2nDhz)d6ss zI~+^8T1L8mL7TZg@0lgsdK!KG0i0#J4+Y zO6~a7MLC~&A0~ROTrhkzu-qei3!EVfT|270EHU>SDM>^vEggZAyr0#C0f)G!XHqC9 zwxe=4m!?nwx^mUgYO57CbFJqB5j+KVAjk40bE_VV%aBQppZO_bd+k!2kqzR=(r~dM zJ4utamhwj9Ha4}2Sh?rn5a>%KOPhuD>S*?D;8 z_IH`MD>mUsVb1I-g1U zt;*a4mXJDwFnQy|V+12=alAiMnb@Axw74G;jyl{}t9GJC;Tkp{M4$UWo^DvO^Z}nY zH+yzpQ(udeKA$Bac^vsb*k!vVn13gzqo)EjDX`SHuw%6AXyQ5W;2yz}gte1dLW-D~ef$)5fGT;;8D8_L4Lz$2BJ zyidfOt%mPMwO=s%CL+%&t&NL`TC9W&#%nu0Opl06x6pZ7O%U;bP@c(#;O$G(d(jpQ zVo*n?!SbamEwY=!T?hnX8PgLN6>p^#=Z!@!DkJF)V2h_b6)sE{>L00st@YSt_OCvh z$(|0@8Dm8qxOPi+5*herDI!i31t$m?f`<;OdU@j&gycW%z%j9K>82axdUr3eYxLuS zbSwo6^UW=Qf~ntf3#45XT)k=C#Bj#Aoc=Vo6Ig8k9rRMXkuW$WB(eXvASAq7aUt~R zESkE10Lpl&64OUJK_MFgSHOTPh@meP z2R>ybU0!116aIuo+EVgkGA^}xHBCWFqlRl}pZHAkQd05jvo2n=0@QksL9a&L9mDFU z0fjd!iZ_Y0AxRr>qKLH10wHg)lXjId633IlT=~8}*_a>l-rrcGGVZ>c&-2-%Sfq69 zWgSAF_Yw>_a7{?>(fde@RevgJ`6#hbn(7v4qmICZ>Y6WFvR3X}n9b;=>c9em_$pe- z7@Hpz^^FRumB7EgS0)H!)r)frJXCE)hCy}R14ic9)CHt8d{kyG!o2X}s(vDic4vWk zr;ifq@tI2H%)WKWEH9}S_#6nJk6x8Os%Ss~CzU9W{%Lo~G@o_N++%BAXEUk}~_oEq0o&z=%eefRNk zY#kuJ1@!O}eQyCSLc2-o*OfQW%I^%AN|Z2kzgf>5$ZVg=R7A3;yC!4}u5piu%&^%#U6q;ENW&`j<8J}xE_#(ki!Khw zR?hH4X)?%Cofp08Nq9~W#pG|rXw9q%CJ<}m)&Y%MK#OxWvYlEfh|q?5?atpLQ8zde zO>yrXu8qwUoM0XJd?2@F3x86ac~%I{6Ot5gFQ5cjP?l?P3Y#ytK&ni^Rh-XvIi|Z; z^oOk7{jsE4nPvLuJaf3U^f&PrVT_ZHBqwcMzIut>LTqS|+hH4?#>ep0;c58y9leM8X#6&AKB1^Fdh3HlmR}z!y|C?VmUtYF^PUkn zO;sN934vm$*;3NCvQO3a3%`>43ZbG(u(7>^(-9aD&~1Cw(H!Si$a-<%IEyhRo6SsR z46owvrC8)HncrB1JA6y!7<)-#P!p?}{E7UXZ29;v0xZVpO-gs8hceT@Vy>kU%}2Ct zfQyVQBJb?|H+1d8vMxVA>PMA7`66TG2KBM;^cVETdOV2|gX@_Y6{<%QbZ#lyZJ#MY zrln$1CQ2Z9Qx9(&$t{YE+FfJneWWg%7hgJ?xE>^->T<48+aK>?GFYhMgDF>#n6lRm z4MeAg_TpV!eZEnl^n#)1nWSYb4POQF3e1(NZfR$%U`2BVZ~nsAK%vQxa=?o77IHZk z&)6y#S)6lwE^FUeSeV%kNlSD0QeHD&ka?^tG|12_^pUy$F%L!A<~1aJ#D{ih*x;9m z^xDlm1B+&32{>G=PwZ&f-I)ICoh3O->fRFQ4Sp!z3Dn?3szPeK0%b!!^+bWpXTDX8 zZ`KZ7W%UqxVD3}csW&2ma`-H_e(zT%&(##T4F1G(rQ*eQAfh+}>$R9ng4NMVIO+zvcq-%e5E`EW4pEH3$PXwufir ze+*fEu)Z%|98jBLb^6gRTFGW}<*U#SfgnY9D?@P81BQ}!FqY5uLz?oC9~wjPm7!9n zvP_-j`5w2C)Yl|~3t1YJ$f!1oEBe*~r9xFQvz%o4xY(Cz3w7-PW%W!e^*4&*=lZEy ziI1H&ItO?r@`4KLR6ciinvy0^-^CVbDg8Qm9g ztsaL*vLNz^{1zyr9fS1<;jDeEz)RS@d$m4x3&dLAWQCYq8;l*Ewr*=euf9=2_Psqx zj|Gezy?XVJ8jIsc+S5;5&)W{a`@+ur{C*1MnL;X9Hj$q5QEMGva$R$+cB!XWSDyEC zbSZLlNfAq>X}j#ZC$P}f%_T_me7=h$8u^CrCQNFs?^UFow{+x@`0jn109xL~!>ejz zy@j->JYQ}vH&W3k=fl{V%|Wc!7%8}G{hw$k zs#dv*iJFt<9it74OkCMwUD{e-2h|wNA?RnJ?x=9s=cSMa8QZw}rLSb?wgR6t^!Z9f zVzu9QJ=^U|$+YJ!U7MhUp$T~xY?Vf2%_w|(kSEv2Zp)jMAC(=5;ld9Ueo=sI;?=KO}g>#dWBD8i&sRX*s#4QHDwVsDO_4eT2p3Ivv#pleW9}3C(p}C zG!h~#yq|@EMR^A0n-_KKa{JsfAPIFocy?%a_O@Q8xE7NS=HU84Q2RkY|qJMHLsy`k?L-V5N z&M;DA)15oqSznvPvLZ+`O?bPxH(y`yE0q#57b27 zw6kD8@}D=**`zqR1*EplR_Um^OTI6WD)&M~ZUMfygIbH+hpVXrLypV>UQEcIBkGL@ zt6q$&ROv|$R+ekjZlhzHKa}BP6>meAGt)d_%HZle0xl2&*_QYp5OcU1@wO-@Ax)$=IdJG@T)cLw`Z&h?NMFi3=(~T|OCbmvS|e*T#@9 z5#q)mwHJ!LYYIe(2ctS*9EH`Ju!%uZs-Bke9##*q-w7@de9p#Tx*e%el$d&dXJn=0 z5%Y4DuGzgKK1qitx23I{ki#f3(qE}XOe~J(sS(}k1NMYpG+g7-XZFBc#WOik5SoD` zQB*xXiA;nmM1_MsgwJ5P+wg-#hP*(Y#aY0eGmiJ8G@JlfU|NO-%p7*wOmq5Rl#GQD zZay<8fU6#dZklNg3Nnuzc4jUq>pSy4>14@kenrg1^3yriMP$&_2ekNI#6ua*+^m>QxKAzIAzcvj+LeLUox z?-2L?M{W@0~{PZB4T>p-*6x(~ z)D75Tir*@?oNG>S$Dp_P9fEL16yS39VrkLme3kvPi)%{$QH|TitHMqjerMBGP17JO z%MBKF1(fc3s?2~XxrEj?&Vi$q<|_EDu-m6-YF z<4$ivPWJcLH}Zz6>X;st#4kHBkGoIrUMEg;x>h7g*FDr);oW64A7;=((&RTljVyG; zw3CLhz#u4LnY#8#DXvdl$ZIFRv~cXH5RFkkMZY07iR|I@o(!ta>_G!}#nayvjmY#@ zp6|Ky&wPDcH2nT%hv8Ml3vgl_am-&2hTbXf#G^?!!N-UZQwAg8n64Bx<0^RwZ-6M{*It6ST55BGXEP1`!Aqr;W?O)BmT+i`y1ez(?dUM zSzEp{=Qdi{llbd_ir-r3&Tv2sZqF?s=azI#LVT?{x^Ze1r-do?K21tWw_Vj;Wh;ys zDO3OPuTYhb(rFF!V?AsB`4NHDXctdLZP=P<*JI4MN6PwhQL2{TsCWH#!>tT@B(p!E>XpKL+i; zk>P)mpT52xVb^wIgfzPuZvd2G+(JnQdsMutdkt2{*dQPiM1ZG(IaMwM_Dnhj468o~ zGcfZCfKz~f!=v%Jz_ctLIT%k!Mg9I5^t!t5K7(4K{sBFM0rU4eQGe)w`r;w|nM;7; z(L4v=C1eI|^ml;`SSSrLL7?LPM#mv=+Z<8|MgIWZf9nMT*k2t+&o8`SwfFj$ry z5FtOz`rBE+@6ZL?*dL$#c8=VCc_@@V5tO(__umEu+a-RyYuGbiNtJ1?2TV0cNuaes z>fyO+uAvAd9m0X!2yi$N;x!OQ9@`1ddk$#K!M4?jK;Qq%8ozPfx*C=LR;0bDGwS!^ z8i964{*BvaA=j(fLzPrv9UZ|{=JH9OPzsZ>gvi_Tb1(PC2++gU6 zg(9jewf)E71MRY#ytU1MUEcj0w%@gs)~&or{wBANkngn*aWN>9cj296SE`d1o$XlH z>!g@m_|JE2W66>2iLnB&>FY1Unp)W1Kh8k*E;+rreo}w2`gjqWSXQgWa_MdiookJVQO^CV40!;=SiBuKsDllS z<3!|)1_i~KL$UM~FDW7TKT>)3Kx=sSGWn>2MshuXgGK`NTHo|0(I|RM9e9;_A|OrQ zbQ#{%`ZoU6F_X^}Xu#bYR?vVTlFpoo+?jnnZd12o;s51pRl>VReO{(^3&35EC31_- zH2>5CUEDouvv8#j%Fch0bs63aeLD`)hN|j@^Xq7S7;6ab$ULkr@E44%pXoR&QwJ$H z9*e&0Z#%8s{Oum6SNs1_tEu~}3{2F3wZu;EzrF>Ci*Esh8~;`BJ=n%vq4utRx4>8T z-wwmAFZnOx&&K(6zL~kla-G2sE#y(biW>g}4C_AuvvQ_|lQZyW(`yCo zR_7WtEc&e4-wI`a>))?RmrC*^b9?;WUoi7uY{X89|0~3t9Kdj)GTKLw0y}`+n}3Lr zs>Q#yIQ^sdv+<{|o=1QIgWa4AdiMK2jIu7@{+H!6ax;x7|L_D;ae_YeO>I7_Ee6-H zIZ!seCD7R5CKdlh_P2pQOmi@HK$e8JK+1Sz6>RRrkXLUJ`b)p!q^Id-KwddMSb3Ei zOmKMMTI8ad66cPXF$Hb%a`V35{FM`;fJ zm*Yyl!Yiz>HuP!xYvnP%_^O=52iiojBjSFj)P)^>CrL?RXl$5UMKz!7tuK=Napqoe zigxY)>FdCLFqEDP{L_)4pGrE|4L8bxeJTKsLty79N)bv1dmFZ-dd}M)`6(+9!o<%M zx&9_q=14NqwwKPmc$$$FhlZh>=<%LwJM>$ZM`W5r3X)7>(VW;+wy*Nrf}_RogQ6)4G${zR5X2;0sL}K_a-wS^ z4;gJb$a#GV$h{a@fpTY#Q;fMBUDES$ZB4n*e=H_iEX`?-xIbJ2Mqn(1&y&n?^x?70 zFEOntiklI(-gaIebm&^{LEC@VK|D`Z+zeRPR$S~g7$`WFdYb7Qkm(x~wZ1S55*ds9 zGV)gicg4kxzbepShiDP3XCsP_GXMKxoVS!c3tqUeD;>7;yqiLiH+kOd@mGC5s*Y}F zpNG2GOr>&y7xbm>u3Kp=P8ob<#LX@;cxTr7Bx&`!(qfIMit>+q{}cUx*jFLc3Rp)- z_v$MXLi{j_E91In?#$lA%XT-xc{d!t8BlD7m_dvAlkrSNE1u&l1sw^q9XM62 zs$Aq!OThmwoxL(#Te^qkq;$mws&G%{w+f$+c-RhJeq4>En5)CBV=)yV_X%>NfMyp# z-~Hbfwtym`Ly?FnDFmZCE~sM98Z~~gTq{RrZ&1H8^FcUkHiVl-BPZCt{emj`tPWAC z7?XhCm5Zuv{___HdFUoeDdGFMu^ow({T z>@oaDt^ZG@pwdOqw=2Juo^!`_N68I#;4?s2S_a_<(B}y2AxwfOWik5J(LnL&zaIVx zS}-^xUV(Dm#fd#&1J`A$9ZcuaNRu7hczNvfD+3)1N37JK|wFF#T=b%>~al zbidx?Q02kW19CiE)*B4cbBmC?th`dgrK$lAGZ|I3&ril19<6KSdj~7kZH^LYry2^g z=452?X?qcgv~EXyV!R&tX12^0*O$s7s`B}SC@v4%F9`ekxlH$jG2X_;spGi6Tcm*X z8+mF98yA@>?CJMtiMjWk=i4!8{3`Oz48a}<#6Fh({)dHQmOsXKSm3{AwG3Zt8CYA) z#bYo|oT#Js&3+Od z{9^pmx5^zVzY*mmI`mnbqbF=Hzu)7Y8c$h~lyRwmG@P6Ejix8v$*KyA@$+?v$9A2k zR>pT|)^ah9ftU0(McLVlCGDNlpfh5~`?PWw*Sj*(8i5X^N>P40YSkAa{E5 zSyPL>@D7!Z#`kkWOmYnUBQ}reJN1{1=Di~`Zwq)-<6=}Vi;@cX+EHNIVoLC;j7=2E zrM0pL>oXJn2J553QuW1E&TE>+mJc7xJ1-Ln^D zR#!RY0v8xt3!rI42~F|pemuCCDa$YAcwu9{Q2f-nR@FSF z$O-;K#n`AlD(*b%Xz4C&$kt@q7RB*Gw(hMwV?*(A=mwe0K>G>PFfp5DFufKo31@^Feu9ER-*UiuCZh?lo-}(t<%CSmU)b-_^(H|t` zH?|Aqv9M?~mtwD2`jWn;e{C6lKo(!PHnF$ zi0dK?ofShK+Ww`QCnN8t+AjDn&>j^&Y61mLZ_y6n{FFp%>pQ{HV;+n)=P8u-Iaje2 zmG2Ys?hq~Ki{kgmA#E9kq}rv%k9@6G+HmD4nP9R!BzCKX$+D^|tK6~8zhg?2N5Dt9 zNECaZH8p#*M8N&s+4lzWn1k{W<4XYHGPIdhW&7eWS7LEQyxoymKn(cPUNh zm-2p5X0+@*73ck?Tc9KG!Jx2LVVps3tkKMJcOZzDcm&3bo_CDQshD-vM%an}O-nxvSQcp3Q1jdg15VngHEGqxa0$|j zEp2wRN1NK$%laqE&TD%HYkrU$bux^dB8lQ<|B8fyp`LgPP?XFa5p{3+QWVniQn5ea zyy4gIo(3O;Qj5EO&Uz5jxLW#^wVqX_mY<(Tp>gaBf3MLBgD3$}Gm3w9n=dIdt?h)@ zjZKH>qlWaSWBm~&EP8QfMZr3WdCiB&6pC=WJbxUicA=+d+Pnr=4i!GbD%8b*LssDT zEA|JEKwhouERo~rV5!l+N<(5rPoL&pCg-YdHOi`IWW?slGs0~gxvdjf?6MvLB>brO zJ?B^0uctXKT@Lgn0$)%HES7NW=_&V#YwB^0)$U*p!DYtmL^t>}UTyf2PSO$2;%wJg zykrc&eE6M}0J&u?l$IT`{2iXMeiv&UHOwtkC{yz&F5IEgI_1%&@F=T_qBdI0&I`F> zHA~m26q&d2D~4<$oApo(WJ!O*XRm8s4i(Hbv*l(y7E7Y=mUwUr1m&7jca!g3-$4W_ z9frK(e}pdB2>(R#1(wOND2^&#-8#61?XpsFy8J$MBmav=TDb!EQHOl1taBXElbG5S zneMDJ35xHSZIJos-rhaH79Q`7hxUX;!G46(Bg}P=S{nRs)ZB2}U6SpXSV35y)VYPQ z2zxGPOF=X?XEgSHTAx=zWs+>YM0zF< z_uyVyjYEbVUy@(dSS*ktPKXglk&0)5N&5)g2s=3CTt}&ccBLKf?1$c!x}tYdR6Z&m z9bFE&8QoDWrk zN}8a5RuLEL-Y)XUbPap2L38ucVzW~Xb0S@htZYJx}cL*k{x72NZ7?cXzt1>cB%ga^9 z)g`3LT*N5F#l?!p%t2|aA$rOj z+=E8a(d$P-W@<(Ic7l<#pANWRVyTxX?H}dzeDfStO3t4ki@R5HSEbK+-xqgZ8e({1 zzwaxUUUufOkukn^etGh(nS;D$Ts)ysCZ#YxYFYGfvLu7)!Lcni~|1-$FWx7!$iEA>R?$@>=M$xHyG#< z*g)Ix;ES4LHZt83-L=R=lj!Jame?+KN}a;I6|BpZGNuS_wa`$%?pr`&WXTnEc2x^^oHiw9A6ZYtGLnH~Nx=og6e;OR+ae_vEvw~a z$7MGM3SXc_%gXiijxdrJlB+lz_WpX;%Yvn#57+9;SE=(zQMQjebV_UNNko2dlt9e9 zvPLs;bnFmk>zPF1=BRtb&my+nHkDBt$f%yiM>MSF**90aXNyiQ`zi5-n`KiI_q{{u?*{D=O9^IeydYpl6ub~g90@unx+ z%Z(eK?6t@8P??#_WJr-7gfFlaS9h zDvv5JKte5~$Sfwlmt^Vr=IideH!DBKQ{`&czeCaP&0xtz4P@Uo-h0DC$nCNNqrUZpH z!48Qc6V6yB%IxIqyaoJRaxQ7_S*a}IM`|JQ$T2u#qEO8@w}6IIlfLt)zRq}AY0m_c zlY8z{#Sf`-ml`KP$ZD0Vmf-L z2@Napm&$8-S`Jg1Y38=ubK4F|7FtAN17Uc5ktRJMM(Vm`Usz560p5pQOKS6WMY@9b zmBtFDZGlt8x~}txr30nj7&Z0d=~&jBlkvHz^M%7IE%Q6JChe~x;bOOz5t@0XOoKXR z)tZ$W5DiHp75CpUg4Grhparq$g`#zg5u1aYnbY`a^VLM`aUu$#FnE~b{$SW&<_})m zp|68G%#x0Y_NH9GHu3>DSEZ1=;vgY&|7PBYk|`Pslh!{R#Ce1j8V{eapg+LEa`LSgm<|0`=4 z>aWV&8I}P2)e1Nq?8XKDtN({*&26igkrN+=tHz_y@cS4?1C!4v626K#Gzy!GeXo+)`n6`NtC zhW>AZ*y+vdpvH!gp3|AOw(uA7ui&TkMe_HEq!qaEGYl-@0%V-QFC{7z(E)}hjMZdb+ivLG*B&;TWf%LLlZ16ivYx1Q2bhk79of(|tnVD`0RE9zE5u}_VQw}sj<`wl#$P#nwube|Jr>X3riu^cT5PJYSrD5|CIk~`M zf0+*K>uit(ZCUtfdpjmAk$Me@O6#FkGo^J?825?o>Mkt!2e_K)48FzU=6*WRwJ7Z3 zuD%L)bCDVL5Af#;?!nPrz0=Co8{CYEKWp*ZXreE{+u$gG(kCwy>U%ncV2p z9eG7iFl$#~c5#N)&1?E$J!6uq)rD9y8+0byQ#bw{=_C{I=k9j{TePz3`Z9$fzU_z)`zrp>%F$lyzgP>!nWY`hD zlx5^h^8<03Rt=10qKRmnNe~{{-yPRw90wQ2wT7m`^Yv%) z*GwBYbAssqwzk}T!_SbFKTo%J+CFQAXOC@_PcjxllVp2Sey^C$pp|{}T!9RX3(FdYksX#02QU%ciyhxX{z8*^?!gi;-cWumf&mX8@WHSQ*p|T7m=Qm z@Pqx;5)BDn2$UPSuOl*PfH9z>3NOX|+Z+mw5x^W9kv54sKcvj^QWjBdvl;}G#OB?< zVj8Kd*4$6sulhLkc`6esLc;7p5EizuMrZIM+qmNe`0%gmtBijDCn23491F5|t(;$G z?uogo*sU~3I;5$)@4KARn3yzG1Oco*_ygduq^tcobQJUnI25x0%QuE|TMVhR4z$bI z$M*;uc*O|+Zj--l+gllZFJIs$tl$+Q%EY>HeZ{aW1{%0HeTM(FjcsWve=Ge;OzAxT z3ssNPz=bF8rR`lDRr?iX*)vzxq+`{S+cnIoxUtX7y(izttq1?3*>S`+A>Ig%2D8Nx z)m1eAzjQRhrpD@(_SqAgpwwr$JsB}Aydmgzy9>9E#C%-6BXsl)E|sfTvahjTAI&~w z{HyvHcTp>dN5pvlsrv^2iBsPEaKD@SDK@_{9)S;)xf?hQ>kp#-UHNw=>006yVB?cT zkDBuhym#@>UP9yJTh_(SadhLfjl&pne>(bE4;<#03QdM)D@UDB^#*FUMm%5^1Vu@* zE6}PcFznyHo}&>ORrNMRS#$+@;F7%VQUWADxjA*MX;D-2h{=BFmeZ=1zkBM=cQG4r z+wuz0%tzP3h&I?e;&}sw8B&k7_7-djfDw4$51UkqRD^6Bo_EgmZC$t5`A0Wlu3~@v z7Kx{RkaxKGlD9e-T-EP0nf54`!FOgSAtIvKl^wF#Pfo47%QYs_zMLhdsY)$&4rjgt zJo6@8=%g8?uflj2;Q2OQuntPmvB`*+m zlYRJ8+X}5QEEEg%ku}UA`TXUE8l=M8mbB<`zV~8T*#KQx!Y5RjN#>ejXVspUmIm>Q zQ46Yg%NojJvG+;_K4b9=wcsyQ=Xikl1FIdG`iaWsT1b9}zI;yx4b#v#?wOj{ypZRh zn|9e7{e!wV6raTzH&{_h+b)=azwG!h|)Jm!buKD@^;U=}% ztx?Ctv+O`=HqDHe;z4iJrD0B7%}gc=dMvyMn!LNuGXnkdKcUje1*e6vt4wXpynweH zESJ$T-X7%nFx6DcM{+B>(!r+Fz5^4{q(Itic}?jnyU^``qC{Gw$C@3=`QEZ8bS9H+c%cEgl4$vlKJ~`iRu-%++W} zL>qiN=}4G=O!f`PSH9&ENab{sTZ(|Od)ykJ?!EFckm7t1Iks*-O%`51GU{j4>=3F* zreFpll$gyq`JQvLF8-(H!lM^LB{k~zej=}kfjJ=F021h)p#JJ2q53)*_3QW+dkdP* zo-s0cfgHp-c+4k{7SM^ur-+A_1E^6C9(c2aeiqHVAOD*y zmZb%kd}3!L-j+aHJ@v5s_kCNy#V=GwpX=%m1K~|H*hwfcshgaC%L3|aDbt|KzTBKg z=6+*(hpy;TKNlbItsV|W#qfiQJ z!Yc(97diS{H<|lB;IZPOGJ+~8#i*Z+J>R1&X_@fKEq&~Ud3B|)Qgh(90MbgfZ6Pyn z16N7ulf4_=Krid}qSo6Ht{DV{g_ATJgpp3~Q%_3vu}WM_Dv6@svbA|~=Lv86xI?!TTPHRxKsA;juG@2>Aem~a?6^Zdm`k7|4nOvE- z($R*ku#~~M^zy@3C&Olynix`Y`Y;=7ZVe+5|DC9FY5(e(_Oz*o#q*<>4Poa+{rnJ(Z!Z9^?TvqYEAp$$TGS}r!`x6E84Ir76MyxWXsvt5WTYty{ zgDOU%6yE->%g=c=@Nvks#xzJ_>qW!c)qq)r5K|A^!m>zvRGw~{WA6!I>rf4dF+~fXX=T+c?ESn;aS)EBKWbD ziuNA9IhA|9Kf^`}r3%;CjJqz+!=@Aqvev-d-_Ej-j!0C%vsaml;mXZb6(>v@_UK7((|46e5?&$KsbR{ z;U#RP-|Da9I0wNsslvaZ5Fdh^e0BUvW{>8os%og3Jhe{m4uj&DqRuNLA718-u>6D} z;rVQskGqj@!jG|Z_`92>$;@=FyJ#5nRo6~2=p8@lW+>wMad`081&#V~E#Q^iO!g14 z$F{Ap9WV9eRllJ^{(v*@3GCiHB@!S!mg;Axu#0sBr(3;CE$@_qE9PY9H||z0A5NsR zhu0tf(C`p3C;LWH@L)C1KjUy9u3LO=@>+Sf*BtabS{&ekiHpZ>?C%$EOHj1 z+n(JOAK_aYZ!m&Gnrst_3T@lmDg`xW`$W8TT5p5pdn<&U=4_C>`oUF(7bm(%-=R%rQ6i-s?!cWcu?YISyLVuZ8IX)gGx&w zBr$*%-Lqk)^1nDGPy5waC(s6xO{@W?+kEYe1{ML8Y@-cYjgW=!_V}TH=1i^$je=VC zx6uybm-I;K_d&*R|0nq#Seq@ueS>`zlEHd_Q9y}N5e!YG6W||^k{Yv~_+vihf28d} z9bt++=&y7(U~A5_9c;B3w4IjNYzBi7itIVAIm`-l8f{CRV0gA!nW;913(g&>1TnG| zjUOhCX`ktd+9QmoPz^RvDrFDNd9b>1Ao2^vz} zR0Qx^9f~ZWpB^Q_dO)UR8Rr&$W3Tj|BkGM;1}Tm6SH~!P%1$*l%FIu%rVqP@_B)q& z#IJ7qeug8bMZg&_eg^?v>a7Ysu5v))jEm$p?Fz;9{`h>*rzwvkH+rtT9P{LcoiZ)x z`!WBgy|rZyNbaeE&6HH}`p|oX1+g~Fo%D~2O~fPeJjpg&ko@P93@}?msYoU6No)iM z8Of?2_R{L!d%FcC^dZ??^#bki5Ny+_O?K+ib5G^-7C-r^M+m|_hXCO_!XvZ%d!cB- z>sRS7xOA?(s7U1Nsz3$|p$DDxZz2}oahBH7 za?Ip{F6Ao43yWnAxcB#~j+tL2Mml2s*}rzuc^&1M{Hwmi(IvRS#>hQ!jYSZF3azZv#e!W z2hNeVgJswh11M|DQ@@n?&1{e6G|H59Kcy(f8|L$~xCQ|&FOuTHWTVnoeuj=@G3h_^ z)v;T1LgA%Er(05zKn=OvPR95nV+-uXxrsjrWtV)xS1wZE5Uf(jpYq`H{y@sZU*S8v z1XIZe0ORrhFktIlk^SE$;eP;_ma-+VP}$Gh`}IFSp}uSK-p|qm*ENCithY$hq=4xL z>C55;k-B1$&bn$93vDva08{@wRCxBY zXEG%m$*)PIh9}7=3m`$_DX|_6A16%H+plr|1AIXK1N;L71M|;lSmSUiNHTq#m1Z~O zDg$RgwFBigwB&wr*lKwWclcGlH%gIKbI{qVo#l}BDTYDso_asTR}LBILS*ZM(}u3C zK<*q&ZV8fnH|q7gBgz)s15P8eU4=LXfjx-&oCy4$-->@3Iv&mgM&9`+9PPgK`5!Lv ze~82Jf~&%hO9{XBb&iK`nK*n;aWT1Px7Np&IHXv9ic{8+NG0ItLw0rCh2TGNbF&sM zwEBDad2IK8;PL-}h-}@sREF1GzSY~`Zh_X#@*f^k5KOTdIo17m_Q!7Ye*`OxyL)_K z@7c9~02in8>n5Qq)#7hvaT6E;v|wh8---}lD=LDB`z>2U?Aus-*`BFtLe0Ui>GJkN z!tFQ%TYJ^j$v*({lS=Cu^_M!kEJV9-77_VHmT>Jf7&%hAs01MkaaHEzdhlW8iIgZk zyh*1BxS!XI8Tn2-WEY_^n8Nc)tU%guo8Ll`J@(<35a965J^J*!F21f)&aNAE`R)(C z!3W2m{sEL^{sHPrS^}1W~zW3y_ za5fN~4k53`=H=M`1JDnY$gJ+{JTk1We3R1FxaU0K%~(o1-ey{kLlb_1POcdK3#yHB zWd}1U@CSWcW`GFgCO+~U)C%;PdI2dc^)v%JtvmU}Z*hxEo?z1WO_v<3UxL9O0q=GYpE57jqFJFxk)ncq+C==JA+=UlY`!_gQJ=TXl@7X9 zRILJzlmDlD?LPFyIHW>NGBX3AW!Ar{UHD(IXgKG*&B(radI&x%uSe-QYx)(c2F${Q zK>`M;ZYI_!Zq{SOss=y%TTrv?Z>xJeZ7n90)R{E(kDaEoKBJe6C-EDkL^Au8Y}A43 zwtV0LU0gzK?1rrJhuXMWgY#l!vfq2%Hts5tZ2{q_z6I(sYj(*62S6d1mz~Q#X{8Bc z*yNzOAUAiKb1^I)6^> zl7>%KkIvIIW*+MJZDB7p2qDsQ9%9BqIebVeh#VW=t`~PLxN)3(zO3Pz+wF1kTuPWA z7jCwGSAkGU(fIa?nc4M+-;kLV2D>X`h|Q{m;eIeS70uqX&0`6E>_BRRj}m+Zup&SN zzMUlZ`c6-`75DaYv^AgQL$p0i;7UP@M8SR-toslfc0>)) zVZ)>1X>)ivT$cT}d=_&~{${K8Al)(3LKU2MQcL3&IjD)Ar%FWR_Yf(Ze^d_kIum%) zSXu4`m(E(wopOr4jPW#ut;Pu~7A^ z6YoIP2wsuYSz8|LQ*7Rkh;~F;N~nTPjw&7}L6=W-J9EE;z5x-4-BiB=M}d22{`ukc z?OKI5{k(9+uh(14QsOWO*5PU}WaODq4^2#Af3Sh#Wa%eVmp0Q_YK&QgEM=M5 ztjye63>pr%NC-Q(H>4RTLIby>zVK^YuDW)I2-5plGN(V6rAnt=^WS7VQ~9e-@rw?zpq^ zzL#>U!yGVEzpT*#{R4yvDabV^P*z;cbv~Z&%W697FAR`@wVntB81BN-(odio&H~5! zV`|J7A#DEuL|n*Si^G(#yGy7q+wEACw$~fHKfJ}8_Vn8CVz2y@<*PU?I$>kKPOnx< z_0La0-k()7vMC`Yaq6OQ#`r|g7B^a2N1d7a*)yLpEmx;~)k25mf;iQt_sL@A{Sep7 zFzLrSc?$YP3S5pl<6m>z+Y7W)q#RDyr`?R8B%r)t)mHi(Xi zd|2_-kkj-bvS0)x27W*OWHMn92iNxZtF1aT`<`Wha`3uAp83H_Z$@gf0vc0W(Mma_ ziX>qRvl{@RAX0Umr8`V$V(?;&3okRX-0sGQ0k-e=XHJE<<~rFW0#`RumX=M8I51R*q*m6{kW}zaq*d$}T?W~mihXoBaBWPlo&tu|h&#FBZOcH~p8xGP1!$&Q?=z2k6 zISis?U?t^fN^y-V1f{O9jww+9Md>r#H5-;@pRBz20!=TT@J!n(o#LT=YzKvaEe0%% zWVrcll0))bS>&q5os}(?OUjKZ0~K3YiW^sx&CWLpYSLT5HB9ep{4r90qwpsWg93ON z#;ej~DW`w#GsKMlsQS%srqo*XDdw}yn0cJJ*fx@Sv3=cknEO7Ej9WujSE?WMob^QU z=y0{cr1sPun%%J}7CetCO>GTS`iSu*#=#%WZ=TcjdEvgcYNh2LekWM3n<1|u*aN2V zyoH=pl(1fAx!kn20k|f|rJj+SMdQQ>D*a&xuxY=oU@0tUojN=RaB%}Q z##cn-xNsZb)7RQBDBfJv9+ApWcOH_qj->RIeM3vz;#2(3> zKPfn&-!AjBjTu9}!Eje4{w_$ABq`rlZ5 zRo8py=!WkvTfO5&84$0)0Jv%EW-afxkX$^ZvS&9%6tKNMKDv-+-f1_16ug^S?s8nu zM|xasb}(MY%pgTFXEShAUih;eelo(l2f&5bjUMRNPf5$Wf)Am*FNjSGTKKswPTr(T zXT8ylVCP5`tS!0uDy!5=VPGKQ8Zz$8b6UB_GhX$nT;o8XSX*}wL0YUmNVStTn>R#F zjZ^3a)P=Zz;|jFm6F)m%34hQw@9d?&IA!nrwWJw$EWcKZHmD&0!WFwai+tF_;?+k{Ttv;zs4)Yqjw#4U1aRrf4B$CiYCoFFP2xh+=aBihE%*9k7|!sm=FH7~io) z{nKrOzT)x5`A1k=#h0AJq#LC))H>T(kA`lgX3S{8D-f#*SAfBdRiAmr6Fo4g%D% z0ulzmlr{_ZDb>3;l{U-Qnu9j2c_?uMH-jq0FJmAIg>@V>#XtTBnBAhk3-`u_yW)m5 zeDXb9UgN&R?SG{X)J!@wfp4eDsVA6hzn9QEZV^|Ub@yc_YjFTgv-KeuI4FJWbcR>snJU={Z zbIa+-4NGP-(1Y5;K<${fv4XbSpR6M2Sm#DwQL9V!)QxY(B>i}FB=N99rat*|1EpaZ zU3uUotb8cRlu`4wzr)L-RBnDfoJ`xueZ=goEH4YYRZ_?^neP8rKimJO@Rxj7VaOwv zIhAiy69N311PaPt*`2{pOyY*Z1r5%sa<~ zNuI~We;?MYf)vl}4nSd)j~rLt{qTx2JA6#>Jue;+F5k!bhN-YkP_eP9oO-JXgP8IY z*&CNIaGk<9(WkBQ@50|QNbWFy_&p-L5V}H2onU^e!W>xq+|ummNB`1c9K+O-M~Rsy@vrsNX&SMz zWK^BV&mM5Jv*bX#+PoDJK`+)%+Pyy0Y*b>p%c4xmO^OTSuBi;>BlnF^w0whIsh)Uv z63HSbCgVlQh`ruqcE89pzmd8=8onyZn%}naCG2}fX=T%U0VS+#q961XkcF3Dr&ZPWvYUn`Pjtak7bNW; zNUgZ_bjUt-Lq70tPC|~c*LuSpc7}YequK)q2b;#+LNcW@O;XrLh_?_wbos$CZUJ?% zxX43JAJ{wM$Y1zBI~+_`=jph?=pp$hhES2<0R2y7cna}VfOT2bZLwf&NBE{Z@|*@> zN>(<>{aDFvcolV8Yk{|zoQHa9!zy*z{b;mNn2JSUN&7_p%@3oFL7ki=bXCzt15XzC zzI7jai0+!y&_FLXo+Gt%2w13(p!rrc&UUsx$Wc3`$8xiK;gGH!fA1VDU7e znfrgpCOfKjHM;XrUQxhhjz|2>rPP>fybQs}OOI+=!4+K$)WFo@P!o4v zKAkGRC+0<~3@_kdM~L{Sf4cX3cB$jGy3ugMXy$r3cJmNe)=M3z{zeOx`plsCLww&DyX|;mpI}s;oGWw&6SH-Cntg2kCyTLpQa^(oG~=%9HD|xst*| zfnR~fU%x0}KE=v$2gQ1RJx!CwzY3kq108)}7?|SL6kn;3U-uU<(`E|Z-D%+7OOnjA zf7Fwue*m)Xeg?%I5w2l0=(zcz_%s381mpn8#3iWna~MEe=2cM4!?QWa& zvZ!FSX{wz_MA=MLFTZe^$t5^W#IjE8V+jMF*?Y|+!CIt1^C~j~v=Lq5Jsb70c;sEs zZkg6>B|n*2L%%H&h2`4Ifx{c;+xvf4c(k_PjE@06-_|>cV3&wq?zLld0;{kwmH>-F1m<~!-_4DSuaFTh>u*J+hSOiK&#B`r8NC&j_Xnj zpC&BY4~zQRB$NxQz#1@H@?Hb<2(X4{A~QM?k*<@7qH;^m=^h~10;qSgn#oOpiYJ{- zEzT?or_5W}lKu2NzBYFz@KX?ZdZOgY$KS}fKX}yjgAQ)^-E3BS*ByF{y~!Y-1-HiV{&?D}@$nb@ciip>#&W0(WJ`2=k z*j4r3uOvI-Vhe@Ube+bKIq(Db?<=`HEBr>1|2m@XXXqB9u93#ZBKdf{ga2hyNg1Ws z4`BINfYVJE_T!LSdWkJCStp{ZSMYyS7}RMAz4M=qAzkVVv|%zx^O^zB(27{Y?N73?i#AXKWTP!m`|Kf&{Upod&r9ZRKrh~Umuvx7QJyWtEA7uN(RiBof3UHgS9S zi_+=be?~52(M^QbdwVfYunPh|*~YzxJt?B!z(L;urswnCN2vL@;P2;HwT53({_zQ1 zt#6a7>%S$NZkp|SYUsLGBh#i7_?h2E9p|xUQ%sZ3ziwQbeq%m!C=HF%bjv$1e)F!o$Dp?zDLKliQCGT#bU>bf z*18oQ3;X!}@QP(LaIx|BWy~oS@qj1epbW~aX<=e)<^ZtTV9&1-Du%ZO{jY?>1-JTELrNncf{qa=aFCU%`2zWQ zVtQO&1R)mDXA zl5j{dTq>=!Bv39H&3{eh2wYCrZqh~Mlr}*eTK(fI9XxRhHxBI&A=K^(uVYQgtJm`D z%HT$so@Qw|2MOxhqB49Zo=p}CX5b+Mmm*r}5Xr+txrfhxQN9$5w5XVqF*bb+F2&Ia zIW|C_A?wWufZws`ujHfyfPUIyJLrX(Mg4q!rB}l^96U*gZBEPeU6H3Av$hEdAy&We z-63Rs{>T_-TBW+>UKB@Z?j9Dy7LN@*)I0wH>c?w`Uh!MA3#2p~j`>{pGMxR)ImoNq z-=1tRS!#vbuIE0p6)Cqa*?g%iG|C0EB1IrHfY6Uh&Ha*JqP^Yb>CpZUCto`0J9*4y zvHZ=8OmvGvwkD2Sl?y0Y5lX1rdOu0a<!XJ{zb7=rB76M82WZk zOgypRw=)_&4DC7%W`lf(JqGkNI-`8qE=f6?*tX~ww%GES;+Q_G?_NO@UT`%@rzE_y zhST9Kh7^!6vb4Qn7A!vMa+z6LDq-Rf@X_C@NCP6oQlD*xNvRa&D|5*cvwCf!@KIosHz$tupL$-z?! z%%6oCi8euUX?YBDceWGe<$(?3b)>e122ATkl`izbB@3oeCFQlJCSkhiPD-V^jcLfV zt7r$4fsTHkC|tha@9w!<;(_M!lmnj9#U;7a7vf)DL`Ew|JJT)O;qXER_NU}>lNFsXW^zX$ctMgjbYrNq{rVRzmQ&Z z^6*NpL~oxt40|OTwQ->ym84B(WfU|{UeO|QR*|gTR6$%B1cz(-PdDSwcSYixX-ga$ zyr%SjqzqRuv*{%r&{xU4r18<$YLV(Fd$7?*&xSV4)dK(wFrEknmKNTqj->yKP^S2a zGr3Ow2dlC7hk^-}$=l?Y>J$ExBKI8Ue|Z>foGquioX~C<^wBExUcLJdKRz6tOoKD2 z{+CII>r(c@X^?TC8kcv2t6})xZO5OuNB_U@gWWqqzP5L_*Z&X3ruh$J|8T)ot~Gh) zbw_>@cdmDoQLX%sUmjNjtBu-lSg5VK1yu!`vztXORb~Hznx4*q;&{#8Tvv~FI1g)$ z4|BHwu7%F{Fn#5v55y|`(d}|46yeg;hVjUFQkGgpNiOCGu}Q})}vvk^b;5`pXw5HE^ zRt`XiGXvZJMqR@sETF2HUC()iOX;?^Fxm!g-AWd_xJ|GIhurT?fEweVRHS_WcMC(1 z0MsyocwbpSm!T(s=4T;{Fa2vu!M>(b~QNZk}YbRKI<-VY5rj=8Eb~+iCZ#VnRZZ$ zU2cjmq#h+WlZK#0B6GNvu?ev{qdr|uedQPAiAd@q`9*I4Gr}ccEpLPU#$TBc-R6qD zo!Jxh-dkJq`I7s(} z^BZgO1C^q<<;MQ>tDy-JQlN{yN76@T@s(f#07fN;0xt-l8AbZB$6)a10vD&z5@&IZ>cd6wR10AX$s)E4Bet&byJ`Z zVk%DIg+rM^hqRlX_8{k&H>NKnhZ{^lKyp0rcAd2On%>=Smb=t6P#F3qTUaF>UHO6- zitU6kdx9^Z#b55LkNJoFj=;EWNpg^V;pEKsR12Y1C*UQ#)hlAuV<%40k=xftRJgeK z?j-NUvr{@3F@f9<#)>D!8b^Z^vpQ@csEBc?ty zQf}y)^XCZs@Iqd;08YYq3o4jP)9T5(&xPcz;kvpYX3!owB+>9T;NzcaIuHyT zkHqqyI?lh659rq8LWY7yZgUF=$KSK^F8F@8=rYN&@PRsAz^2H2)3VGfL8y8ZJ#Do| zI<;#ArA{Naae%c~zI49ewbz9&|0cIV8eJ$J=+lp%a?RJlAC4T}vsfT$ z1f9Rkc(LvoIsvNU`o-C=>flW08Cu4yeqH)OP}>)bn{wfWPtUlJ-2765vPtLNj}qR# z7tF72bHl(=Bl%?nRWZ=A=rkwS0&J-uN1p%(P?v#fDYRIV(>OiQ1L)kvYFSb9S!^09uz zD^j=unv8izYMd4Qp;n&aHfUkFL*G+Cul&)-)+4B@lSMx_Z(iUeni^jnoJHEr3Hq{5 zZ|l?Z>r34v*Uu2Owcr+tAo^-=HTUF%94nvRU%g#5b83WdX;W|h0nSSRPO^%Pq7^b3 zQ)XT}ldW-G+}vOkP}RBx)1X<}YQaU7f(*qsOwh5E6Fc%4n&G3HPi@f8GfSo&L?i9| zETI!B> zBX7?W;wL zUxLsTmXngk%@g>P(Bo}bCXk1X?;Za@6rRPHXgmN^IPqHpXg518cA99cTLN$$UzHUN zRb;0Y{jkrG#mZ_*9OrghGnmoxa-wW!>7Lpo`!H!$XRWks`{^b%o)qH%5|72l%`xBT z9OZ85nX8%8wCuE+n39@G+k$F^mZa4dRUx?^gh~Q#gFckanmEY+u)7TuIrJ@BD$VOm znxgx80J`3pp_hNSG`pWRBRDLCE_wR>(P2=bgrLM}3MP;g{8%Y@k{}we1s?O+h|)Oh zqGcI^Z4H1Y%Zn^0X+QPDW0)^fODdZ*X&~I`__V0RRKn&W3QEp)ycM6Pn890{uIwxx zt0(ht1xdf(T0^P|#;oY$3^(ulowual4~{<Pmpd5Ku211#}Pj1hw<5RCW zF9X3kMo^zG3I+XskUTi4~eN1ei+b*bd&3f;d9)*9Os^v)~^!oOP=-(MA}`dhHcRk z^R{m30qYm(Sj0Y=0`KR)zhk95bPnHp(8Y|UqcD*_{ccVx1z(8Khea!zu{YC98i4&0 ztfVdngx#{6r{ObNx+O1Ol!+KSH(qhYiEC?llKA<>gy!h+Ei{^~wE@S;zB z?Z%{U+JvlRQO>gPN)pyBmF^pcj=QC_&QsxJ>E3uMYD)R{1Q$^jz}BZfSvP0c2BdHt z5O;p<(~Y;ef`>F3lj=IxbIGfJ#&u+=?(IBh@QMGGuiw~YYbrsUUKG1I?NoY$9GHZD z%D}t#z7m9o%k0ntY$hc@eiMGJkK=C@({%Pq%dm6?gI*PB3TC3YE%Yn-!LDEyAQb8v zfwzF|>H+;BUWhMpve&@nGG~opZDG_e()M+LK@N`MC5hN*c3N(ga-aqQ!#ZgDdxPcv z%xK5FX|6AicI&8<#cYW_-<+~aq*2mjs#{Vx@o>lj24I5 zw?mB@3Qb6L8Tc8x|Mod_9zA3sU99?`?GTiY6^iyNKhu!vZVgY?7M++(Q3q-wcanD1 z-lceGzMqG$^ICzO{9oskH~AQ`1*Jb*qId_^_=tLB`mT^nX$;pgB0wU~oXmLC)VreC zxKTi3nvG6a{573bHaLhJ(`meB)sN9N*#+YQkdhESM^Sjr3zofS!|rKfGX)M`?ZUV< z(@Lvy)_M0S>i5%9P%wV58GEdtY$`s)U&S76`aF2wtL}55(HTsS{=vx2G>BpZk}~XD zL6pi`zqvu4<4VoC)U;K3ZB<+H6eN+{G^>?e3PkRskp?HIt;Q5SA|kH0_ZSGNDSSBr zs#(re>5ZB1ADiyM>vSvz1VN&DeZ6Gn&8~L^wYsSUv8@V>X9F_?;G?kZgV!AT#zbj5 z?Fs^A?GdK!Kqpxp2pPsK#A3-Ln9AW}i(yAI$HsG?f`iUYUB(94u zbN;&hD%O|Kd%H|ejA~MMvWqsfgS_6|Gkhk^{Js=H3sDD|Zv(3h8-zB#kN&dsE4FXq zgPq^5>E$G!f4rI-&sujw#@bL-L!_P&#BIEPI?{StI$S$1-I)Rndk08N91jSHCs`nC zAn6@9|6g3aXFS^h+xH!-Mq65&qSOqfHEY&tOA-p(=b3fPhdEVrWm+|L+9KYlD{Z=&J8d(LVLM&SBbaSiG_0VPkp0vlS(0 z`|-Qgzb5YKBOFj;53^Eoib~BO329%&?)#~8K0^l3g#*Ig3Tw5VRS^Vpj^pW?dc>z{ z-L%FvIFfg0X;*QR#h35j&fjyaLR1TiWyKcR$I1>B-753(u9QN{>ZhPs5PjsaLEz9i zgRRp?4(CkJjR^w`B)bYkO`W8h{)kRg1l$1-V$4avvJ&cFxv`AYIMRDJA3CVANSGxD znhy&br|+a~-M-!}%dr3uZyLy&NPdo8-)U-<*x&R%c84O$4Z5NFKF6XaBLSv;Szb}} zX#S2_m2GR4tA!zV?@`zEsOa0{8|yNE_Jp(TKJy8!$E=nZ*v|4de?-a58syv;=c8{u zdJ7;m*z0zkHpNL>iN7ZBGB1}5z=}|*2-Hoe--nxERYT**#~Yffe6&wxp8sSWba7_8 zFp82l@mMaCSstMRL0%u{gsPHr{ouVr%KsA~yp~3sQC&{_Vi69*HE5N1)LTo-z`!8B^0mM3 zT3~_7{g?kef&O1{@ZUYu`-knsJUittRV0x<{J-O1`Wl&cac%eCmS5lMB)@C7`RPQ5 z$S)@Xl%Dq;2@v7yu|%Y^NSWN>e=y#T&pQ8u@dgklS*lvoIgNu^TOvhCGs7ieS?yy( z!V-3r*rQE)yl}rGE{cReSK({4OZB$S=ITYz-N>sKU$M5u=m$lLw$+ZvkCi@rZS2b! zO{qQXO4@woL>#}yY|dJEBK5NGZz{|Bv{VT4u!F@bRR(U}?Bs9yyV3{%!L?yl(xOuLI0klkpZ?(S-nE^Wn~InkYix zw1S*7{w3zK*cJSXNx8EH2>d})R!O#RGZ_HOx~@=gm@|8tY%rO{DV+PrB(UF4`m>5w zZ^o)UjSgHVtb>!!>YVH+(=ldNywd-?^5X(?IR9$Vge2T^x2icL8I+QIyTs{=3tl(~ zUGw^Bq=?jvI`+9z#Xj+Tf!i|lo_<**?lP<(JBS^d{aEhJN&aXU#0ns#+T`n^s4!`0 zZji|ivzpSb(`zMX#=27* z0*oT?ave2&d_92K{{z{W)t{&0GLyclo_jEzQfZnA9L77kiD0=6mDELqd>Ws(w+c-q z>$IbC{Jtt!#X=Tc)P|M`yRCTfRYOWzuU%}Msm-WH-hafD z!1Ld6hae*YP@B_J0=&z^#Y|Q-by>K#5=}!x7uq;sIPq3SMHs~AAtxyNjr(eQPP(q% z>~-?QNBBy)0s4N?AU?KRRWwR|3P%qodrg~o55%^~cWDXmJ5OD?->?Upi<`9Aetw|O z!la6^n)s@>xek`U?+hk+=M@^B6#rw0dse)DuV;TCTerskPf<0S16hBv-#~`#TMV|!4dxmJGjqMY`D&RXWD>(qB0D(aJ^cEE>&v#xShGS_lU_MO-_&FvS=4Y+g4twSguKw|Rz&=t z>%{dPjgJl0_VHEb>;c;2b6^+a`O4u5_P}!i^$K+;kObTn+`m0a#?ckgVzzCr&?>XE z;9aa2^KVnLw|0ZAw~sAhvNk#H&;Mcz z7m)@qU0yPp5fw7dqPTKHrEU}J+XnkIsj3Yr5WB1__c3H)D4bD~GEeg$qg9E5^C`>8 zuLNS;c}hwJmE3QOm&^}0NbB^8v)fvVpT68R&V{2aFi(s3FUp4S|g_rsx2x#!H9q-)fz zL^+v0+m$pA`xrZqirxazytX*-tP0sL9R1^(#; zzN_+{7_VqQ_MO^2t%gBQ?JvmLekvt$0v;3&tX{0mV zG!?@_RXHqqmAdzd;>j1ECQc;?ID0R@QQMT#Ob0(Vtj=sdjS}&`@ib|Pl`Q_(E|OfDgs%_Riuvx2_iwKL&7HKOQ+}9h35rEKJ^JIRStj@P|t1%upaf*EtZG$O62Z}Kkx<9cdK+@MPF zf}t+iuyUe*$Ia0X4HMp94Mhx0r{>DwwG#Mk&^P^LUd4sSqTN6WWC3Ght=Zn@YLOse z?lqqTU>VWj^$KtHK674L?ISd`d`KU?Bb;bgIf(87%fqR4UxBu`+WuB{+%L}Rruk^5 z#=oPNDIaEM2)~zQA%+s6Ok|`2t$E1p(d^?~KH9Nsdrh7M?b_r5eb`)i==V(8>>$aa z^goW_@gc|pIquj$v=(Bo;tc93yg7O6g1MLZXNWU5FXk184ZpVZtar@{C$!X+K}RfR zxXOK6;HDTtXs^Kv$!B1ss_HFlM01-I>IQu~%13qJnq`I|+Vm*Bi~aiDD@ZN1FQ~n> zpfSx_S7;HttH*GBDkJ*qWNd8GugH?j6~E83yidPsG;dh3n#Ay69DOWOtnQF-%Op~> zZc-+g%Vyx@8Y(=!{H=P@&6o(eT&m^COeB)rDZudt!QD;_K)&x|Rgk+~1BUKTO-oha6VAZac zcMmFj*6SCBcDhL`UXD#INzJg~2S#t~fRJ3inmPmENH?m^UJO^{y}4Iz)68ep^}A|E zxNW?M1#&mbQL1Z&Kq1wkMh%HM>NiZG`6NEd@pS@QRbm_f!tNO4mU>KzI870Nc|@+6 z2{;j3T)@vm&0!(8#*lLy`NH(ARkgjfD#Si6_taqPgO)tHFp zE=$crla2Uo2rAP%XFEi;;hhYzTs_6I!(8S8+uReiM=GZn}go{ zfuYonUUkKdbaX@PP<^{$W@+u!{*ZTLWDXFV8UdgNaFI(~kt|wowrq=xI2>ZjPSjl# z1R|e{Pv$>Xi&+E!02CbWmV#iH%Gq_XGT?I%DHr5qUL4*_Vw(dkl zGL(>Fyhrm-+R+ za~2IMe!{9&D5NHD(vS0#;DqTRXZdiA{RO3WAP*Zo32$qE< z-k_6=IZV-%hsWCG| z-Q`xCB$gW-dGe;$eowWLU1nfv*H=ef-TSev_P{D8P)Q&mX}uu+^UbVS>BPSL zIG@*kS5xPsO=Ja;UzS~}y}`99p!d@~u@zifc^N2(d8*uYX1e|MP1D+xbeqTVpHyIQ zHDXfnE12!zR@~ASbnc-@S44#`5p=1nytAwf~pDmfRO%im9bUFbVd zE|QKLNQ?||7u6A&E zLYdF8-qMq(wzM^if+ETAGW2Va_UeGIov45xV@f!C{hO`|VNIK?UmjjCXf~oIVLpLe z?gU|ww-U&UvCL{MEXR`T54WulYcDs+k4?FY=QJ+HgGhY)-N9@a0g*5OHue41CO$pO zX5!pjLVVCgVuL}O@!U5p#^Sp66g(zpQ(I72f-~47RVcb2tKf1a3wdq%KL&$)%)Ns!l>iW7MAEn?&Bz6Snw%g4TF* zlD1Sn1>&94<`xX{z}wf;?vp}CNN+|w`M1z}$9mX8dupD}iBOiqQ}NR|nc2On+HJ>K zgwu4ncQobZt2{|W;ioOJTrq`kDX;w>j z|3kSV>Y1#{u%KuWnQw?TKLHp-*Z)Wqu zg#z(6T03pir9QlAe~yWz3**c}iFP@h8>+d;gyLE1X4zWKdCd8*Pw+_W53aC%iw;f2 zM4Ozx-i|lzBfN9d-{M^kW;^F3PMV^v*cq$tOg>G~g~K~k2uFjqa$9@&r-kz&axR9m z^>LTHi|qU$%arJZ=Fe|1QUwOp`8JQx{OwXd#ln%aB(nQ&I_yOgR_>O_7dtu-g}~DE z;0~N{?di=(%b+jjX%4D554V&Fx5Z%5mYd_FW*h;VQKSa0Vlhg9XE&pLcpF?+NpdP;a)eWpW+7%F|!!g z=3kY{?q>c7PlIw#v!`CWyT?SZ;tfjp)K5VGN&hlkxSP+bR>Ov{S4|bjDTuG&0%J~V z_6NNc^jFnVn$TK$&%7d~r!{fITP~|M^@guP;`k$Q*1H!8UDEji2fSF^8YK+jdM;rFX>g(X1y=HOx3P5rA~#ng`~|x+C=#%)__0`zzs^G zMsQxHco+Ho3qNM=gLcxn7KVAjb~_7f^Xd$aCJ!!3y(1rbC>b&YKbwBSeKzZz+h&?x z|J?-PG2yYIir_Cu{0%^UL4sJxe$qY63l{A5OKt*3d~16uMZ_Og1Dz!V;VagCzQf1V zASh%(Np`hVZtVkU=fhm4F$bw``Lj ztqRomY0bm!@%Dfd7YcoEEvm)3x@6sIFe{%f>=^Y;Nj{V(qb;>Xgk z_vI(MiMh<8ay$8)g8DTH!^vN)l)OKgjnH+ATv-zyEq2?v#UbPLLPgEkuu+pwYz7*=p8!PRew$kcocy7i9=*%A5sdq( zIPMGN_o&g$!6Z3kK`Lq9I!m&>ZP^IjaI+5Xg<&=`$VOa8t&Fpc=Cx9X3)$HRecqu3 zp2Mn>#J;tD4#Y8<4chaP^Of=mCIU8DY1<^f(b-~SoT?u9ngB(IK%b(0vk@?F9y?7M znyW<#D&E+5-uhXWwY&vrgkHV8&4hL4 z^Ha+U<5AU~s?WB|v<2KAr-LCpU}|atWe!mrI{;{zGcT+UTmUKf>2AxE6yU&y-$$U@ z;}efD-glVqQQ)m^iO6zza%w;F2!Ko)A4!oycW{o!lCx>)Z2^Z3pw>iETk0HYobd*>TQ1!=e>rYr zg6_jTOvfjxfkOfPfJEwDYO+>7lL36&hnsZzRoEvMaj-MC3#V(^RM<5i3H04^>_zzT z0*dC8A5om#) zr43@dp9iw3U21|j4mDTDdE@LGy&N!Y)GcYlQl6!>rbmyYtWjYeFEoKQPi}h!-yzkb z>Y-C+pp9w03oKI=p6*YMSBtyLO;_m`rJN?x;_k00#bPWLC}>mLoaMZoGDtltGI$)K zW;i)c-TU)hAomTT?&Tj~X832RLFJb@23vto3-&Jfpzx9+vk9@6FG;L{Y%qApz8~@N zm8?G#G`P+$PuHeT8%SwDp@eH5cQF>H0)@cAnWcr@Ivy`cWN5a>r>)jS7 zo$cr{zZE^@jZ^uwE;l{#_{z=A+o!Ib@O%hrbdsTlfi{4nt|oGriMIw#@lu%f7gG7V z@+%Y|)86_YpiSGQF$e3_i>Rk*Gtz1<8LDjSIDCZ+B~4A0zd`cy?+4rxU4V(1v*_*Y zl6_I{I?ro4iIu0B#8)U%MB$f&w;1znxalhKrbDEz^N-Bbo~Kh`OHZDw}$JjlKG2H7Np5v9jM#a|~u8W6U4&397Tn&dCJ|ZoP^&atmB3^AEaWMdX zxr5l%Bo^^H&Z0VOfJBRZy`P*1%`ixsPOe{~HwE=%Jv=;u<1dxm>F69lSUzTduKvCY zf}Phv*V&DvT;aZva2z zIs&eJ%q4gTb>E>DID3LRJG9v|>fIHn`s`RQGvIF<+nbXfqXd3IxA=u}X9IAUHr3`* ze%b__%B`=&oe*uu647#UdZr8%Q2CWmcrf_)h=#K4=iCp@$8Pl|&D$?doY}jBB7w0n zl7^oB80^rD7e!S{v%#G&A)y5%ojvYMomi)!S*3>u-P78vzb$?y5N?QNzsqjPn5C$2 zo*!?37_wK>d>rQjmug{b(M7e@1reKq9B&#&Uen#Jz%h3|j2=wTS{KR+1mTT*SOlRd z>4k-uG=dm$4>>#j18l%(0#s5b4;82K8(U(E$d{DIOfCtm@*alt_q~7GmZ13czKv7u zE5CDVh5*>ozVS}8AbLk&iC*nZ-n+STsC79=*qO?ktwgmW zOQNqH%l~QVyGll0$`@ryh1zK3B<2W`djl%(zf3we{23?MbZw1sn486(QX|I4$4fwr z*e?ug*n6Xf8F?_xRj%B>ckmli=s#lY_sUaR(#z-&cp*%&f-oNmgP&T?vH$$u#9Z;- zX7C-+uXF6@_U7aGg>Ox!`h6JYMJt0+t+}mK!b?pWVOfyQE5JE9kvJ28IO8|;|B5?V zXC^K>$`Q93__noi@&d`iH^0f=q0uQ9dsMXdHGpwnRV zVGSQ8{2)Uw{_ppRiIDi%%atctKT>L>iDE?`(s4g+-;2jr0L1DUT=V)01Wt-CSkjv#3uG+S;WUsvdxUY#u zX=f(L0!N4^ODU_!7movM6}#u1d6e$GnIIWYyj=s+>2+d;zi$9Q8f-DmsrCA%+e^8p zra0{$YX;}QaXe@CaoF=t$#urmlhrDuAKU8Fr2W%Zrf1?9yh5hGg?=r;zurxA=!xsd z0K8e)WfDK5)tvo)kU}g<{&96dfr{L&C1`Q6FME+8ttb~yDO%`M;>=s3F{`-z50IY! z6Cl2x01FpMcx&44{5c&*)l=1O#_+`8R1^AtP8wneUB2Nk6&Ia*N^}Pj#=q>4`3&3D(fm zH^b3D2Wk1~T%Q-J2wIu&Ms|A&AO#fjT!T!QFV8O_@8rpaT+5vNV*RU$lB$|QVMsnL zP9Br+M3ni`b3Ff~?#KDT&7jn>8hugvf+BtM(&Wj0xj=GckZlI(q@t44TmZ96y`Hc_ zv>CyZ;Lj9vaS{5cDqgT6a6re?qKCJ`sI45fv)C9BjEo|M)@dJJIBcF9VhVAwVNC-ibbsM`{3G z_4)Vj)$jHEcbW#g^tHWeNcuxmy}igVNBn-k8aNZQi+V5C{=JCh_1jqc#odd0{^m|6&mf)mJ%c+EMTCGwqN6W0#HhIA?D{N-V(9@Q0So{MaJar2e*fR@^U|Sm zdl#ej|4^b2e&1jE$+b_3&o?Ae!0!BS3K&O8?YlpxnM8+mwZ|GPijb zJJc-$f)(O!4UDRNkOgha{a#L}eLvBbzsEj4cF*{5Dwm@H$WZG=&9XC5Z-XD7%@pO9 zH51n9is|n^m5btBq*5|dJPcC$y%|5VAyWMENu26}(zN%kT9WmsPK6=G3!8cEAO~x@ zL8%5#f*3QBG=<78STYHqaq zsv4jeTSQNke=*r|@e0ggbR|liElfw&hKDjgz zewrr4&0Kz#Niy+pi#E!H3P7a1(Rk)hGJdZN@WE{D|IC~Fv(PW7o9E#FLQ^l>TDyKy zBIQnXsE7Clt>pG`uwr}`VWiM*!Tai?mdo}fg@L6`f0MMpCq@%^qF&BgEPY7M`Ra#S zQIxp?WSUdNa(B^r*k;~8SsW3h)$RckoJ$o*mEoTw;iHemsF3~QZ4lpJSWYjqC&0bO z7f-gk`By-Ff`XMko#E%6_X5kE6^zi>{mO- zSF7e(8!iwyyL-J;GK)|xnv5_|Gi%yr{$S+n!2MGtCoC8Wd-^3Y-kDJMB_=RQ{82-D z%U7pBZbF_utzMJpo+@yMU_eE)O~rR#>;6kON0VIC?`)IZJ(=P9joqxA6(scJL&)bkBTI{Y_0wt2>hzh_QU1Kcl1@&z`^ zl}O>^1n~~Y`|`xuc6$TmFx-tORTfw5R?C%Nai5y6>%9pg;{);%xZfmo50d3@xrfA_ z?*?=;?t13a(`a-67->%5o}?8Fe}T1sniSN36ThcgIQtKvN%Ow894(WkxSy|3 zCRnz-TIR12pmW&N`b0@tvM~l)@x9E$IF?XtU;B?V%?+EVDC3#Ix?%o?J zP!P7i)AmJ47Da?eeG6tadz*fEJSnfVZHyYW@BWHm>ZcxkjbI3w*&awp(dkfARf34z z4hfm33x6I&FMqFMR<|rGL>VJ*?`DFWI04!4o0Wqx1()L&1TZ+5usT8R&Y|?=(EH1- zl4`>Nu+6>@Dy?2VsK?x84?{yEb8Z4@gt-|emi_@!jN$Y-T%KV)8gG7_|2`)6h@ zr7vK~kl`NW<4e(5rePq=&$(Y~v|)bS48gCRQb6>1X|QgtW>h(cIVf$nD%s|Y?+wi( znxh;BbxMR|$15PTwb3Q>_SD`y+;iswWuk>e>{ zKi7FD_Wc>U{GB#NUi=?mXMI%pHSgYI^1MKw#=y3Li%T$P_rvNdyYn~4r2G&&62f@O)c zdW_1j~PbyEko}&v-7nm2IM23wS zsn$i665m8Qg36iOTJv^8UY=$LM=xrYCF**#r9!Ogt&aDDbXQ4@vXZM7IKHn^ah(VUnk3+a=p;?NEoI>zTAdXGx77WsO}~A z4ggaB@Jc18;GI!Tgn|WL1>VuAnQBy?Lr#L$V6}7H1`0CoA-yyz6h8iPSR-R3VQL zTJsF1#FJ|T$Spb7x6%yvs~7x`R`By#D`s%?@bJck6;3jy#0OJxqjK_=dy#k;14J3- z%O;L%Y7?s*hC-&+?FKMKMdQZ8e%isC>G73xQnwi9Rc;w%?0tPEWl$k!JU%R4Jcp>K zb{CNr=bKH$8BjTJz(6 zl6$X?^&D7FKGEL~xXLRRECN>hz7RPnK#P%dTr?ovxMROvS*;8IY3~-n+?7Vv6)MZR zc}LsWq-G&32H!MjbA*3Bh(ZLVKFcbhk4G}I3u^)Z%&;Iy7X8+1?4&QO_?CSj{eD`( zkTg6E!`2jSEg!+3h)o(p(!vZWpC;y+5aWHwA-W{DeldkQ`>a^8-n1VxabK%gwCFYS zI8k|^r*~7BZ0f=_-0!YIe45+pA=~G*645EBkf5ATx4Ga=)UY zQizM_Kk1rTk^6ElExRnO*{8kn*0>?a4gY0xGu!*K_$Gb+WAYpkRIF#tJ0(QiopI{n zMHhCPz9Iwby-hJgg0!Bp)c3a%Ihd8?iBOnqpHlJX#T(yuvY)ls8KC`-5*u@>C#DtC zt@#bQjKQ3uCyBKl9yx37LnQkoGc~#mtv%T%5upSmmEVL-TNxIJ|@GIgoc2&#S zn83?f(y1decm6T^P6=egp><`g$8$uRB)HHIV z9A|eejM0?}6jKi8$pj74<3E19xatF zzq0Yw5=x)$Yw*?M7vn@kT1XlmVKNsy0eDP7Z@RBr$MiL))6 zHK}}Z`(uOXn~dUZwCEa66*Cir)WHkCOZm3q z-L>R9Gh@<5iu^6S4Rxc_1>~rOHHhLS&qXSgKQl3Jr4(rgJe()kmhh+SSV0oS$6|$S z1*ZUCI9vPn2)Wi;xQ5Rz<+FN6Y5xFYFiO_5q7-i?A$s{xc)UVLyxh9mFY@{L@CB1s z_yFd)$&Z%BZWr*Q?NZ1nzbB1%6PAg)m?LSt`1C`RXq-pMZ=w%lu5D8-qkWUG^F&@) z3YRP}q3Lxa3`~5GG#?5j=iDh!y2T@JQp%8BHt+wioD-Dox3gHIEGf1-XpJA-9Lm_% zfl~9xvE3ni^0ON>6Q|bSVmd!i>8{6QzyM~t_%!il#F*zfcT%qoN4!Lkt~0ix6tXM& zsC1sOxm!5hVgeW^2KRncC=mw=M@hjemj%f!g&f~1s8u=BZWWm5?+mD|nE5>SEHg!w z|A43pZ*|@j>)a zg}{faJO!gKK*EZfHHz*GqNOWF_H!+&(3uUXp6Zh;AM9|eaCDgz`;PZbP0xbT3bGn3 z$+DuXmCSdgpoRAhcE&~VS?aG|WF0Tu4gh69)u3;cxR1XX!5g}3{YTO!>(xQnk-;1X zaPAX1NX7UOR$5|!8IBU+W8$|bx8itxKU}9dr8WQk7wXN>Am#D*C6AQ9dVDzT|0Jy6 zBKkOuv;2uM5>n1~o5kFZ^BFBs?3|DSDB9)KsS#arxV5$*$;g9MT_*5eu zuGO$=2MGZJBFIHw8Va^6W}F9V+d zMDd9T%66XiXEeZme)ryk7}%WB)?uV7LJb^J_T=b~YQ?0mK&VW0QBmc4@(*t}m@`37 zY~;a%x0y~N05Hu_Xn<$@<|^RX?5p}JvI+V5h+nq$N?ad3>P5$iizKjCFMJ|Oa)cqL z?2h<+tfhd=Z&m`Kmu*Cgf6ncf2=<(_>fzR~pjP>befnIEpX9-)R6|EPNO(YHl;`m_ zFRp}SHCE;S9hd)a`25*r@Z9>pCZ)$Mv}4~~M$fH9E)3s4%P^-rqa)mnQ&`C7b%o5G zehFcN*)hyY-o_(N*f|3PK9{G~kq ztrq=1wxxytCegeL9hb?3y{Q0Fu7@-KQN6R{W@R{w$27pt{eCC!#P4Bo@G5rbqD?h3 zMl!{^UHQbBLUK!zVw0XU#n=sXLeg{NG1a~W!wjeSYR$prK(+Y|3;mg$NC!)l4f}0b z8@-9{E>w7Ys#OIqSx)z-{q(?D1oo;t&VfKdvznJxsVQ94h4I*v4R2sBIV{56Q62E? zc^jS;jT0FKNx%8St51jkE+|S<)<{jPa~ff&fr~}sq%>;s9f92OMG^`f%#u|BR^M-T zwm>`$DVvoH&iK~c0a=3c;TV=J)RE5bLLa>-8<}C z{5*cpBD%@JtT(WK7*Zzz@D>u|vrrZ06)aWydxx?}q4Srl0o);ddpTG;V@zk1MD^)t z=nDl8r9eyi_J07U>#MRyJGU=v%_V(#T_k1qbbYQq+-?$M7%NJ_-qX}ngNk>MO?+rI z!@JDE&ayR#of^_qqkPNdEFZWT<5ad0cuvzerWv0UO2zrNZ}wy5)JXfDOH=vTyPRFL zK%J}pw-!Vhl^+jEc7{OB=L=F~SZW2N{kC;EcDuZ)I;}9&ucw$@5H?s0@^1154?e!< zJ8Vbc%>&3G)sW*A+`MD>k+>l`uM!nF4tfI{!-%HbN^rw;sPyu#X;fQE9bV73CD*qZ zm%mD1kf~A-RCwl}F#s$BPo*2|K*-V0X!~R@M@OD2jLeG`HdPJuIanw0Ad*YO403tb z_3nW=#iUkh-BRzy0(s>|Zvft(6U%-Y4zse->2{Za3eWIquaIdD{(1MyzVI({D`na$ zeoG43TBPK-BoAs?x!e8`?#I|t46pFY?CN`&R;I(x>Qzw6`CRz5kS%#AU{jf@t@(+R z5nWCT`JZci_v5#{UVmrH4G<|Mc%&}t{Y&4gbJ^d&02)s@^x2wwE*~0KsdlZ+pG>M* zpC&R)t*pO-rv?Mq1ZBzYD!rYn0!?yCZS&cLNI~h!GFbm)DyJ#g^tH-*mul7*^-e?L zSLRql)wV^J`l@7TZSpnmOV;#1&wQlIO=?^B6vALTX}cd8**$9!q?pG9 zMs(GF0sPKvk9eYIY>vvUo^ii9X5zojVX*6U?wzLJ=?;H4v32`A3f`GDbtl2O(!7u& zf%i&0oFvxT4|$t9$?xy2?p+148(K|2jLVu7O23E8C4rxr4$VE3-i72^5NVpiV%}b< z+=*b-&ON#pj4Od_2{5fcw@5VDy;rDPYi9g^)SogK2=bu}O;S>c6E08!`LltUK>9U8 zD}oyUlOuwB)w@@2HYw>g?A=p)WB+8;+o8B#BiZmd7T;#^Z7?##sWBWq9-b~i($U{H zq&8P@*f<^NGQBgZFKSXUmWG}uUUrJ%@pC`%D4Fn|s-k7KK*9DIhWk;GJ*P1H^tc66 zJk5Ih(*^&WZFyOk=yy(A|hV7^r&0*w~Xx>UjK%ELX+J0;P+=ooB90!751|I zoztuX%YOj;mCWxdL-sTqeFm2~F^P8#12Gy9Cw@NbXNjsKZXf{3)@i!iy{UGupL5E_ z0%8%yBr_hXo>Q~d>|)Y?wOGQar$zJ7k~lVkL2+2t;WW?k64c3Dk@~0dq0b$sX6M1 zUJR!BM`@iky&ycKP964(t->?It5J!lvXo%)IkLMeip55+QWC(Ha0{Z*wp~h11)NDu?icnsSScYQ{>O=kn-`}_ z*5n{tMF`>Hd>Gssk$lS!=uPL%fnD+Z&5J+V>xiHAzn(XfbQjyp`ZWBNABTZ_+&7zH z+3J55W^iN*3B2L16>($G{%6-u9=_NW-uJY7JN9`KLg(lwI(Cy6=PtlZ!F7Fzb*cQj zh6NhJj=R#p#P*g_z~iicfR%dOp22s>9MsMrcV+m+T9NhyIyW=*HSvHlJ_!%smhC?w zcjKm0Xq7+9cFOzcV$dM&rBhX2H6bp^>sFqi>r#!&uof}_zRWP`{KSkt0`MiDjb@w8 zRY&Z6Nin)YPnkfCYs$Q>Xod}z{k^B;H;lZ(8;P(MBMnV^MX%V`T(U8Zv&5DtgO9#R zXk6*3@xzqvcCl|m{pIp2q>1%FYN{=8ttyN=mR2rm|Hp#p#{y%ksZOy0XLFmY(!Lfu zu|mG^^6b632vu|xqk0ISm0C&p{wF%m6;Mk{6vS&0U%q$#vMf%2Qv_^TWS;nj^eWn?x*CN}hB+fM%?+|wf9W1UZT70f~U z7=|If{1*))!t~C@aqoH=XFy#kl$zTHK_iEgj$)x^i$dv$fDdB>5%O`a{otZ`)3%;^ zNeLT%JdU{_4f%QOS(ggmCXYHRAW`XTqtdzB*$}jOnqcp(U>R11pZ<|vIx?}dUG_B1 z?4^3=L&cpBFNFlbK?LqmGPMgG9-4Y_fg)fNg!|<#RAk)d;4C8ej0yW+1!^0gidt3AdNK{f zuHpce?t~_L2jMe4rSa5M^7zDH@vvY}#OT*IptIw0-?nwwykZ-h*9;AWPLl?01gC;5 zzNP6xHgrXU*x2}J1K*$$54Wa_)0UDNFHDeA&zs9>D%K;0ngt-#s)m}Hsvv_KkM$@A zSIVlud=?typ2?@ae-rw+Z;CXYe)MG5Zj3hLne*!Qu3{;fwz39_!nam}a(AIXim}W| znR*}q)1|+`rTW{deo-K6v)q`jNYA7Nv_Ea<4QjrEI|km8_-*pMlp4yMN~=k^b9Yzq z$#|+$FLBjM(-yI>xfvY=_!IVF^=o%aXv)zvKhy_=OmAku>{~aQ=Px`B-Tn>PE8o_ zxujv}lZWwvU+lZ1%+fg>gy7A7G&*}f@}q}I8&~23S3?!74ygt2r)ONt+HH*_&D=ls z$byaj(QhQJQ+)GKVdVh7L*p=6=O~?q-a?4BHqivs@u1TOn)Oh8A-%GKAqgqMCO1p< zfcIu6XuRRt7jg|E5cQ#_c1e5NE3~x~cwCL4dL_DIB<|W+ zQ=+tDvfSGH$Xys$OJllK8aTN+$18i7pC55WnS1<I&Y5uFha$1E}v_v}TK$fN_iix>xKVEVvEF?s?7+eXD-&r&vKOL{hI%V7*eNS#XN@ z!7a~U!NRbvHO%lSA}r^0z#ueaQ~9lD7)ycdm7n+vE*9Q3$Q_$e0?e%B3Ea7;r=q%%ia zs&Myx@CIw(C1Z;ugPKq2ZXcNQm71G=VrAlsr@9k_r-=?F=?)WFf^VOu?b~cvqwrr5 z-Ofxy{QP7?l;n4oDc1pzznsPlsLOwVO6hxPWWiN;pc3M%}R6?ca7>6FV2Ls9O^Ztr2Hfw-1a(DGF2H zVXvA!Gy$lvytNMI-Y>b%?I&c8#X8t2e`6?iXj0yYb_jxA^K)cXyyZ=MhTZT0q{(s-2Bve2|1tn#~K)Pe3#5Qu2v`Ps$dMF@>q;!pL z*ch#J3rM$gBhod>0g}IazyEb#$8}%F{Qw@EkH5#U^K*XQ@7F5{GH_Rvek&>xlIXyL zq&yi5aK)x1c(bj2r|osYDxH#8o=tA1?%>NZrY59yJSD}&*Tu)j2CAxmGZCo%4dxOP z5F0u9$e zXrQn{i)Bp)J`rXJb`WXy7QlnTK3scWlC0iobGTr8uxcAsI$p?SPrRe-nv!q?RaEF$ zd3gFYRV=bg2QmMyW{E1UhQYmIXz*R86rCv)Q#lHq(O3jwJo$k7s3r?c{^L# z0xY10QI|F`(n920Yfh4?K4-rzf<9VMK}#P+4j0d@KD~c)qy3_Ek@ZW6eXOS4i`cF; zX6K+-unJtlvO| z*c^|0vp)PA@S;@XG(%UAKd#To*3vD^c`gI)SiB`JKo>HUCqNoE%dnp7O752PD)3t3 z!0M#1PhfVG_n&|~!yL78f3?H?gH+g)l zxHZ#tTLpKQJ{kit$V4?$f!LBWpp+!v`$!1O4&4BmXq7dc1CP<0%`8GviLI#cGx^+w zjQ>{2=*WmDZ;+EVr-00^u1sXvif%&O3Vif3e6%x7Dyni8r&_4MkQ7SpqlYvX=L^69ASVfXGu#@mB2`F z*>$46NQN1pzJypW^=U9%-U|QTB|LSUYn9i5bzq0kVR@f;GfGE00ybm8xh(I^M+l+5 zPsYfxky@=oo%PL;YXLvLT8ng!hN&uJUumv?t7;0*tTIu4l=Rv&4jnY|k%{_^;q3GT z^7-BpnX#MrQ!~#&nJ;crNdo%|P`%=EC-0hYyLM&`h%Tq&xo|rs1DWuC3NTC9wgsE;xv_HqZ5|%11Q7T=D>gTk1RZ>< z(D%vxoN;X9pw;>O6axN~$**LQgQ*quPk!`}n)iPGJ4a>|0~@!5;_V$=5J zF6(njOI(WvfBAUaYC_AtoL!``>TR-*cfXs%8ZWCsAoC}m#X@`5stz5_i1}MzH-Knp zl`RZ{Q7aI+HFOPSAH#+@ElruCF-=$@YPa0-?Y~8iq`S+<8K9TLcG(zxk|8$In#30& z^qdey4WKp9>mPnH`f$0t!9TmYSp3dUSABt#R3jRH10x#eS^VKcvdCsX!RE)4S*C~u zfA4EfP!R~^06T?RFhb=>)MISE^FDkOrtAFME|ETjGa0cHB2X0xJd1$|T!ydtfewB^K1?`n{o zz$am){`K4H(gkZe@gDsCx7UWqR^Bk0c5(n-bFK2#)mB6IAc+kfw7B-bz^wmhszpp5 z`T;H`fHC|w_r6$XWc;K63{wP#BmoJAO$pJ!?=lJG(o9`7`x3JTYmg;{^!1m`nZJ!z zkbb3D^~1Xn8PZPAYff}SK{$y&Dm0~oKim6zq1yh6op~$G28DgwxPL>}>n%+`wlmmd zwjrQ1n*>+i018%ze?K`&WFOBAgT{Mm>rSv^8FiM`AkS<8(=OfKpJc!E{5Ns@PP)U>x6|a0zwnK zAx$NJBuB(D(KTpq%3c>qH~7s#mAZgi(zJ94qLr4mF@%%|g(lF^Yf}JEWLH$P5uY_n zOyA^sJ&N?20GfSUs4?+o9Pfv<3Id7CUQoNcdeGX3`_Cd_9$w5@%HzdP%_hX4WnJrA z_1c9dl**~w+Eibtq}NzdX~}#LiM|U(-!c1s+%;R6^y-aWx)ZG=-Oh$Lz26UiQ*=nd zV<7Du3J)I(u5vUEE-2z1laSk|!%)??Z|f!#yB!?gh0;$1U$v?;68NjQc;J^2_tsNTMt15)2_0o~*P?st z+4MS{C+&~7>JfLwqR$;r$*Yng-wj+q*x(4{)TMuc-s(R?wMU&C*tl|Zk-?&gIN&v}NF4jyQL`sA^~ zeyF;8wGyU!?X(H_+}W__*DcFFI$y+-Z?7J0K$Cydq!B@_rqLv z-GOtsQN@m}NTM)EJxvomfGwd&k#|fW=t#fxwM$P%h&6>r)&if;S#grbH6<4^70TJs%fa|s6*3K!pSoN&EZDFTfA%(-Q7BXK29X$y5 z1l#2nOWfT1Gw5Ke7x$al4_a!l?aSek5}Q5B44CudB|hb_Pw2RBJELX#J$e7eDu{k+I8D^pi`4Mq@C_Zyc1 zJ5!e~q^L;ZefjZSuOnFWw{l=`6+O{u2O*G0n|i}%xDC2AbwLM6d%xl!Z{VKz9{R!M zig%`5CGVHyGu6aG1&4{P+k{mAx4B?!f1F7ogB%Al=fVK|P}k4SM9hiNCf#=? zrsHu%mQBt3t}Ypf z-Ylj3Z`H96q>uLJ|6MCK$q`*gY+rR7Z`%n~9H;(l?#B9NF8z0w)o5lRSYA}2yB@Ct zDW<~-1!6iP0`v<(_#@)S6`bQlujg3Nnv!kpxBmf9=+^xo0o3pR4!OP!th#;{O{1?> zx-%sIyTdj5ALJJYhTUcHtVhfR`2ozbJsEzLVCfahR`RIy&C+gYw^!dgXX_AFV_(S41j?54~9laghE#?M%=)}t!{{{5U{S1vC@1NeC0fx|N zTb8X41-EqWX22kSVKJTwwMjM!5MXBZ5t$LTM-WLyrHh_zVQ2f?SaIA#75lrNTk1yd z#cyBb@g`GxMzc}@?wGl^*6S#q$g@Z zuPKe+`+lFyDw=jOESF3wkh}3WN%L+)+oHB95Vj6Gl%{S8uI|1*s&U&aQ=V%+HP1Y} zpVkYTp?)}dIAo`#pfx!oKDtAGO<3@Q_;jgMc)0mUx9W@a&>$@zahz?Xxfynv z$O|_RBJS@I?Xp+FOAO3!CJxW0e-MTHr14%a=}NN$Req07F1XhaR9Lq5C zczWfkIseqyqH#}L8X~UUEQnu=@~on#)8KO@890s^6Kbsd_8@GW3ejAa_pXDgDMOmn zU3e>o+Shsw;4}9h00aM|C|H>M2wwlcVPTx1Zm(zX+|n4 zLp>866IExi zSez)Id{;IJjE4(CCFT&eyf#vBsu7AcsjU{k*dFrGbTWq;7I@Xb=#XCCjm^)KSZsp5 zQyHlWdBMpm-42ZMnCDS1HV3IopN{ocGG-%R3F65fgA z3gPp|snk)q00;v!C*d_Q;NNry5v8q+J?97rjSQVMOS&avlozOeA43g(r6aa+wUo;o?qKf?$Vf za`BR#x0#XQ8-p@6P?4I-83Eb{2d9ZqZ1$uiqa=;?kJcVG2@LDKaP@&IM@uj3ysofd zRT%K+;(t1CuYw%Z;5y_7)!>@CB`P^(y2bH&Ca;@zeHM0z5P>-#KLA-@Vafj4yO=m~ zpRppnrGbXF)P5ef#xv4e*{>;Ptj?J~Ijh4NrtY2@B?`VuLD^|h#Mx?9Z`9*f;y34--;2VZ}uSx5Cex)_@ zhfrR%n-La9JBut>7dwhWl;N_80XuTmauhLM3+R-Ciao!(u=kB~1BTiKLWSJ+w#)jC z@hA=X@g2DE0p@#!Xdr=0^^yt}?|*84YUle3W8?5`0#kFVoXk|z@Cv?Vw|mz$SZutC z4#nQ)?MT7_>MiqmmcCwFvpVNrYMz#ig|8?RE)_3Cja7(up#!uLWeM|WFC_6L~VN`Q$Gs`C2st6#Ve z2k--pM!qXwc4$%i(Xvhw*)bz;n$#LfU>e_+va+k4p+}R&y*v0YyP_JgOfJJ(`bMFg z$ZqaQ>!o!7(SfGgba$SIrD%SZ<1f1{^B&g$3dPZqq<>NuFTdo;+&7vk{;Qj*UuA?Z zP4%&5+ZYE7JiW-#pCuL^0#94Szkh}I+OAt-v4mPw2+j8EwV$K%Me;wcuV4D8Ht3_4 zHu^SAw1@0`ZOzI=WuoBnPtQQwB^4Ihu9Zvt@H^HU8j0MRj z&GVRt2?-i_{<%n4^WJc2GxUP{3VNU>+^V>&c+C0e_4XHntE?#=gnU#}6r=ZC7) zYBxG>-S06O%8Y4U&lWD4F*Ral&605og7Uc{$@UB<;R+}5XCJ=uo=-gct(|isFmSJ{ z!10{4_fORp@HL3zlBRd-F;Y-cP$E{u;^=$D0EEGS^`%J~tcb;V?L1Q&182ed?;nZrr zbZ&dJQCZxb0%{o4R$6km^|VFmvcb27fzetKwPXD}C!KxjH7~hVna?`&$P@t(CnU!S zo0mi;wo9Kt9w$Zh(>;@$oOHEGVy5-x?L48)SLeA5|Lp^>luPRmG2}E@ZJ7kJk$N`7 z#E;)m8vPt>1+KKLKfN=ZTsAR1iIXW8pjRHJr%$>^58~#CQ6g_K_z=a(60bP5_gp#F zd0;%C-tzAwZmv+qkBlKPdE)?hzyX+um7%p@{ez~sDe?{DxI=eosnbw;1-NzYsZIgz z-`Dv=L#xSZt(0cXnu!k2QRi$58t#D|s+0CqOMqUl&gbCTKVvQTb(TD%apJ`ZH4^t* z_7mOh(q7aNU;p~^O4oGq(LWFaesqL;sb&H+TsXH;T@ zej$&e;b;?{*&S)Y^*Y9Cz^syBp_XlsXS^DPXmpU?i&X}<$5HQ1 za&2HX525CZWk-eB!T0QrZW!;^#TGzL>3&?!AW1AaqO>md#q>A-+5n?_5}!XxXeGY!%b+S@l8FcMMH3Op;bD< zw7 zefC@jPjZZd7VL0`m*T^CmTbHue)jsh#u>b$DUD z!ryd*Wd=zeK~k$$2!E)G?KeR*{rXCv2<6syR9V~oVZb7y05UVUTZ3rfnD z^s!QToFh9@>%{6pfA+4k)J?o%-3Pbn7BkWti?pPj8=w2dYjZj($LZ=oT$cK7DH-KF z`WO~iMm*abS#|id?fL#Hcyh)%YH8cn`+UmIj|o5l?fLY$rKMOYzTpo3g*aiz^~Kel zPdpcF7Q)TD$pjd=H3v4996)-z0uN?FTou<+jl@eeKfI~$)~7C?tZ@1?ef{V8{m#v> zyQ=Jp^m1hYCg#4wdGK@q&fX%$)xuVe`4wn|5Gw;&&~KrTF2p+g&U$+wL1XC z#}*XFMy5zicwv*fXG7F}O8PpJWp0#9P^D8Mp4;`k_V4-gC`7cS*7^ zyNmP2hLt7BM~u%9jIR}yytKI?pbeQ5UE&yGZw}IUfNyK#{zFx-4nKv@4pYi&X~kL^ z(mJM&qVJI3KrrQSBL1Kpq-BIy)> z=9i<6?^0WU)rn`=nkGq?_;wc?l{a&FCF9t`)0*;2_)FZJloU_W%pyrSdD&1=b}s~m zTRpkmjl>SnCRGMz*%0)Q#?|}b7mxCK#ttR!4u`BDX*4|moW3l_3^U*!=Q}BdPxhlL z1vRqcv(nuLJ|&h*PYzl*{6y{aXt4bUU|{^O=#b z_BB4qlwzF#ApY0Xy(|XqJ;w_XcmCH3m9t@SL&xrmXVoR_l)3&tJLL__oD=m^ib@5I zi-$gz$5WTY%{^>^JRTc;gyr(1Ny5MT+W$>Zj|oNbwNM>C?Ft}Ff zqCk{tMZi%dx39ReGk=Y3gBCqU6~N9(P_6h&rCw+sf@4wT?ZlyKM;J}M@eqwlcu73 z{Z^Pn(sG4>Q89XYV@xs44Ca>1@YYTbzrjZYc~4(Nm)F7ao%q|D^QsmMI$e=?9ueO$ zLQUV%+eg@9X{vd~-rswkSM9PObz3lFR-Ex>_k1k7YbJg=K*OczY8K3$lQYBoEz+)T zN1$rdVQ^mGe_X(8XV~Cbme|(aY(01yh&(`gM`+sg)qen_i9fdQK6R5a{1QkB9mU%L zDwaa_&lZ-JM!j?oWCw~}BwaLMBO=9jo*|vfd#N~#ZZTHfbWsDrOat(Yc~-ir#M4At0T_}6LCOsGQ+_99Ggdt!AxPr^*%-PP0x zaYy}_ymmW!B>;B}fYi@UmiYvC(ro8oA%Urm7IY8#C~az6+@B!<5lM84Kgr}%j`Rc8 z89n2a-sxkqQUAI?rvI|MT>foRoA^Sfv45QDuZ#^!|1ujLjijH8RL03rBRbIl_{RW7 z+;3<3`nn|&qi?@({k%h~TxiTt=HRZ%E2JXNDfhC}R;uD?baFBM3;&;W-+?TuYSuA; zwYB3&@o8vixW4C&NBTOhB|}R7mx5Maz0KsNhEoVJC3l?0$V-C}eBEu9^HdtF*>>Kt zyWbi%&XACrQ3Fh{8IuoV5+K79g%KOgagzt85^o@Q2kXg7)f>3d5Mhp}3-1})Bsvsm znow{tT%;~j{?o!AHvg=(0XG=2-c~9`;sR*~F1U+C|6qp2kR|vud-cw8wC@@HDc@^; zFX$lfTU;q^*iuy>gOfueU%SZgfzUvjs8$|Z&?YB^C(pxnR;d#+rs>i)rE;_ElphwV zMf0Z-7-fq~DnZC;*b)k6D^Q$YRWLCXGs{T+2jKZsxGi$LXU5memd?lTWorJyY0azs zX=ADFG%rgFOQF#P|RX)&T$Jb2TXe3(I#po_C#uJ_cWy5$P3qGhP6B>w;Nj$ zY_SK`n&O8oe}98B=)%hQe->ujcKsc2RU&1Gs3%if(&E@wb$)Afrf%Y~{l%TXJCIz% zjUSotuvgnvy8WNxlZQ3F*>4Aq&T0gurR_GY@=f(Ua6*4TDiQBmas%^b=>XR`6r~o+ zhdsC@T(eTWGmJP^QI*(xXF4-3&235wQ}-Y+>Bgil?6c~*WPOuhSXXxXRIU4Ba?{hQ zEt^aX?>oxiALu6doCfpA=R(jC6ZetZi2A3S*Z!}FrWddg_b=-2b76M)X<)eBp)CIX zum{rOQYXwF!$@t~+{_r6%2SoRD%J;)3tpy;(uMVpv-NoBPVgUg-#S9wroI*5MKDVl zvmT{gJr|mt>i_QOzkq18a7`V@TWouIEU4NUVzlsAD%n;haL6@vrbm>DsNG&z7+2<$ zvH5ow1W&F3vn{+N4a;80r0)oaD8cm;65xqZYhSvE7+svYL{1mHswE31pWTTzMrEM~ zh6UX15YvmwoAfmgf{(vU#2-tKzKcIgtl}eoU(f7wn>T~qL&75T?mvI)Zb%`*53;oW zs-*LWjP5tMPaPbr5o>m3y_m#eZ%}Li6Zj{BYXvTO%+95o!5lc1*t>yo1T5`VRFt|$ zy$ru&P@b1T*08L&tdWIqT4QfvmVoS*{9Ozulv6!dFxTb?6&!PiO<79~dYv@K=)$M> zM6Di;zfC>X>_#|xxo%OtYp#|ye(|v*1@it~$2jLHPtgyBS>=lbH$9HSb)d(##74ghprN+FbQl5y>QP)F zP!<9`_EL|V#>&rb6X6MKedZf*8~TBMiIyjiMyO(s;56SVgjsGY^-~J;xk~i0m^3@o z$%ro}8v$VU(#XH?w;@=ymG=p=(rGcZ6dGCw>3ok-$FTXKZz_Gz|K55sSIv`EGcb&G z01KxQ4lK5;KRemw?=nrqO!Fn)8+ehO22!VD)Zq>al&Q?LIgh2>1lbhBfLq*&9nnyC z9b;f-=4Hpu*Pc}u{jDf%r^s#tB=01m-v9mSv=`QqEJ-SS&u$~jKF{RjaaEmhlxt05 zlovisR;m6OY>MkPxT0!G{>M0xzJ--!Y3(?^a4&QqLD zHI22fkwLknnpMaMAwfARMS=@gF3=vDJF|c9Hpl<5B+(tcl82TKfw7xf$7R^BuWDZC?zAVyFiz~N4oK52oIk1@ZmGl)wSSQQ{f>5m7G1h1M z95aYBk4K&r`>II^SZ;DG`{ArFZtaUp@HF zzEN_1=WoQSPF2Zs=6{uOj zBF}UcUh$Hz>-4T3!d>2E;G55VKUzpk4Zj}SzHf$~=3ekpL-fKzoKdLK zq9XtIMn1kwP}gN7Cw;K@h}Xof>RD1e-sh=ZXER&%2}pS+!O6_n8U zzV)SfzJJ1{u%-E&6FT_fhiT$L{H8TW&Q5@W^cVFufA``a1bFY02h@GMN;5th%wDD3!J>AkI(I!#OK*UKUWG>AXDF=6G&lrPH38 zjG5d>ceHeHDT2|iE}SO-KE|m_v+{WCrf1ahm$zix@ma6-{NoY+h)7HEWvZv((qCmd zp?rej^s^UVsm|Qurynb~`}IKF{Mi?ld zvP=(Du3uYVxN4v2+2?$>`o5?|ZE6%6FSYoSg=j;n>X6-pVeJ>mVk&-~{6|LB41sr2 zdExssURb%l#IeS#g4f}! znWvHu*J?jVKwkkGp7r;W2FH2yhmRWL)4yP4>5F%-rkSEijEc`{%J5S^f#XXS5edn^ zkex#Do1EhYxfpwHZs2-5?P2s+jx*j@=Q1IB?A+kK6d;oqTb$cM{m7FHm#+MO^65FX1NIr-s+P9I}o>e#W$2<|cs0>qho{FQT z#bwZ++`YV`d{hF39!Ubto3H0r)#Zl|jm3Xde?mw!7CoU(9}(tFw>d4BJI3;NRmJ^N zf(E)X?e4ZSwLgB)%wPHIg9TQk$-{N=FCOIJm}n?03LIcIMa>(Q{)EWvmBePgOSEU%N zHIR@e}SS$V^Sr zSbd6G``)94Ml|afmi%Cr_>p=8wE3~~z8CcNz2r3GUs(9wPG28mkLb=0WzVpbC!o=*yc4NY*PD={@@1u+nOPB4r_p~)({7zNWj6Rpq9@OoM^^vI%sz}$ zq7J9fcRJ6z& zV`1^Jhx{F^_L*5yL-Z2-6k&9fm%ij5=NBMnaS{o&ZR=#S2LrcA+TOWIEQq@8G8;AY zhBp=Ze?g@<7!|eY+Putnrt%z_SUmN&R%9uJEx@V!wcr+L zDW(*MQTBRzG|xJdl;N&7^UB@4<FG@_Lh1!U9gu#)OP>CRO?_%bTv~hZ0+yvvbp2@sP!yFF1j|QQtSO!AWAG6XP1((!zx!b$t?fm_!-7$W~+W97F#iuBdPE6VnS0 zJKMX`fCA}J=?gpFsdCL@v-<^epKWvdpm&w%ljwspY3V*ys8NGIt_j<)uuQeK8+(el z`?{4hs1D=t15YpAjr&sR`W^B!IU$Vd#%Vz@7mTZbs2YV%aZ}lb3xvOR$SM&k&vxf>cQCzv_|2pjNJYyaO&WE9t>?IsmtOEncz@ZqP*(6PC~xlUtYX5X zNK=;IRqKi$k`ffdXb8f53;Oj8{t>W#&yA`!t$FEoS4+>pLSgFJ{7O+?fmoxXFM)qL zuR*2?dcR@|VLtgd`jL34uC^{1XRTb4ZgviL1~jG-LJm$MKa@Jl(WIWIOlySCvI6}4 zZNB8X8EO(6oDYcutk~2km|TBv+ovwAsJ|01r0Fa!zF|I4I$Wb~nyfE+N0*%$K=>3P z1K-_Z)+T7XVRwvmY+s-;x#RG8w^^b9g_668!h6TA5CJbf;=Wc#IE`^ zmPzV1o_cwN)680J)(=3i^Jq5YlS}XJ+y=zS=d!<;jPON8D>W9E>OfLTwSr^+VY*Rk z>qLN00b$nmR-2|e7ek{r9*;pj>i1@Oq;Q-_0jJ1QFv}X3dBWIWzC#jA+uQ9vDK&A%H4N`7!z=L-(IqwS(E1e{E!wz-~>u9c>GqIP7*Ojk4;E4w3OYu22_2Ms9)4hT2 zj}rr*8}_@r4N;H8SX}bI`ga~Ek{9Kt_qDRPmvd;T3RTL>c-dvcS3blYvmU?G*SjwK zH~N>4x-sfVEH#r4V5CWWD*7 zdU+7h6u}j1oV4jFU>nc7OidLT0r+wn)nkgMDH7UQIkWI9NH3f?;p^z)IV}daODR0^ zVI3ff)UM-FRbE7oN{Mbk>&`jkP$U=L4~!7(y_wD?sG{;2Dl-;zu{vv9ocwIfz`YU& z6x0vQ+glBj=ri)Bgc3AH*YXeEhB*{Er^zQi5Ey>pUS0w-Fr{zhk&V>8jq{e!PXsEf6iT=m^#LT2?KLy_6f~LI|J4tDN&s~c# zZ^*l<(uvV#uwl|Yct&Bdwy#X`&U?~2_i_E8#cTG)sf>xvzvelGnvS&>h4maY!3}9- zTGM7^0b7t)5LkdaU4qgUgA|UD+;QT2x+e#Gsw`c_VK<@JN-ZNhx%=gSceZ`}bSD1v zHS&|k-(ahrDX3bCL&>{?UzCl83nr_-n75h;eH_vQ>Pf9@oQ zJP#YcZa`7LNuHHAf&YRqNP~|vi5_MzY`NT5u9(7HYfeZtzctkpSYZ9|P6STC1U{nO zP64uk{EdN+tO0I&fR7f9AH$`cw}_{h6;iN;!r0pQARw$=^$bDi`@i=Q15 zQu3q!Y0)f@F1b1?^I;F%#NvLB{b>_Q3Bvp`ACarb^z>nkA#HQrISfUG-0}C-R!igE zOGWfmT~_yAW=~DY>?M=TPzEUOEPwmzC$ZAqlXk}5 zc8|op$Kln#=~Nn{4X``p`<4-sSLxRsS&v>eqpIR)n#XCRnO^>irNLzs*`JZryHiu{ zc(l#7_;krO;cCWeNFX_r_tPBAYVK<|`k3ma4Z54mU`aEA!xA1QU7<<0qF6*T6`7My zKFO%<*Gj1CjbQyo)1a~jo&0#0%tzy^Gc!|@!r3j>EICqmvwwLRE}gdrb(+03PgS3$ zacr&twouni#NR1Nz|vhFpTK+>ffes+p)T&Mo_DsKTdp(-KVuB3BH8+?U=SrKnx~YJ z`R^IG#A$z1X^!i|>0^&I{CHpCLm zE>-4Vrt18LM%t2;${R_`x4joj78t(<*Gg#H*`DVU+vj7msrTksUWDgPaKSl0y=b+FHveD32I>fq6-|?@*H5^_lZ$~=4`@c4sc4_ z(PBPCi+{9MXnfk%;Mp!9etb@YZH*%*fF|bngYv;7{wGYYyF`FU(!eg$)(<<-Zfa!U z(`2}SCBT_`lFqdn^_!v**j@K>gI_YXHak6fqGZ>hD8JQwa{sdbet6y1#^;Eperv4$ z)K#hO9LjZa0%jZQaMGltV+C^aV|11fGTi*G`9&W!T3-fAg+EEy2z62^CA6 zQoK2Lx~fRLE^W(yDacAw^jSCZAwD*~zTohYRjv~01C^|vGr~UbWnc3mVT_`ejyQbU zLF&Y%NH`-R9CrvJQqGV6yB8#cbR!6RLEW>#tAA;?jp`~?)!G9QSV zpGm+x?4f<5Uw;|mpPtzJZ;g@l>L)`qVy1lCnQA7f`qVVbs$_hFD_&;s?c50k5(F19 z2>oJArF(dM(M1DNEj2qwion~T8HMs(nB^DRu=1n}+l~1gK+M-;{dH`LS8!SfQ7lz=f5 z#xwU?bA0Ef`YEZ9gg%4;R}#aWI!91^Y$e_UZ>`p0SKv5e_N#_UFuVh#^$rpus1|^2}3FBWmzwfvF zZ0|cIdUaj-DT0iRK9ERSiUrNIPOZZ&RN=rfdS-!XO4DktDN#$Fnt}?3D+sK)+jdEr znLd`w|HJ#!pe$C?E0nAGgX!7dVPVV0V$Ydn7HfX(k@^?rB!Te9O1h*czCJ#Rk033q z_x6_KkT7=_$B=syX8w6@={`0VH1zzow#+7MEWX!kQy)393rYg+S#SRka#t9nzG)Q= z6lJ!BS=IBG$(Cg;EKT016&IZI&*G?&bw%N@hxAC9Jk&5JBgOU(SV@H~HrNL|w;*|^ zBeQO*%Gak@Me8^2&W}1yV`BktGP1Iig!7af;gNRxJAlN~-fmwVJhzd67H7%MqYi_N zy26|IxgPFRWoAy05j^SMmk^>@l*WR}@7B^5zR;C=MCqMM7g^{2O1a%FZbnbJq{eYN zVnq&y_3PE=W98p*PHr;ZF1tOeXq&=Q<^7bG-5oe_Oy5w28x*7=Qe;YEg8?zKbFh)b zSa-WTpU(g1wor%Ls|i;%ePs5-dmdqXjw;3v!D<3_X-PXw&CdT0C~`~55dlE{AjJZo zloF4?SJ;QKnFaP&)&u)N9-fF&$Mu7P862Us6<)%J&*KALnt2FFjR#g$NZmi)eg0y~ zLZ=P+<08H7^iC0P(q*axHX9KvVZII34WON+#03Bz96vQH4(C*;93Jw~)}T)din5Oi zX1V@MC~;hpEU;|xWaN&Uv>N9w=;Nimy)V)pg2b+z1&dLf1RotUfoCk_&H66JZtnDC zX)!e8+3hTLXkx*+R8lK7KHdASm*HlzdlLQ1YcxiYMNt>uCHUj981Keid!(tYPqczg z)}>8c0E|XoeJ{I|!j%F$culh?bqtMG723XyME8gdcT#i2d=b<@Njrq4IuRQvn~PNS~HM2ZhHi6THEmos1g z^k_o-810+fMA8jmdEbO5Fc(8=M9@WB#gk|+@~E}Uz&G9ZX`hVy1_+-~^d^|w)Ez

LhOqa^iAs*p?(0S>P>Dt@yp!MAnkqp z32x4g*0sx^$^mP4h#fjl;1?Mx(E2_=H~)-?oecn3x%VlIl}G0sTYPV_#NbAuaL79v z@=#J9UKaD6LYZcWR%iaX^9;W$+5y~D$LLmH>hYBaI}o(%E|YYm(Q&x@ysh+6_+DUv zsA=gi|3&|n!QNp4WLNHCP=61x`V?I$*j(?s%iVXye~u~#T*tKuZ1+aaMPD#w&0_1R zb{Nbpp^%gHVWMM?BBF98wy20x!Q{c~`uDYVj?*Rj<^9vPy!!4g(7u)L=4}DH#xYbJioVW7m(?B{>wjxnHFcu}428@HLw%?&)2KrF=6@9QRcbD7qx*3C&6vt1m z+H9HmX^>0xDS`2FQ`LKTM4Fn+nuP#jn{IgVm%AP0lEYGaKw^+6(W}A2z`sf- zaPc-IKUd)kgVSDyeT3Nab05CdVoBFKtWumWc~g=?H{22v+ZB` zko%&{;=u^$XMU}u&H+F3?^ z>ay%N?gsB>T9_<3PCQ=6802&iF!)nCnYep)j4Ub3c8Nz9PaS;8?7a@%?4PV>>unrS zZGHXAp7`D@2}_VkaOfl1UFq5_%t~kp*H!R@eoGGyb{3y9y;Fem7*s!QlwDAD)EsQ1 z|EtCJrF!Kn=s$o4_po5WxMoYusS_T6){tsKim~g*aRJ)25c5qR}6;SB~U-fS@>Ro^x&jvCA6mQ8;; z>vJ6$wmPG8SWWE(N}Po*M-$Gq3cbARm z(P71}cuN&IAFUOH$tx-OogAd&O!=v$JlkE)`BOM2aDjOiHa0znB<~^_thP2c2@z{e z)eW>f9UQ*%iH#tKLkBrKd$kpCmK)I&n-7`Am!**hY$ZVn`A2Ct7Z}MWgNcI5e51Dt z@Z*I9nPFBH6~5;x-O*Qx#8Mvyx2y?hz!?y)11RRk=N-svz4lijYpKZv(*~MBP@K< z_U_~1H3ZPVI68I|p1-0)HF-_$Jp#?M$7!lXXU8K{^R5`)e|j#v586zGGmWfBe3-rG znmYSM>UhsCq_bDVi=C17E%~I-W(Iz$N{fU4XnVt(hS(4bcjbEGir0ZyYx|0%Kq=!c zPjxi)_RS5A%6YVW6i`;?+e5nLwa(A|N}U_w6c>4;W+&?Ry4IZ55$Y00ERic>Amy|e zMBJ*`B8kQd3+b<~<30gi?}+wq({13+4H=}f0w|LU|Bs>X&UI#cdMEfi5mGtrosg-{ zg=t|kd!ER(tmQOLik0%DnP?9$6*vK>ANwO-B6hgWX$YOvl*_Efb*^&0fe>MiVOCm; zjY&!>+5GcgVOg@6P26NrMp=Ah<)GtHT6sYG2NUjnqmR0HWevmq_53rC-*4NDo;(uc z80JRoE*yQyUx{26wDcw+b6_o*XPxGCRTmQhMhB@sCFkxTsj7kaN0I<8X}?USYlN$JLN_smtXa(#7+#ngh=pLl^qyG1!J z?<;fpDlU;#2sz5(xN5V8uHMt>Mr)x-C%u=fJVvOE=Ax{s@uEE5Ll@>Y-PGCb?68r? z;LkVtSm|fhtM?chUuLn2-YaJrju4p?Uvr7u#s>fz&bju9IMjT$| zV}@*N+^D+MUiZi_tRy+fWvnO*`(S78Hhew=E?kIEI1WyDKGr+ zo0RX;FZ%G4zK8+L=p|7$ik+km1ymc$o+_1YLLpoBv^WSrlXTsbWm0eED#0_Arl|{0 zY|?+UQso4DciSaGejKEOzhx-N?MvG;9qv#WbQt@70I0oi|zRL~WdiK;ho0`ujT7Ugl2sSC5@jV+CQ!;^bDRLsK@HnpiAHn@$qG z`i*_T-4&HNEspWO`J=$*FvR8=U|I-5ODl+nI;oabS!pIdm=u=w{E#wXVxwf+?B~@9 zesL$2s&%~-vC`v7EA8#w@aQ>!Ewx5N?DxeO7IfipiI#U(F#oF@htcuT86N7H3;`f& zgya(>WYexM3`8}e_s3#ZQn4wgq`juW>6R!5#eSYdaj#+FW3KlybxHTrD|}55Sd$?x zc&OslL;Q3@Qc&`}bgea7hvJ^%tXP2ga!{v=qx%igT7!iEw3V1RNPG7^>vy6{xz2T^ z?Yp^qelqW|1z`2a7%LK3JiXmCWr%4j6M4We7{`7r%}gXx2erAp-rWY3If~TCc2S@16dM$-nGxrtVF4;a!00+${`1`jK($jqR zb-rv$O2NBfO>;a$&OWX~B53pDF3B z$0075SqfILk3}QXj+&|#V8S+&DkG!Hv za_`eRgh$7;X<`92PeTSgFa9Whoj)obHMt^aZ~GPq(z78mO-~6d867LnPSE6Lk0HMF zqrrje9^{X-Ic03?RF(U9$X#+0T#%x|_+>ealxT22hWVYGej&}?IBuo+V1IE`F#4wR zbwnu}GG*3`|GTrZ&8%u;%BJ@?=@N13~_-oM$(<>X~XvvWrk9Bc`m12SBC z{K*O6TTW)sULCJDgV*_Vb(t`f1PwVu|Rv7fV(LXbr*h_7n#(n6D_KO5yD9!jH;FcFP%Ip z{@AQ{VaAD@$u-||eBbbp_1eS>5$M6ep$x|f%Bt<~r7k0F$k=MtY~%(FX8?uXaB8bS zbfM5=xTa2YFBJ_|c-(8l)04%>k1iIyZ7%A@C3B0}NWHA2WVIai*0&U@a$o~69Q>Kt z6Y*nn)0?*Hd8}Xoxm85Z((GORD!2ZpVhsWI`+GOd@!8n7mn;pX8j|9-Aj|{E?7Ud} z*Trk(k+jWPA_|;B19=DuXjl>}zK`wa=Q`rYkGmoIFe7J%v=;FCV}f`H^VyG} z8eFE%wylWjU&Nlqjm#a^93nK~2m7`u$&61+WwB+438XuA=$SSd8&A7^7CSF~W0MmLA`tlSB0llq* zy30kdK+-r+9h|0}t{RKvfF#HGykoGP0bEFYTY$>AFXwvdI>C%$I$49-jN7Plo!NaW zlNkwzz{$ieTf5!#)S+utp{7~M%O8!*EyicJ%UsoGF_rI&XazZLt6Ufdo9G*@tjVbZ zPFIOyU$usNy+_)G(`p%ZlhU-lrKmhGp%#uPGiFKh7B@e{o&?-8S>HS%^XoH~!|DC9 z^Ht*!U8()UR}ILH?Jj4$u9g+8PAp8-z5y!*;F&r}Ie;GxoVzN&HtMV?82_dXx(y#W zmHDc?-+G>m0N~9Y$UL=0{QX7Z_@(cgZ5m53(p{g^fYY;4Y++}IB>F-{#odLynt*#N zpg+D25En=)IurX=dr)ZKO=j-ga=T0Bc@BBCeN(A(mwvp*lSFg$YdYNm3q#4-A>1qP z2+NhtRjKyB)UnM+-HO7s^5x67P$Psc(#M(9(&AV!~;mav`Om+1y?8fZJ7n(8!~qBd$>kJ2X})S7Hl0_;w4&^^(C zUH~Yq38UR ze022ZS1m}uC0mGx=Mta*FNaf`1w1^=jM!!C-hSwg31WHW;b7kMyt+&Jmlk1ssVJ3X zw$(+yM|Pfmbmx-bK9%S{z)Lfl>=?@!nzPS4({|nkdT_%039maHWx_O1yfvyrg4;hK z+#(jiw3(~TmdcU%JjKYhiS;c)WhnjOK|ACcyacAePbZ_MdY1Q@QX~Z z2A#=Ri?lltLv{_2aNRkchg9viWt98!Htj=^YrShTPruB2aTABKqn|e{j4J0Z)!m=L zj#z4{yGX97*^$uT5vPWYjsANtw4tIdROP z0(+-kp>YZscG)W2G-+r&>4RucOHFmI=c6d}R!m3C{hfkX}zZS`_ku&m1Q_9R0Nx7c}B<>mK zM~;6sL8ZzKSa`s>+U3hv7~2Y-YUDaXEDR@%(g#DxCkFsuIm(bmFgmquu#I`cT`x}? zG7RIQXfwqrS&Rfq-4rwh5l>|}i_LLl6s{1@?-XG}3#r0On*(cNT106gp3ehOmXrXXvX&^rM!c3q+FuK6>%wM5)zqXk7n3{(FqiNQ zHiXRd0~=0E_S4*CK?$BSa@1OOJKjxsfgV8O2HN174 z$%j|FmYSs6bqe-351OrP*^K=O2<6-Y$Gx~;55)nboD?wLYcR=YX-sMcN~;Z$rWR2G}CMU0`Z*6(+SgYeL?QRJMHgwjXj zulu9jiYh1|*iCJ$0BfQc8(&4tElvu+H++Z_KIp_q|oa!uu05*-r>+ za}}4fA~6Jyl4|Skdt719Z^Zr>RcHazZPS79!{f%pBdb`4o`sWhu2SBfo$c;ECyLl3 zDmWHDPp`Rb%i<8wv(WZD782l3O`wv8C!HW9DuO}+nJ!IA7+?3aP8IYPj_)Sro&yIZ zx32HrkR5I8kqqv{P&Dw9>KGHXN2Z^@gf54s|~K8piVWsv1Yw)5e{L>ba>EpDxyGe)?9@x zF@i<<8Z(ZzBbbGpKB#lF$YbM>;psp+cMN$0|8Ow71uIMaDwvF=Yx7EBQ{(EvXCT=c z)RLj`-krKtj8t<(dIyMUYz6Py7j@pyWQ7kS8tPaj6Lyn{#LrMF1D@F9V7`hLnoFy-? zqS9n6+x7axzG@i?{y$fE;t_XM~A5-I= zum^@|8GzX7`#!gnBe3FlRCZKZ3XauYCFWVVo{I+!H&Y~?i}uK9KW0Wt zHM>Ch^C3~7#9}@PR+EIKU|LLbd5r^|wfUm;?Rd9{Zle>1qlr`(;^k)l+on}8tnIE* zf?4a9h%ZM3;QEa?Dgb+DMx|_VfZoFqyv=wle!E?=n9i@2jk!l45urhzBBzIsVrQ%L z=7maXQbM{HH*joZ21mUFTUqTQ0cDyp zhL>-6UGe&5biB*f+Po+_ZI;i;iVg@Jm$m~h_;Bmddqdg;!~38Oe|)>YH%l^i2j_ICD4eT@FHhQ}RY*pAha!e(c@F%QgIXgVQKw zzRdic!a$!x@Q*U*KFkA@nxi&o=vc^GUW{v5D#KpSEpbMP8f}MtXl(NsYkrpx+{`VA zx<>s2G{Dq8$?NmWgQSgMGL&BeohiDJ4PQBcBim)WgiP`NW;m_8z@ue=>~rbWYfLH$ z?&SQ#I9c3$woIaKLHFQSP-BOE1-zNSmI}y$87SU8i^A)7^b==nk$62*uonTz&x~L# z6%dikQ!~z8BU@-c!4_`?Z2l71rJ#5saj&aFDDYJlEb$>akvAz$^ajr@fac!qk*?ic+?XS6TxlBFzR%BM z7HbDI5R@*iLx#|2fxwx9}Cn(6Mz^9f7#LqnTbjC7=?mTY-}7tt<>fW&8KgWEi?E3hk%$9NQ34f)WmaWCao7F=v zVcuNN>sGx1m68Agm80R${>8=Oxp{Xn&6nRGY}pR=niY@~{%-=`ulr1(j$r@L-W%P= z()8>NogpXfTE3ov#@FNf4qE$M(;TrAHEkX_Xd~1f2)6>kCoL9U{(-~nw@M<4NL_wa zYl8+5`GNgUIyO2<_G{!+fnvh23LwME!~I~eNB*WNV039`&DHG3jc(wuLu-nQn+WgQ z>u`$fNf1z_hZ(6r|1{7%&f3&b#a+yRKos}=t(EWJjA)g!uz!HQVJfzgWz7DepVnwc zd>Z9#ZwObn;>~@t`iHJEm0k2v^RJ2aa*Sx|Mt`ySK=R<LFwlE{B< z-+w*1RyqtxWc=&HIjMvBZfm-uo4imDyFkioeCbatb*k140ClWH)!S5J$}rGPkMgQCY4ZI}MqM_tE# zldk$%w*)@c)9l;k%__c&&m$trrEpW;)0`6fHLL$V@!wb?JIdu%oZaV4F#engjm|(o z=|Fa00SU?F%n{{clpCIe!evffpQ8asL4b7zgliV>~1VL9mk>t8Z#9 zochyqK;7ns88&NcW+VscQ_K+UYzPa-Gh8;HK4_EqyPcDcEt$#2imy6JZGZ;UVjZ5E zr2wz9Pv=RaC`?8m*(d>Y0{df10p-)Lf>*u!HfF@FVd$|&O4Za|Gb_R7j}>`i$;=6F z=Hea_aF~ALxN7mJe_yb2A>@`W=J{fB13_(-(aUNDC6JNS$TEpd2#l$>Z!S~pIA%q< zY)nbWm$O)?&N6=~$w!g0u+zz-OtsCQsIWZ(GBfW=7r%Zj^H?%=#F$fG?k+jdmd0|4 za`TOc2;p<*kw^$WiAy5F{g`g*k-4j{=bd5o(T>IH6tpdgB}hnu6{jH+T1RSXL>9OO z8*fMq!{b2rUWMO)ylnk%x1A+??V$^?9*Ml7rEIL3Eu-eVc?`*yr5gp|rECoTn=|6~ z#m>JnTE}~7*-MR+$f#hEwngD94Q;eW3T%vwK!*2m(p8K@Z9)$p`r?8l92=aAga|cY z*n7A7#e7yd&aUu9JK-N%T388H`5xe*%f|r3&2-UxXJgHmX!}vRPfTV>NQm|u!8xhI zG2}mhu(7ym9;4#h6zg}pnELW}{i8btU*&Sawu*=K{i{DwR8*a4GucD=*h5G_77mk^aF+Poe zRf;!QK~bdv_rNL{0m!@JG7w~Un1H}elnh^Nm?N?#GOGyq;= z?*8&FV$qgl1Gz5ho(kjKEZ;>5L(s>vGVEvEs#K_+uQ)B3dp*lteM$RW83l|OXpdBkVrhJ%sfv{lah39jMY#m-zJDc4-ulZu z*z{8Ur)hGu(5^{Bf?7ieNnPX1OgnF|u--9?tOtlK&cky}y!vU5&8*b3h2gtF-D95; zue1_U61xodW{M}s`DD^?oE7FX3cOaCC*@`ynVkl6=%z}&5*$ZR zbFdpJBK!L4guv&jL(Dk`X)lQ=nDG`bb?X*-XOV7QWM4U&$8JRPP79)2khmSX;u}K0 zRCW7Ts=R(3Wc;$RQaig3!fLZeB)t!YX?7Lqx)HzEr2I_UF9OT5n~$xXtDxmaMS;JY zqr<<9gPK_c=ON2^%8%4>uW{cek~8l^Qc`Ti#5Q-&u0nB|KFrWX0@A!bIQU;xdx4g} zfSklKucYPQgVZHgzNwtAaS-k^f^kpfCZvM3Pp+Rh)QHquE*Y4-GP35cI~l99)^y*-<8Beb6KTu0n@X`>u?M)%q|OBZe$ z<+_TGjdDsQ@6F4eZo#d8_>FfMahG0}mvYd}>a^9_x%P*GAbG?&rKQNDqgubmn@8I-qGrlu`kdWZX;$)u(^G)rg zg-hj>i!0kX=*~CkbDXR+z#Nk5DrTtMpK_ocabN}80dYi!pW|6}0yT0^93ot_u0aX~ zCgjxm?tj`t$uMio5vg?Ykdf44_>>_~J_L~Mc@|ag0xej+UJ?W@F7I@kk)&SjI}YexXY9uYBPLYVz;U((i0e*DF9LM;t5NK~ z5EB!@lfr$eFd@Lr^UA*Ak9w)Y`4oa+E1L-8=|-Av&)R>$hbc8e#>*s1PS!Q3z4w7h zAC&V=2s9D2;LHocIOqUA1l<@ay@GopT<}iQuu41(sa9sVyr~!BHC!OY+Zc z4(15h`|LstTJ5Dz&8ppXgHw_*59?tNzs*?1d`6<~Y@JGTVE(eo{u3z;zT^Z#_?v9` zyza_s7yq+)d-0-WZo+J2#W;ycG4v}cqj)r`rkQYVOBn5uk3Z7p5n%P}g-Q9bJhJhb z-Uo=i@K|HtS<%=`ct!toDoCMB4#*&RNqKx`DH~GdALD60|6@)!=HxgSe za@hIUC(p>iXz-b-OtVJvmRsrcG{0W+7I@?^1o_)DsIQ@yl%1U$^BMt^_%c2IP0#D3a%i^yjdY@Lzt0DS)$N}i%R=Sz9?R<88a6>sQj^~HAvisY3nLN$0G!0^ z9Y9_CogXy?Dq6}T(Rp=#Rq42TxSd7KO)Hr-8{z)w>GOkFoP`}S+>&yJ5V;qmzuoPK zjxL+up>H0yYafgGQ(v+{(}W27Y_hKNHy!A9)AN(Us$_?T=_#wZ9cKTSRJa)B*+PJ$ z)dE&?NLH%!Agl=W*|#$CMBA>qWclDO_Y^9bfyW}L5J+}IVh zRb)iA$YF1*$3>Q3zi^!WTuBKw_(ppf^XBW##@c(EGNbcL`;16yYCUOFySDH$6D+26 zh}>?WEe>s~beu%6&_ZEDy~lcu(2M@2X{U;L1l5f!Zaf)d2yjj`JO> zs}Sdp?4?FHG1ATCd`t6R_uqTS>Vp{0J=dN~t+>P$w{xq&Q4Ze=SX|mUR2^~->t-E- zfcVhp10VzFwDke-1Kd3+7fW+IdpbWL}T; zCFC+#VSfcHDZ5C#B`!)?+WH5Gn&Bcq_g{|J@Rr4-=S%Q44#5bBy&4bEEM1{9*=&@Q zH11Db!`ugw9av>zNIJ4Nc8uNEyAR@Q>YOING-b^ntRq=(N(_Kao$@w2itR$LQ?1vb zqwMFS`vzJ7DMVHFmh6k-nEL`pD3QH~bCyvG_&R(}p{tj9md+jvf%qCC5R*;1%*x7L zc#>rA!@A(4E{0N9FUFil*}DcI#bYYcw>l}+rHz+Og(c5ncr8-3}P+o-QHZJsta)z5V?3Z`PP4Z^R`I>R;qd(pi*!Z}4p^4eq^xEXs zU6l$=-U~i+0qrWBVf7pa>iqgyf+I9moqVa(PPl)fG(k^j==d}PuRXI)RcpUl#RgQK zLgWO6@rQ16cDr4ZnT-a&qV5|{h>{9*+oNt*8u=>~VWjb@$P`gJ9Sut)P^$-hl3O1q zE99!&T$|^!{4%mk&D2ZWxPQj_Rl3Q52|7qNAzSzl6C?BWm`FR}D$)Fr6v-{IyNESw z@R^CJwVjDe`jx!ZXeoCjoX#6bl#LBQ_Y9g76CGWDQ(Xn*vd|!b@pFw|GV_ga?kvhFL93RLil^oNXdlZS%&^cbyHfcy}Zsm z5E}Iv`wEhVO21t}3PomPKA=P)5KNNq#elLqT|Vc5oiwwE#ztdTPTmzaSFturOyN>j zf<@uMsPx2|&N0O)Kh~tA&*AHycTyl`&T`zCU6k90Vm`c?|6P6z@c9R5Xa5HnmB7>= zuMRNE7(*&qzpCL?}~ zXZj^^>p$ldjj>4AyIbRTO735qw?EKtMUejQ*YRd}=*jXMgX6!FW`{xl>Ak<09ZUU?}5RnYAf?f zK;ued#~7}6*bN%(xJg+Elb64UIa}_+>*FR`o*hLSeBWu#F(V)+bFml%Q-eN}eSN?R#h>UTWzLkmhYi%Th*ltUWvaCJxdkjnI5Ep85 zi7p*sKp=ntuKGwT76~$Bi=+f)h$@I18%iUa*T|k7Mfo6lWT5}Vu>Va2ay+83Bgxbu)dKjThFz6wzK*5<$M|EK&(aIs! z!>jiKLgM`@{MLRLnL7Eqj}Djoze$<_cj6=rl4AmPbT65X9d4uZOC9Oso}O)5v+Oh8 z&5Srmw=jad!v&BC%p`~Q^z_iYU9MTRoypPGo6k8xlT+-QNRAR>yTTHMwywNC{f!qz zWQTt($H~S9F=6-nj^G_B&jsTNkFELL7F-lYSP@m65?2>Vd@$SQ!{IH_Q|Bx=DVc9L zcZuRKA710v1a)iflU;9dhbey6#b0^Q+w0v&|G9YsFf^q~dO5IYeM5c6Bf#~^`A_uVw2abKHh&s{>-fcE;7t{EAC-aQ@1n!FKUV;qpmT^DJvBf=C{EgM}JkQhdt=ISlpv{o$OSQU~C`B6-uIR0sJ zE%_%Q8cTG@kaEE9WDHD43TA^P(~y1ymAd}}px;0C4ZPKEapvnTA#+Z8m!@9ts6L~6 zulkX-%qD8=dUBq&h zAl0+OOHY$EiLu@y>`{A$K7Ual>{P%g^g#s zWA1{dv}h?EGPj%IcI}p*5K=+Z6DV4pbf$l4g7sLBr_FZy7?r0 zB#%LozO0;Dzn5pVDuR2GaALeNXEdalq_vKfV3WaT5q=FIM~FdTrQK+9Gq3LbL=jBy zZTsPX6GdQOT!>y+A!4%uYcCMYW5jycuru3my{Mgr%KT2(wsj@1w8rYZX#c_1NFk0z zlmoLcG&$CnQgrM1i`P;W!p-S`nj4X-TS4PA?CTd9B`Y|(y~M%^AxBkgVSfBm#bU*L z`$((xcgk=eF9NY#?r@wl-BR}N{s%fS`x(Ml#db%NL1>+CwNC0JUV*_smaW~yZJaWud3pZ+^a?LU)yeDDgaFu>i4)`E-GZ6mx0_AZ4dmjc z_Kwcc0jysgqTF6^0VXvysrHX@&9Y(RsfQ$Gw*BAX(F88ogfADoP&12MxvJ6x81^vZ%+dK^Z{ z*M#6^8M-FG&R>?Be3>b^FIv)f<*pn^@VF zo~nzfCpg15L1KH51ir7t40O|SDLMW1I;&ADn?6g+;Hsu$ZO}C$Uz`^FO>xD;Pcjrk z64jZgriO7{d=h6$AFlyMRDLA-AFmrI=;kqfg zhdwKszW!TTw^u0xGH#hQ)(zi64QG)&C>vz|G$r&;S(YIkz$@Dd+DjI0i>Mt2 z={K?LW~*MP>lg-`5LE<}LfSOQ+FQ4yuPkgJ2fb!|zO#5Dq{6&=)l3iYg z;UC4l&be0TENb#AZ)ksCwslvcmIuy6kc8%9g0(kUn0a_&jg9Y>t4kHJZa)+!%b!iF zGrr`Ghh&j}1ID?+W}`TOJ%p1Q0scL7g|5mDgwod=ToLRvA(;h%*EnIpmgkBpuCHzy z8j1TK8|~K~a}aLRSrp4Ekk)D9LEQ@ZQ-})B66EN$Ui`e)Y4C0K^<6khJ$Vc5mYvNi zNqhO)CUC<9pP)|{e^5Ud@AJO*u8QfB@UQRjZ=mYKH=J+OOYXo%=eRxl&JW@70R>b{ zNx4TjmpCP_63y+s39`OuAK#j^tGdr`XJwU0Q#p0WacF7}4HIY|?O!R{xN1DCvX-KM z9arX>q*eA7hb8iIZLJmvV}{-45p@?1?2J-|5b&oGhTDFDj`$a_pda>uh#Zk3&gRb4 zk~!riJ#FHxrij9)UNN>6XZMnW3w94oW6mFx)@K^+qst@E;bVI_>S_YpfAW|LMW#Rl z{P@z{>^Nno#R^et-@91F|DNQdkv%*9eVsWl^bpPW17-kU0$%kJ?2TeDc@jtV+C7o` z(?6i#90NCzIYeBkceX8#=wu(Sp-+gw|K@OXw|`jmivOR6CG7)7OHw*7KO7W(_&-MM z(0_mUzr^K#2J8uCboT$7z5Rj7-tL|Mr!J$>m|u}!|8FO@`{#p-_W$L~{`dOoG`Qmb z%ZKIr&xc+5fT)!D2goA&2UuDl)R;Uvl4@&yX*JcT-sXQ~-xjI}5;%_hp%ZNMnNYh2 zhrw66X4&t5y@$M?h~ddqlaE;q^`gMz$yq3W^I-(t6vvg2+GE|XU`Qk5>}+m895HRX zBJ>#NZKDL}M#oFHfm)r%-&uUM`p^93IDZP?0c2Q%kYcG%mkeu*W_No@;)M9d zV{_r|Ti|*1;q#|l8Tmr6$Qu{x??@d=7x%#@E~&Z-a$xrTp$R|SxB;3h1*-toT#}dG zX-HwzMp}>nNfKsl$eX~u@jVBSh%B2!s?O~#hf$&*=y&^w%A&X?`+cH7u}fK{=uz(t zN?n8>$6nPuBp;uhdCL-4+1}dKV)XQ^nZ+mZ!{S_4eyerLogO6Nz&<%}jBAYTtGN6C z&Q}k-*MQnA_(@|W0U4@lG&)B)1sdf{JUK2rBYvu)0!bNW1a3-RTtqAw96pP7?c8idKYThrxoO)JmOs;d zGKcq0N0GzXo@s@7cm4NZ%rf35j8WMlCFls{IP$OfDg^_s-*@2~~o?BvLo?%rzN-7*q!}vo|&t9*&q~)~rXVxxLBJDp|g#LO}&7w z!sTg0!}CpNB>T50Tu%I9Jf_6q9Y9)%FB6%wM1irvcT>~cY1LGpJQ2yln#eUByC*yx zZ*k#`KGFr7amv z1r_|3cFWtE?e~M*9m!T9J*_}>9TzHabh?YlKFf28G`$%I~DR%&W$;{JtnaS2jGit813WKYt+%KJW?ujKq5KW+;xy> zu9^!0La3cLmK-K8Mg_Qi+g{8r{rq#uGh?kz%-YijE)ca}mSF~Oo^ z-fybKBRXz=g&?;Tqy*&27k3y|cV;o$N});<12J+uRD6Mv8Lr&c4oyu*0|ZKv^8=Mw z?LL-;h9B-u;-weiR%Rv@Ce^auMwuw5a^IXg>N$axDKnasD&qi)#P6?|_8h)lnI`xe zx&Zz5C*8|^Z9JkR*3{8&N>a;G`nge*H5@Elqf|%vx|#$s&9i`bFIpoydeYEj^p0d2*D=3+rSj*S`JkrN}*s@0BxA zO};-qB~|N>446^K{}_4&-=@!?-$l|x3s%0e-YdMjo#4ena9sc0SaYqu)(zLxtbkoM z#8~qXozBJsLm%)Msi}p3pgFG#gYBLYBPb!{=bCuK^M8VRuMnSi!zAB+!R7;EcBFCGX%T_R-O!GwCS_yN3T-cmYDBK)LHdHG zdrzlA5L=81U9ON)6S%B?wVN|~!APpudoo}5#JDBC%~cY(Ynx3ERqcD5YQ_Hd{B4lu z@nR$JLDSreg7SsDEHr#D)(Xa|QwCPmQV)s9w~g1ew3z^xM(vnjG17za81;a~RO5yQ zXrUUG%EHEIilk44PK&H|I``fr4IHaA4!0RfX?1jMV4o9M826)5f*MXCBTx{g2s-8- zK)dqs>G4wq1ck8wZr?M@i&jJ!uxnqO|nPZlXXcg z@wSgEus-2AFs=9Tj+ZrvKi+cT!eK_=j+_}LcCypQ704>vN#}jA%Rs2sN(3us1l@e5 zp=`yo=|zkU;~iVafSd2`mS^Q5Y1BPk9eM#CSbq9duyGSm)F1T^8LQphUnt#?hOzqz zDl;8Yuy>V23ZcgxfQQgMYJvps05I={NlAswZbmYCBMP?RV1*z}cQRBIH`^%bA?sNlN_?%99 zMu*heaFM8o5IrHktWDGgkXRJaB8fE4Tkt#Uo=13)9^q#?&1C1`)~Sf^O7z zkAoSiniem0=36`&&|A2mfx_*ltI-G&$N=|CexFi|i;8S=mmJfn+#U|%-%}ul1CK1eF>`G2)y*q~6t5>$GLug9 zcI|v5t1uTnN({@%*xtKny()D7MX_j{klf;0ei*fySbk{{`%Y4gcwxy?)Ac=bV&>iAJ)+$kyQOJ}E<{xt8F+L}n97mH=Xhw|q10=&dI>`cZ} ztvqgQ&?G0ofAq7kZg=VrKa@@)iZtkJEOYnZ#|x;@L|S+#fUI_V60MOycrjYTmQggn z^nE_S(0yjJhG!b~GD**MRiP2mv?)VxsvyC5MJ3Nl20*AVcPV`qW7Ds7KDZ;;WbqOf zE&eUhXoD?Oz%U5OXn-R5!hat&j5p)?9xPK?b*tdub-UAdY5KzuZGW;U7_ zfNhR~+)~fAiN%pF>((koNR5Vbv|Nnrd|6d}Q(DUmHG(+z)W^g6zOT1Ns-Q|)xGJ%D zw9t6q>pJpseZOxb9HbwezU1%gDq9}t@p52Nf#J!kWjODk7fe4B8wYaJ&(vIc$IMOc z_cOE!LiiCYI(>MhwD@E-(Qve?l9e?7}8)C z)#5%Ss`$j?N>Xfk1Cxu$YrZ!Ld@FfdUkyMJ#a3 z>M)No`X@wfdxd;0x9PWIlz(|fDMpou|9!{mK*9Z|Y$HPM`bksZwezd0{MJkNz-PQW zMRUFxPl^`#ymiH~R?u%*Kxl0x`On*@a@%~~?9_<<#*zg4230dE_UGeYdV@in2==A6 zC>7u9fL0l7`SDdC+-yV0NCZ4IW%}o%kI1P&Uh3u-I@5bTz2cgqfKCt#UU{*xx~vwo0D?>cozKn9U9bO9>5|wkem-p1JRbcU zbFVY$KWXC+|M!iK?R?^B>Boi*kDcppW;;&S>;J(DefgiH*rDVNKf8$AGt>K4#H_JU z8S#rH!is3&ICQuySJBEOwo#)mxt{+&Zg9_jy=vIKnZEu^_wbtIKXf4(P>tt zp~QtW1S5J{Epma5YuVKZD7sqESrWw*QgAn*@4lU=#8C9Gr4|%L%Lt|7FpRxdx?AM9U;Q}&!kBp3` z&5K;;5Yr+noUdMy?o$&?i_QBuDiYJ)K=V{tLz=;^If{v!OPfn6<>%O|M!nA-vRbmq z7%7kLL-olrlQYt7+8dxu40eNl#i@J9TDTdSnk3S=4hYj#S6ltoUL}I>nhcsblQFH` zlO|BP21^@Z=&z9L5a4qp=B{_)12WIw%^tp=Vc7Y`E02ws*wl4;-y7pzqKn$}9;%3~ zfAd-R?OyqC#n_||w0$_?Ydy$dW{P88WVQ2ZrYpsBR(_lg07b%ya1hV;6teabLG7+v z!sjW%AQ{*c2~@*iicd4Knc0Jnb(T23%0SU0#e=vLwZ(t_jyM=HY>_W9uHe@z#l1Fm zbWbp5mwq_)4eTT$heAi9{ASRJ3mW3?AEK5l?WbcD8K8W)qbUq51&8zB9_qhah5`tZ zEnVn8I+*;ma;J4%B-vwKqk1mXu-3z3PBC>5NHJRuX=h~BqE?1YK_y_Mp!qf zS7fVkL^EcIlJzbT$WO%{es$N@K;0-Ywd4(PWP<-HI2=f4EPK}0MKxuaq;WcNmV(8n zYiM85u$T;5b?mx9ES#EARxofnf*y_XyK~s#iG>C7pMskL)?b#tvhk{W;0Vjup*@X? zuq5L=#U|M(8}7j4^o82%x+=!>4l;O?OwixM+y&=kl4C)L#*aYL^3>`7ttZbab@sQ&R z6e(zLVt#**^EC2@SvMg>SlVz<6Imzs1|d}1m5d=>nZg8#JcX(qg->$cPYOBL7sr8d zMW#xLXu{Bmgp`6STvy_tJ$eSUI}|&ZI>*mz(0|}=2zPnQ68E&|y3N_G!Koj*R9z=J zt++F>Z~~E;2cJ9w8`r?MH6daAKfaMF*)^k<=r^fPMpYOZ^5nLUidX5=7g`PqLvlXz z34^4Nt-QO?(+feKDW1pnM2-i2=mt(x5B!Ii|DJi2bi(U&|n>5dt9q!8H4(b`~GM?#z>m+3%qB0+Hd3o;bg0(sA zI5KAM{tJlH9sc%sfY>n`!rd-}PLUd`YM)qhGyi_`@_S2ML5uThb9b&dF|kr?Q8~); zdgulGh_~Rw2a_~_e$AIJjK!5#%T?Eys{Tbp;$92+fvD|2%wdqs^dERCK`O4)6%-_R zJJY*a`cv1?F71lczW|NH`F4wI*TeP@R9UG`91txL4$%-J3H zD=!~>c4oWINfWHw#ax0m1Ia?eD+f)DL~rt}lRL0pQJ0O6m^PoPgj7sh4z%^T${b9a z`8r7mUnVhD;2*OAdG0#d-V6EiP`lWP^3I$0q!%ciO8gdKYt(i%0eP6?)m#f@uVb0gggEWQoDC ze}6Smz3iPhlgJmo5rY~ME_`+LPLfA`wXYp2@%b^Mi;cEk=>Zuw^=AIxU%umM3&wya zbKpfqYoqiSxs-Szwol7iBp!Lcq?euKU8QyE+U{ZQy?g38)XZ3*NZQ;>WRs35X{37G zvE9q=Yjm!uGU@~xJ!IW8G2MEg1MN8#d8Mx73IwF4t~g9_M2h5ue->G0ybjC7bU4}% zhB}XBOXFkOSm<@zgiF%Z4NBu8k(dZIh#YGVo%||W`>s{Vh}!NVdJ^g(cb&_Wq1~-% z*vmr3Kgr{FX-D&hXWNkw(vXiRmYXWpYIeb&6vu0+H5RH(2v3v~wHz5+V(<#ZgSY@U zn>lGz-5UbBar1$5j6ps!B_}8O#FBp3$0Phr&uLjIlH@QrCQqkl_Dz#1Iv_ttT71If zsM=;R-CSD^G%*JV*JK;jg*=}B#W=sU8gOYoX{}Of6+h#Gb#i7gK7Fq%MdleLkj6XV ztE!y5(y4IKQgm%uD;nZw#N$cnyvG#aMn8zv=Gx%B?Z_F$1ms~a(67OYQ=}WR)?d&y zw==a>HN}SPcD$k&ssXiky{WkY)YZ_#$K`svwwvz*=Tl=DliRIO z5-M#AfCGn0bP3?f?eJG1sD(zO_0&tlo&7uZfzo>8AT`Y+T=Tg8>j;!HV}vPStW$es zU3?(O(eucvg+FvDRm8fjWEYz1rqno9;HH-4o5A=mKwA(B5F{u0D!0)WJ`uXJvw6|f z@z$j=3-0`2P%f=HoGU#0|{ zO`DE0*c`fTdK~fNr{OL&_=UJKWy%r&3BPt#v@V}Htn#hwms%>&)@ieJwufU{#^r_k zjh;7}GJJjJNGdr$$!z;a{^ENz{-mvMB|Cfc=BIdF*A zf2zR7dIO_RrN#xd;89V9U`pz*mnkG!&p|p{@_!j1A|qLr zyFMDvr^|zRwpG?|$+3%BybLwxeI9VF%zP8` zh;7AYJ&Qi9b_^MyOyYW%7*=>m{xs+F`1N}$nUeqlJabV#djuX6u!%;SyOyLX<428= zS{DYIuT>fS3g)|JLtDn({6)CiFgV{Pi%7i@uH6tx3LUUIiMEemuUa4TLB7!g8gD{C z{6F(vii^!lDGru~>KW~mN^W5!(IAY zf@27d4Q1Qu#~hRi^ZvoMx)vaS9X}zkE~#Q5{9!`qBBaq%cOtRc3OeohLuc)I)03%I z&7AOh1Ym51l;nVYPw$WVg+*yIoI$VBvRkj*nk$)?OW5_U(wZ6%`5BNG%u^w^J;5`+ za@KyHk!D;87udKvy?7Y3a;dug`Couslz)ew5dK+Lg{-b;6S&Q^{YGhQKYv#*>TU3#nV+=3XaOH{Gazc5hD z`-`M-{|)!t_Pg4vfx8{O?)ZH{j0 za%<21bQX{~-$Lz5$j~XR-zdD>G-ZGw{UW!kjNSr`uD9I5&fC{J)r_d7m9f0uI0h!% zunA^Z)5%5Qcp?f9Z;tZw6u-mW(<62t#+dBNK5mH_c%*1HXIXS>uR$m^i$S6%gHD~k zZsJW3vT~a^N=Z+yxN0}=d%aRT)F_Szo_+W-Ag`5S-UqrSIq9*{)h$F9sqr}73m<;ZI;%}y@t*_+wtKD>ozuo?Sp24pF zr%IIw`8ceg^)4v>DB41%uB^GLqSW_%uRg6@0=q>6wSbfvkx|c#<%`_1+;HA_AT!FNsIxFePw*F zKdln(o7MX?g8rNskWTg*X{-oh!6kvOi%aZ$Ch`_G^3$J;DoF%1ROUFPeSS0@%ZQPN zZ#!o2?oW;kM_tv(Om1Jm#CoGEl1FV_ntL9(Wqq0QL5 zI=zNnr>I|6tv-Elx~F;B+tw4AC~KZoX+v zhdu(MQlfxzhlQ8QWw{)6r&oGdH(CpS@+a2pzUjbt`qUEA5Po@pqbieS*D_rw)%?t& z)pQ&!#<$BvcO$<2?w@1U3>dp9qxv(u^Inn<9A7tZRaMgpDEannMnoGgS1AcUrvuxu ze&w^joH?8GrL6~Bm{Np~kG}4#nQ3aKju>>ogX?Z(T10W59pLoKy%LXg*ACq59j?7^ z8bbpGP0IU4S3=#o*E+81sR#)PRj3wd%q}Qg2~K8Ky-2-~U}jR8Wx-#53O>-A0X0Re z+lKn|9yelC&&|k`KP!7|e=CM(XSL6Z{;Y9(-ozVIP6M?8TS(2pB_h(KXM7nken?IJ zx*m0WLnVx^jqM>CpO-MX>3rr^%rBy6-y$%OPMwnqeJJ@?qA*-Dl^{r&7v>`z3hJAu5z9uO%B)au^RU_hv0BD9Cu(WXkc^jkMxnR}7F#^*&OIZR||r zuBTB*_Sg1u8kT4rwE5ciR36K>8J3vhLoA?G4Gd2hZ+{``mjdJDK6PpYG*tw^{dD$o z>WgJFb6NFjZ=$rp0;ZNMgV{`E*xNvt(slT+e^d)8QVw8fAF{-H(@h`gmJ-J zTht3+HEya$5E9DuVG>4s>YUri0JvlnereP&tkX6g{wb|B70t@-T@*}N8)rD1K-=&~ zLU=}&qQym!!A$D(*kd-?=TlaezGJYEj~fj}q@qT+fb>DgcPn#XZ^1nAuxI3@Cg=OH zWfbV;x{_npV&w$lh03yHhS!GejXI$Gz;i+5vMtvFITfmwhAApb1^3?~Ol+3M=?SOi zp)jo1ef$-yw{IBdy{e1_9o$TfaeN;+v6NJg`oJ+nCvnoy;DTRGMU}-D&|mJ%fIotV zd)0Lvc-92d?Fz_{Xqq83D>D~91=M!uOf5rdDZNkRq$KOn3}xwS$_2N0u*syfEGJhO znkZfEO2mb#Eh`n=E2;D*RsBkN^)gRr+O-2!2W{hj^Vzj*6r^x$NzQu*?&K!-m6-=k z>i6-jlDl!q9wvFh=kIyizkpX(G9lj^MSx*rqwJX@lo=J35LVMIF@>dHfF6`pyyygwmq1oTH%cxQYM)NL6->}s?Rw@d`w z{E~#G>U2SxrlJRt7(3F!aH@@qBeoa#fce(NkmTyoSFqf3gkq(vAyvgSyK$|~8%H=R zuletn9E7fy<5UNfe$FW<-=n>_QwCSL`P96o^5zn9p>iM9Gl8;=8hL)=+IZ%5LH;iw zw)4Q|$HM0fejs+gv>0sNoFcHckZtG@W^e8d-k%2&AHsV70bibk#PyrgSG7*R>Gf3Cmuix z#>oMUay;=p`ORGkhhBzz>9;!i$DOth2z{*ysDCvlxq3BSQQyHQmuh7lvcJcvTxhSt)BIq1E6P510Vx=0ccQ`QjpSej4Bi19S` z%`Wq+`VV-{Rc$lQs%P@sq`aZA`+dIImeqc;kgiEXgXU@NoD47gZh!vkVG%6>+tkWq zfSg=EuPwtpu{aS3*2&XXJX_N16m&i1@5ql?TbM!;Mz9Hd}sU-2C(es^m z%Aaz0&WBX)dc=VII!u#uQ|wE|#<*q_to(T`RA0L!*`k9uXm1jBwsubc656FD5M5%j zTIHo+E2GkhZex7*E=cVaH|NGL!bdM9wb+H9n;AaenM8bLu4XW-Y4j{SDZAP{+iNcy zWEPta2KTz!%&T|2GI@ZLMK<0~>K$YA1*r8qkW7&b@0U@Wlqvzrk2-?JL7!}hLziRL zHPdC#1YPZzw(|ui4M-t>887m7cdh*Ip2w@-8$|dPofIx|rUuGSIQ$a(TSQJ@_uJju z@vp4JHIe<*Vf(sW`vGw^Tk+5|VE1otReR&XGjrP#oq2F_R))9Krn+%KXPR!=DM~4g zzIgd~9sm2~fuFg|ByX6G+cXO#Zxc@7=H5T~m`NLKe8a>CRUY~^tnNZZ%qCL;dN^4=0Lz7G8fw$9u6PHl+$P1tE)m*Tm1HIJNQqy|H^)xUcHa zvkgVWcUi?UL^ulYNtE%Y+?C$18@CvKwSDVvhoal)2LHj0iYYqeZM7#@rp)f$iD5z(<>g6!1vqRojTc|X zetz=;&a_ywx6vgZCx5;rII5^_4?W5AuV(DO15Fo4v|SK;dTIX8`~pOWq@qFs7Y;^@ zQl`LfoAriunxkF5xVhj4d=991IN+*w0bfpgj9&^d30gbtVrVha0zaWs(VGiKLIQ^S z)LNYPUOXppRM@MM4gA21?~OPZFMqSyVS@5p%QWd8&&krAFSm50;L;0EOs59`#|#Vy z`bp*3#fk4Q>J;62%0Kox{{BgM*1eKQ`6Rzu>rIb7@M#2MVS!ie@;YX4eNtFa5p1my zHd>lZMKTTd4_B|v*G<`@yG8IvL|5iGRB5?}<~*0C-bY6sfWCvJg>@*l7GdoXz9@?m zIaZ?3Od^BS_fTY}g2liuyB&PRG@8#WGRs=AQz2f01Pxjilb?@TfqsUyrZv~B!CMy{ z7iiK-A4W-xdnVhIJ<@I(G|KguDv-g1lpB?hA#eF4Iy6nfK-`)o&V=?rO(a%(tTQG9 z`6tCFQMkm;-bn4aqg_ZVt2a^Wr+_I^us3Qg^=#`fY%ZTns&?($+;Zma_tE4jky?Z1 z-Jk$Tq88r;I;3%9+nw?Cl0I(Ws;&CT4pjAZ#BxL34!i(%-Z=@Mq>2Q0N{0+yE{H6UwY=-r-r&)CX7v;HHbsaZF0JbFID5SJTybMa=l+LqzYMGfL1n6jXy~qBU`1%EwI<~ ztSmtomSY~h3611Dqs#9T--`tem$YQ1+iDHMq$}}95`MR{)ye83gV^}}+HuN=Ym?~N_g`LKx zo$engIS+NJpUv6^3h|e;3`f*-HPFg8tKi{YGk!*N@2M_ z1W2R6t*{m#^o-we9=c_Y^1weAc; zC9_jY|LfT6OO3Dp%c<@E_kx&d|DGB%arSj;o2UW(KTBfq>R*}N9X&|i5uy}k>unA< zQ3`YN`z?wQR3ApX&MrQU`R_HzN~}DLpXffl2xAvJS57!rv3ecyar!^3sP+FwlV?-I zMoj7Td0>aEb|-&jw!=akl>QX|^E#x*&roz|Teo>u(SCk^;@+gxQv;9fxYbf~E|MUQw+Drk_K@KF(%7wH>BYN35Fil#I2zNcir#4=Gsa< z2AtOT8Ff#sh|FVjh8rTw5LGNblxO*oTKz}uKTuz$-lt!$dI0TS*CBzQer#2qdpuT7 zuzbkv2M#u2YFDZsdqGcn8;~!~eB{-oU+yj&4I09om0QvqwTQ&Y%RU8)YCqG^GKXp! z@+8s?_h_!wwa~cC1}`exApdDF0~FUO@!jP1j&G#lisGZnTtMXN3@t5Zo+FDIaRpaV zmeoW3+6%|2*;NhFP|JE7=mPOXuiw!170?XG89{qHTtNimx%CsT5%Af%$pc~SI-hQx z#s6Ic!YiQT$>c<>O^&WWpEJkBPgr|Yd2%>QUUk?O4?wpoOmAEv-~pUQ>5$q?pSB@C z61{OU9DwhWZtx&aNiKKWEVi4Un8uoj3AV+-(_*5EsSPezK+)P;is{t}5}oJc-c~S$ zP5B{+^E(rIA?)C_QhU3lj}Xuc!zFKSD5o{RbHN9w7`p`*@C2`#DZ%`xw8ki2*heU$ z5zJ1q(`)=?ik{PiDz4_&2ntx{4NXk4tkfRP|KY@n0R=y+e}vo-6P?H6tVxcNn`y#; zagmpVlFu>z0U|I_)+_zLt$!cRLx{rHj=SK15U z=9atcSzS#kMkE(K4lRSRU|tU!2p%o?Nxn)8?M*Kl@JNj!#ixpcwKm@Oc|pm=%0rYJ z0~BKao(bn!E>LTxrF}N^?1s$pL~QXvt@Xmjera$Xw++6VK1&{p67z&o=VD!c#7?8mF7PC{Vb8s zszgLvn^RyT9P$((bcMx9;-7u8tT8H^5QdD*n+3DaC>sb}OXC+J_h`n{|m zIkVqZH!bIuuPxjrlZ3THNsdY#A$JwGE_>D~QjrY1A#a>$=oXHmPfL?5Q1~3H+Prpr z5%@{{fqK+|q^RD9FK|e^1r+UFQHFbt(&o8{s_A*=(=KLu9d9}zHUKvCnx}Y$uTs?6 z-4#iX`vkKTb-2^3)(cU&{e>aavb#d3Q6WjTa!OCLO_1UIdHdlb3;A@GXGU~`C7qG2 zPzfYaH?LfaI@}JO?L8E^qPex*@M`Ks)#WypB_MAv)+iRHE?!-u3-DFUFK6o#Us{T2 zsS9ZQdp`4G`O{(}zhfz{3;DMb(UB@zjDQhFklJupd%*N9XKWlLd9WRQYQ!y&HuK81 z+}J&e7!TQRpT11%b&a7cjjRYsl+vka4BDMMzG4Sw_X(wxK>9UL3bz854%K>U97bW z&K~wqlLj$?$NFaIHwDK*JYt+Y?^701*e;^smqje0)hTBOp#kyJt(&CI)(vLK=cUhQ zEuG}_)x%Bc3uq-HG;!g)G?_ucu1i}|e12x475Fx-?9?(nt!t$mk6_-rT;%j-V}{h* ztPboY-F*ctn^ySI27beXSm6Xy1d4BiyzwN81}DTzjzY7pAbf@)j~5q2u%@#FU{#Zw z)OW#N#(^ z7FvP>#~~<47#|?w^hnorNyK2RBF7*WQ6GDI_Y?eeEUEuvX?hSPoibhwOeF^*X~^H)>o>%U@-Oj08(^ z{R?J7=ATF6LKyar=yP+e&dj~*WrD0uvi^YqTY%kyNV`M6|yER+H@6F`#MRqZ_o zQ1$GSqbJTjK-#kQH8htRCoOdyRr(1W5g2%$@Y!`g_NLtGf|s_aJi*51oy`9G5p5tU z66Z7~An=eed2&jXlU2iKdAe)b6~4cPUN&1i(`ua)j?z-}>BJ;SQE>B$rk)_*-f0UL z{q`m&xvjabINr^q!fSH(ByoC^Fqn~hLS}zQCl(s>f{qOka2ECC>kmQ7*wFiyNz*I~ zXT@fyOzXylw7XodMY7(0;&tpq73gOdsGgFoIea}x9GUJSo6;0pypT0@(4Eys=tYa- zzM3TahHCIe-2yLCnS-qfAkO#-=7DJN`%fcLF#j_n5fNy!z;T{E41+t(*vx^BhOQyM zX!G#g%^v~?%=E5S(;O^D+h1T> zJ%vL{?o;WTq90mX>RtP174qwVmrA8SW%pVXJ3P(0IxsA26Nk7t86yZishh>WfTv>3 zMbMSk_YhD`YF3WHhM=HB#peX$y?;D+FH$NxTX>9~UzfQKmghj&=y*}PR>xnJ4du9b zf&8`MJZucVJf?H?r{|wRb`h>_gM(J^7&phBo{keX53cXz4;iM4Q{Lyjkl>yUnw3v@ zI++v{Rl1VHO-ac^YvmJIJ2NLA$M&Umuoey9P@l;}l=9)x0$doW zU2}>S5>AYoYQ(LlAB~BIg!`q8Io$_}wVxlCkI(8j?0oPnxG_xM8Y-^R-DQBom?yt0OIs_=%hoeL zk8J(ZUbL0u?XYN&j&5g3!w4@4HIxO4gepuF{^oA!d&>RV9U=xwa7)lPYB77^r(Xrj ztjdI8rCr5(Zb2usm_^|1h|CjtA&@;GlNeNT9PB(cI}#iAir`$c7Ky`^t2@{*c_ ze|8d(xco|mF5Z^HB`A+|Rzw5eG!*ntn#F~9+VI%?sL~Y*3802<4kiMKEe<=tQ|gP4 zqHVA1|IRlqb`>(DJ6x#mPC#UUQieiLH!xt))i5ZXHk&-z`@XlTLI4qS_6wdBbY58N z&Fx)N?3BNsGvng(5+jTY7I;2=zobD5!`l?RW{om7I&!2yJ>8X08bfqoe|F^26`cN! z*WBrK>u|8NgcZ!3@m@ZtIu~(+@|h_7fahWA2Q3G0b7>9(zxGj*zvMC+54$C*q6^Xq zdw50lGG$W^n%8eex#kn$cedg3iQLXxT#iG4gqM?J<^4a~#HseNFzqoFX7S2R;Hdn@ z3dvsP1TR5ylT|mTg7@St4hc4XfKrckqFsB+5rE+Oj z7gQ)JrEj+jCQ-3q{@AJ~%HNNDX7d!W?wgW^*XA7%ietU$ z@P)$YOaz#Kj3U||qQm{Ik!eEVB&N55ek1y9e`It&wh1;%SKHV?`x5oRN6RS;iG^lD zv!d^`O+4L_n#Z23S+(a17j|MkKLwHqF#o-+!qNYP1{@K(Eq;GGC9lVk;r!R~HuFER zwk}mp3-PS;Vwm)GE^4A+S0p%Z_7yv)!uyKrh?M!Jm%Rm(1PN%v2o=FZ+4**=8lfK= z`vO55)>>P_`u>RQebP>B-apmTXXoFRBw=-duAOHRlcCua2~##c^%L*=%`(E7rpFAp zpNNDeeK|s-5M8vv>nXo_JQ>q)HRPdUM5waJoj|c4*Z&*%*h)gg>^E2z1V7c1H6l{ji1&#>Re7p=0i29;=j4Fmp_h znGA8)p9CGm5NrI#p5X^qcW^`-%9I*E`RR728AqIH*PaZ@tt$gOX|3BTf&pxFm(>}HjzX_@|B=;ns+m1 z7tWF&J3b0&MaOe=>iMehaA*frzMGt`X8x=0&M^&uiJqJXi*#I3w5a8L;%NS~?ZU@T z-@MT?;NSj_w)P;3A)ajStk2c%)%(YAJe!#orkYYn&rrZ5B5RiS4@QBFP9Bw491mZA zpZKIetjqNm&BQ=3>_e$-c7^9t<+aQVYr~67y2`sa;2yIf*)5UxF9Vw#3}w7LtzmWE ziWXrASV4BZPGhLJ5CK+1-#{(YGEU-l_Oc@1`1?O$ol8ksy%4dDGAbx@7~<5>jg&`zh3iz-mpN zGN&W!I6fbT2oNeyHq10>U8ndZV2lFCN~o*H%JHzSCz3x==2eWF8If9aFwM;=zo4OB zkV3eR_G{|{ad3*NFfTH|#$DFrFX2y)sFM>8B_zXvX}%J2`-)*|mrssnQl>8&B5vJM zc4?`mXK0Bk z#V+G9E#S0~ve_upb)2N{$Y7~w(J%OyL70;o2uucm3#==-?1w7_y#Jjw)fDH8!UMLD zLlby34l+4y>{*R9i}7!ZdN2ee<0|g8fBUO}jitCW98H`hX0W^X7jPP`tWwdbub7aI z|I?M=r_ur&)Z|ZLWl9zw-`c&OCvpsn* z-h7iza(&RuD-uewF->#nK0+)8l=;MRvuV3C5K`r3}5O>b}G0`#$R^@=7eZe?4u zPWUnE%*&deZ{${vq~Y`OvX7eC79NmWgPrRUs=wKP*6zQ3CDGB@?r9nJ@+@rLq)pEm z-ok>?*_;*`O+-f~89hrhtP#3H$;;2e>8*5-X_m^*}Dv}K28Xu?_0W@e!v zlUK{gl?rG`M&9=8me{`lgZ9r3*ZCDH7ug}7R8FZ6j<42oIv@82>YJ?p3y|9O`L%n3 z`E~Od1;`m+iFx)0_slz`wV&f6sv(c^>tA^uhs}HE2Y)1h9rokFH>MfWZ9`GMM!xk$ z8h9;x3emC%#J8Sb@A~x5dJaC%9sC?R6xHtfERQ3dkjkR}T!6f&yWIR9oC{VZP|Fdy zbzeEyojx;Sbj2K+9`eQBVCRW)TN{P$!LJ6Uima&H;oM^stJ6gfYpFmlHnsZ6sg{5EyiJ%>Wln3J37TNd*1!^1ytsnyw3QbY5oGs zck^N`MbT-_+OwC=1x15fU?_2A+}}zIbtHDT9A%`t9^I@>dX}edz8CYjV}EH%`l#$t zzTyaYG}uF~k0`!Tk&A>Uy`)E|m0dVrT25KSmMqq(JPj!gZ+EkNR`EI`j^aohDe-iQ zAUK-pHmrjBuGl37svP#ME+hIr99c$hC6}2s<$| z-i+nQp_Ns_luCO6*8S#RQi-kkq+HmR8O1G z8hAAJc7U4hL%_&Zep?OP^O>qG@#UsFk>WdXTRTW$JM-}#JE0E}X1={jb+~Q|&v_<$ zKiCz5baM*$(QrWMsnaeR$KIib>H$kcv|OoHIdRX?B%?v$%!p<*wwtZ_%sIu>2BY|9 z4R2h05bM&w3#1Fi!F0Nwr-y$f<9O{S(p6HoCiax8b1-W6AWPCJ^Vy5=DP)dEjlCHP ztqXJ&+@*OxNcpz*c?a|CV_TS42r9bkKo`4kzJU>;8^_eR{@AbQ*XakR|L~5C`Y=F# zLB&J6CEt-)=Bb>7gKGw;$OqIFzZM_Fx!2EpE}YnL3^7#mS|pcaG+EB`8zynEY@AnA zES*S~>PGAbM8qJ_UC$v!hLRK-C6y%OU%u`sIWy@0pl0w@bp`mektqu=Uf;L^{Vvi|H{r z?>f2rYl#&IG+J`PgH``N>J913pL-a6qY`*-@;yM$&FFk$2hM0TF#(LQlhaYNexAXQ z_`4UR>^*&yq3Umn|L5lvo;}NQ;-T?8V=ykZrxW@7TjJ**SW`?1*;GA-iNgxL{dD-J zq1ehqxQU%G0~svxxomD zy;bqQlZEShfORBqa~Kp!B(;(svp75baHNZs?GN1HJ#>*4fmwNGBbBG36D0pp4H;zL z5$GeTpq?VV<&xyrJy)5k_%HP7&!8dqyD`Vg0AEd&X@JIQ&E4HlP1l4&hjUn#>n5yp z^GaX>stSb((NMlwxVoR0|JU$EU%)%wj=1*q78ft`g7w8+@5 zQ-&>;e!#JwXN%Q@ym)Jc7#GNto6LR}z3*~no-5?jTDY3M9xKB%>NYnz?`OB`OvKK4 zvL0lN5SBTA-npoqS|@R)U?7DxK;2fK%G09c@mm7?_UO}eI=%DaV39AqTC{qRB(0I( zxc^nx)LO>$B#Lqs!N9H()B#IhOh-@dKN=d?^U0zvhD(Z16miEFWttB{~cv7aZS?YUBiTmQ!RbQ6o%!nEc z|6^~}KUvpQ;mREtV)SF-jBvo@w&Pp-e>C@<0ZnyJp8=v21*BN$U}ynB>AgrNl+b%G z(m_B#K#G7Oh}6(KCWKG~=~WbvE*+$Ugx)(yb1y#6zW;Z3KkR#WB2gEA*k&;Edkt%z0xdxk0ttcZcnXS8ENQMB@bk!EZ^&ZUwx`aI3ctten>>tBpMrrJ3+Wqy1C zH5G44P4%l#c4l>&NZ}Sr^j~W!6JFE6lI^hju*PkC5cErhLZMQN)p+GQ6$2Xq7GVYC zycx05kXTFWX=2`-t1=Vrp5goqWn-3Ga`o>t_JQ(=7W)L}kf|-1-a6au-#vNWuxDl& z)A37PzBg`skH0&F$Oa0qo$c+$z%m^!KW<(?zd88REbFIRv!p%B)1k;q|1j-;zjwbX zT~bz|>PylOg*+o9?-`rzviSq39Z|QA_B1j&KEOXqImWCoDZNLx&O`2)-zSd`4gg$GHHFb z&qo(^%i?FFSr2^zBB=W;Q@uWM=^=DDW*W%R6_?Sv5R;5M|EaaC^vD8#A}oNa@L~Q)O zAQAIw4#9l($|OWbEurERPPOrh9uk;Yri03(!1P?2dzD^#7^T!gm~oOWhwX&29iFRj zBJZR$kv?57Q=nkbO8&QNjH#f>%(v;rUG$WM9Sl3TahF=ya|?p`)9E!oLii@+MbXM3 zqNa5{#t?bMUGHCHl<2b7^jLA*kg6yi`9lB`ZkJ;0jQMT>eF|Yqm|CLzq%6GH)>FZ& zu)&YM@*3{{1FE`nBm8vgh*)yyqDX3c`b3JMQK-LXGoq+V7l6q=Wy>x?E z*)SVHQ{P2g_decF?z``d+jl-l4Q&RBWnbQU-g0UlmYHM_j4)CP>t%t8Gn^OdaxP4GJKbggGqLJCm$c~sNvXItjWDLM^ z8fq!yOIVwPHnjCCRIbRL++wnKa4Gvi5`EOnDQcVQt^&)}F1^9}lo%*XA&`4}kn1;CZ_HaZb# zdNyLOW_);JGvn%QTch*KIMX6z`~lvBl`P4EwWC|6C)u8BDoJ`DM_f-HDcUZjdDV6E zMZttyDBtjfzlsIjVE@)HLMDD{XMa3;B--A@K@*%%lg~jeVCcQ5ria=rQn`_*KP1|r z(T5Kid51UcjBOP>LrzcX*9lb#hB$0-!xql?m77+QMq+aYG$lkpG5#z2?~U9TZ(vxM z_d-0Qr|p{aJpy@dIyD)VFic!d7!0npV~VHra{2L*qstFXk-1DL7P;6Qe8!bZ9f4b~ zjL#Z$pESTVKh^ig4X>mU$-2EQhr{({VIYcFzTIGY7x~?RFONS=O4VXa0aU+XliDRt zDTPAap+6v5m^0=}Zae%b;GH*Ml##*JA==g6PRPozuzB@dA@EBenY^}f{T@>S!rR+p zp&2z{N#xaGmUGC&u5^OP%MS*<>L432rdgS*nm&&o%SX-#BrnC%y7N-D=MzzkJkdea z1e3b@KDiOP-P%^zGtjWGH4xdJ`m@k;Q@b%ia%5Poyn^QuWg@u1%i=~9_Faif?Dn&W zDq_>jk@q1J8J}RinsfQAdYU7-4o1^1mh!L%odggm;rCVE8>3v(Bha2u-AqjHjHiQT zUA9XSm#Q%N5RKc8B^1I=_!Te3R*bh`tCO0n%89RgCG4Dg{^PqezjqwHLF@FLog74Et`^A@X`Uwq^@~*AbiC`T64vK1r~1wFYUvM^53IVz!X=f z?WAZosf-|J9HS}u-Kz#4CtKYenjj7K>T}A-n89rU3HFUhcX>j64J~ziqObTFZC*L` zF_5avAKH&2j|3(+?#Zir=pF;{TpX6lD#c!m1s1n64oFaaRd(U(%Oqr<*$Km_A}r zznAGQ?{p$V_?%5VdS3cIOU2gGlvo4WyUw(s;V8NpW)02t^ zXzD|6NOCqw$h|IX!;7+`P++B7TPLonh%6~ppSUptt3qz;u|9L99C$XBMJnDMOU0cC z{TjvcJs3m|Tznm|i9`h!>7*5->PnF#;vIBG;$IQP7(+&8 zi-TEEvQKEEn3Fxfv3HfbVWP_G`?OR0CHeBplUz_F$_Aq{zXBvPMO)I9ZsP9D1z6d6 z3ufgEmPD%OvFq4k?o#QSryyX`PPwjvGCCd;A`A>~ArmiadOsI=2WEDyy=wJAd>6%t z9!|Y@n7Z>!CQVu2*D> zXI4==H5KgN)wq-HA(Jk?-!xfQI{Dlu())5Eh?EXUrxxIOoL9L#o$O9hUAD18q}=_I zgE2Tz{4yn&!kEvkD*IMs+ziW!c|y~g*UhVyVHir#HeYM==a)o``V#F;1PT68OXwHk z9~w2fMdkHzu2X!KRL|HqwQm<=G46f&V{2>}$!!7y5NVkC%|iR*OeeLnnN-X%R=1Fo zkGMC&F2ewx5-bDP(9jgt<2w-Fw*u8x>;KwwR*$%q_q}3`!qJ8MCR^b~vVme=uyGwE zgl{T@k(6lxe@I*yrG8UQa*pbpIxNQW{H((JgVl6($qx(NPxwFr?@H`u#;_WgnV)7& z!+<%9uv7S3o9Gu7{p}QW=dsU@llQCYL@~aRPUJ)60t)m-hAv-0FfG_SLcA2@3Q;+4 zR=gHpjCuA{8;)z&UiHujI@gHi1uZjfV0`kTH3NZ0&03R~wa-CyfWqWw$E4M&v<#Oy zmw+0Tr6qpp8z3+?XXR(gdv7mihb?Sv569G~piM^A3YyL}Cv_!M6^ipFma<%0oj|!y z5osb(_j%^^%&(tZ5@MA_4-MN;SSCG_uQH>ZL|pYUaQD#YnH(aeLH}cYl`8Ln5#`@( ztmD-i{g@NW)%X}tAi0pO_EJ8wi|FoZts$=T7g{*$&X0d_j zS^?txv1(DdUI6*0(|C9Olf*}Dg-RkM@lTbg7PC5r80oVRi}UX7zC>91%xIBi&?UuS z)!Xb+8rkCYQTiA@<;2oS0IoD4#hueVHpxu+hVuM=eBe0J6uA}HP`~xGzyNV8OCg*G zjuz3M&qWY0xz{83o>W`0IQ*DP+P*vO$w`3=Xoc&R- ze$5B{B3rXOD5>fS*-!VkOE@as9Pesb>3T%>_6(RAHRe6lSjrQDo>Ts!Q`L5 z6ZX;Lt&LV4ZX&-7_sZT*c&A{?1)AWOvbKYk2c<9AefMpUe}l_p)nm6$V}d8n1BLe& z)_FNs^WanyEkhBH3(6CVq7|go!8ngz3a%WNjn(@#2P7~DOWnFKjTXWFx+EJmm3*A$ z#rZ<_#UIcyQ=KjkRPypsZ)7M=Io9=F_g)kh!m}aH%=JEUbjrmn+r#*XNM|@%wY8+D zuZJrccI&pKDJS9lK?rH?sg;DSx#QIBT8<;-G}{Kd{+Y)O0{qoWMOiizDcwoGh*_{Z zH*Df!WKDzx5>{yg_$1FpTIrhb_)qv zOeQWcV@q`sr7j8P+h z8~$P>evZ*X{dA1xOp`IeH<=6#m}eL0MKB?o zIPOcblBl@f#%3g*UQGY8O*{UCYv0nklD0fQ^6}tT>uTI=7 z0jlNQ^j&+hfn4-Ekywbk5DC|R=V+|Y&ZVzCJZ;_m9Lqq^5X*CXK=b4A)0dEq+vL^M zX}=#2O#UyCtiKSP=l@$K=Ud4C;RTdbn2l-F4SWqId*k!^hqgBmv-*xP;(C)r((>ff zE@z{aKHf;M#9Dh)Q5m%V>L0*Y%C#N!uIl`;|4@VV*!1D(LQCo?gv=W>22 zZdw7>^`(Hnum9iLEdp+z&#>0h3d%!~-g^~)KoWwa7vr8+Bb#Dy2eoe{SM-8ciIWFf z<)dOD?I@L=20e&KM5L4VN^7)9**^bX&ZyyWe zZ@x1d+#{bw#W@UaHh3dj`3q?i_;qOkcR~!-oyrs4v^Wn=dAR3n_9F$JZ@j8cq_Dwc|O~& zJa7-!vMZm8Xc@c`+{S&2!$2QE5G+FT2Q($WRjPlSjt89&QkUnhYQXxlrq zSx|=d>5(o*s!k`(ZeNx=!YbQO3WirWTsnCqmX(SzrChV0;u1j~qHuJJlyV=MW1S(4 zTuX9DN=NJQ`w!$LQVrqDHW=-S+vy%@cprK&7T8{VBD#5!k1gT}jiTm%K)xK1O|Gab zgF{JPVfA%rrg%^jlzWaXyUi<$LdOUhy#uYFsGR8XPLMBn!_}@6OsRpZpwz(zY4m&i zKvY6Kx1QQKo*z>eMx&*1SBSeRBpYJZ2)z?h3OZ@$j4uQE!%{+2N18ZA-{5|WIzOrfw4K7i{F?k>+4<|CXyw5 zqncOzu)8x6h;)(Y8FwVM3Ke&SFx#r}j27qc>*?Gb3!A4$?&8pr!1H$UjZ3F(KQ^S@ z8@I1evQ}O7F>;Ae_R@?;)u=fP4SDhmCi;g;7@od*I7W#NSBEKTC_+TQ`;v1}I1H{- z(973VU@T%vmpd>}CgLjYZrpsD)OIE&;50`$OJq@%BE$Q1{-XC)&F7{MV^fpgF-AOY zKhWEx1W47^K2**jy7@vki|bUJTd&ayCgCX`=dF=ow*Udm`7NT2BLO8VJc)qV;c$n+jH; zXf~}j6Z<$=$0hNZZOwykKXHr$=8=bDDuq^xhVaJ1S*)Xl@uIFl06bv;vJ2;5UyNvS+c7py4Q|e7`T??wm z<2kenwQ?>hE$V51LOA~_2Y*Grq;7{W;;aN)x?$DCS)eMQf_^y3a#Xqanfp;a{r*?5 zXof}B(-@utV~SDJT{AC<;k5w2*Q(V5I3xYTD2{&7X{;KGDUS|z2N^mt8I2nQexP52 zQ4f4$2i(CF>?FmFUsZiE|`YcQpX_&daJ8(w)`hEM)3=#x4J`O zEEF4-2AmvV~bF0Rx_fNO`DR1RAeYbyg_=bEo z4k2H^*%aXT%vSrhm+(S-Qp;;)Qf6Ew=FruLonFn-m2=OlW&HvQDc4f#`S_I5RXh&f zTUxp-vT-VR&1W2}TMRVe4!hJ%Y#SIEtEI*xn+5Ab;&=q>-XtRs$n$lP4wx3cpGCLSTN6t7ypv1{SOE{))VyZsQJv#?y>+ki65@)O6)N*c`wPR!oy?K z=%DABX;;;qA(%0zgdDCv^O^jI)#80|mh{45ADp!F`dA>wLT~W#+XQx)$wA}JV>HVm z7JSy0`-z5YkT`GcjsNpAe5Vm)X^%*lnx=V5R-i9Zv_@m7KE)7fus?17-2XvzHCiTZ z4`PKaaHGx?(ogwpl57>a>GBCdt=et!_~@pLO6sGJb;9iu7WmH^#6OH|nPK=W-zcFq zU3|VoovBP~OAZVY9N>BmDJVL}n5^&^`~l57OuxJkYwy^46ZE0?MFvjHDPvIaD{O$_ ztl4VyFy=n%Yx}k#=3*z3yd(10+?RwD>O$;8@1(W+m@%z$v&;!|Jc}I>%jdhghrKoR zq*qR5JQ>!fQrrVzj^zXsYMT1>dxiQhEvA863!9SMol z`9F3_l1tnR(00@=7a&~J)|d{pH@X-F>I%PMcMr?>jz8-cQzZJjaN9|@2g1YiLKXg5 z+rzTZP6n^U8i^vL6Yf@IU_UwAYH%5F6&*>eIMOwnQ;JVlJ#gt62&*FrLxhfnEkpOZn zxLY9)@KDK}PQ=eaP`C(f48rJkky=l8Wh-<|R*4wtWrt#P?=O9@4AS@ETEId2n|xWS zJif@8)*c>yv8ba}Z_UMpQ-yH=9o1&g=445b+N*JK6`D^yAF*+BJt!Jtd$hdF${F}w z-OCX}=$EE5MM$6}BNLLJzW$97^c;>(-g}E0MW67=c_?HHo|}8b=Rj{4%S*^BV!Sm_TbI=|2|E@+zomPwF(MF8^){u-*QW zBdQsUUo1TpH?{>E;(F0|*f(6wg0??CQq%JAq|kB`-uMuP3_&qHZB-yD z-4FhNEIXpm%@db-6rK&HPHXGu@AB=0I|eJHw%S*`jixE%M-$cN-`K5A#FI#fm`V2f z5!BHZmRAHs)xo`g7u$Mc4}LbRDhJYr{{eN=OD*aL$t{`=%v-Uaw2}$*ZlHZHcU!7CH{w2!7>iHwZ*>r#?d#yg2Op-dHa`9V{Vfkt?fcj5^KeITR`koQ zL*7q&#dqZToah1cROtf1-NWda1AwPSmHo440lYvrkqy=6bG<)-ZA#*k+1EP(A(UJ| zPTsR-AO{cg_SEMb>^BbA3$O&j6mu7Tqyzq*S^n!y%ge^-B=_0)gcJ=AE8S$uSQ*#= zA?V~AWQ_le6(O~6gI?A?`{k#ALMWTUf!GvUynAqgMWK)jZJFX z1})Ceh(1!BNTNz|=5J+p0L7Ds1>-O$d_9eak6CYlaWG06Ey0jwNc58E)1|vj5bi2k zT)lBk?CUPFZeV9Ezy#qgTWm}qE(PCUDvQV2=_E@=+T`E;$-~-%rV}x?$ap0}))@jC zV8R12gR-W*&pt{Jwu>s<{KkP|H2tf+l4$g@d)Wv`!de~IMNC*MB4EVz{LA{ZqR zk3RyjXC!&JhFH0WrbYK~IbE5~Y$((+ zNVS!?Hufow0~l9~KEPKhNpe7%;hrsOX=*>kvU>0;k{omqy3P`}Sj2Bzs2z(uGF~0Dh@A(WLm1?> z_DKiJ>+l(WLw9~dQo%T_XB85Iv8iq z;q3#s?4#Vu5Zy2&PP_-4fgHZXb4Z{>Cjr3==2@cwl#~@4mtvmE!`fQdE}AsX#y}$H zIK!LP9WsgTVN%}I8hXlLPu2qnCIXN5RWcq@6*lgAs%?P)D(eY8GI8>x*BP|ux8$iK6-j6 z|9J03>9uYD9nZt$(`x+#=%q#gnF{u@FL8e5BGUg#>3Sy9(4FOF)y(5A*1}L{T)sIl zY3jx2&aZS~&j>*O;!H6JWWNjwk_B;|*IxcqzS5l=e0bkHd<1ahQZ#s82`Mq0+XczJ zGyPjnmi1Lc6T{2()5q6XQ?!%fz-x%t8o*sFeVtZYLPc@{gy*sf00%tnDf^>=_eRHw zDZT?!+VZ@Gn!{NR=QNeF*Is2#pUa(wl@~E^JiDGDW8^ZV!FRqCuNrOxhZ(agHyK!TF4wi@KKUrq%96Ldx14KCqbYe#_+lf<)+%Yh_} z8tKl9hrXxnmmH^mK&tYUmn{wl!(d_D3omgVPfyN;MN z=HjB2o4N<@ejW!6H+Pf=Wib?zPW%C>{{hi=UA+t}aQ|9rZre;RX&+x+nn9)C2QmNe zty2F*Jhubq=Y-q;6G5+I<2@`OB9SC|zx{dXww2&z8MTMh{^GS{p~qj>eqtx!{iLIm z*!N>gqUVn;+Fo_Bq0AZ9Laz_+rvB3df9v&dX-9cBAT(zO{T?u)WyrEJ9UJ!YiRa$C zx#O=6{r`}{-wOVp9ckU67f%yQBnKJzm1!?5R4;~uw2gKcV^(wHSV=ENUZ+uWTFcIwy_HO1dcl>SbuR+9&lFOFv|D9Yt-Q7F3<~V;@X9K46 zFKa2l2msCkbU{ghR)38@IF#d*;6sozea00qS*Mp8f#VV)*E79$mRqoK@z(|t6JLR; z^uNkEom(8PT-!lUUJwDLduwEjQ12Et@$Y+rNw$s!7#@0DAy*=?K(c_-iXH zfLu3qcge2R_b;bw^?6>~6!u6~^B;4M-~{C2Ee!_l;Q!);59smV!B9sx|6@@^hDzeE zJE)??+d6IY_B)vv3u4{B?i{zd@s*x=4WKS1fMA~c<$Omt@mB030bPYT-_VnUT14NJ z(~WJ}-J0i-S7ef5$C38FBGr?&RBHFNO1yg1>5Kz9Qm0K9MmxL(RFmDgS+f$85upg* z!Us4~S~7}1QzH0cNjve5ZwJ`~(7UggYR6!{3ok?_nds^1C^Hva`1X&;y;@N0JXg%n z>Gz~g>Ed*kS{nxzP^4rB*MG@z($_DBU)*_0y%q;7wC+#?$smP0I0Y1;4z;Vg0YE=# z_x?u45TMyZJe>CY8vvrOpgqZ1fX#l%yhjC~5(=*X!~t9eN5e$JxzsnF;5%}0EPALq zfX-dcp}#EgP=5tbtzI8#76c^W?gm%`F++}@c5BxheaiG-w%w5nSJ7?)uE7B=u>@%J zM3$&{0z%yIGs^r0knaULbBR_o3tE9dY zCK17?|8k6gQ3oIg0-7!UIkz-?@7xCg1R>C^yCb;%3Kk*M!65`pm}hExfPig4eE~9N z*!A-?GI0dBgjfcEaZH-Ij*ub(WGdVN0rmC%BWS9}-$$>h%=HxD_PEafU14_uDga$i z7Wkhtuz(_a^3PH`RM#g8Xox51_6I1Y1Ezrk4DpU!=a**yH%egqthfY>!T;(Zj+v~m z;TxDJ1&{~$`LDa-Z*vRqt4R!_6>k<`Jde5>Qh^Ryz&y*v3Ge?kg2=>wNu&~9PXJiv yn&_zMd Date: Fri, 4 Aug 2023 15:00:55 -0300 Subject: [PATCH 124/177] Added Typebot integration --- src/validate/validate.schema.ts | 13 + .../controllers/typebot.controller.ts | 36 ++ src/whatsapp/dto/typebot.dto.ts | 14 + src/whatsapp/models/index.ts | 1 + src/whatsapp/models/typebot.model.ts | 38 ++ src/whatsapp/repository/repository.manager.ts | 7 + src/whatsapp/repository/typebot.repository.ts | 68 ++++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/routers/typebot.router.ts | 52 +++ src/whatsapp/services/typebot.service.ts | 336 ++++++++++++++++++ src/whatsapp/services/whatsapp.service.ts | 57 ++- src/whatsapp/types/wa.types.ts | 14 + src/whatsapp/whatsapp.module.ts | 10 + 13 files changed, 648 insertions(+), 2 deletions(-) create mode 100644 src/whatsapp/controllers/typebot.controller.ts create mode 100644 src/whatsapp/dto/typebot.dto.ts create mode 100644 src/whatsapp/models/typebot.model.ts create mode 100644 src/whatsapp/repository/typebot.repository.ts create mode 100644 src/whatsapp/routers/typebot.router.ts create mode 100644 src/whatsapp/services/typebot.service.ts diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index cd6a1b52..7f101a96 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -974,3 +974,16 @@ export const rabbitmqSchema: JSONSchema7 = { required: ['enabled'], ...isNotEmpty('enabled'), }; + +export const typebotSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + url: { type: 'string' }, + typebot: { type: 'string' }, + expire: { type: 'integer' }, + }, + required: ['enabled', 'url', 'typebot', 'expire'], + ...isNotEmpty('enabled', 'url', 'typebot', 'expire'), +}; diff --git a/src/whatsapp/controllers/typebot.controller.ts b/src/whatsapp/controllers/typebot.controller.ts new file mode 100644 index 00000000..aff33511 --- /dev/null +++ b/src/whatsapp/controllers/typebot.controller.ts @@ -0,0 +1,36 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { TypebotDto } from '../dto/typebot.dto'; +import { TypebotService } from '../services/typebot.service'; + +const logger = new Logger('TypebotController'); + +export class TypebotController { + constructor(private readonly typebotService: TypebotService) {} + + public async createTypebot(instance: InstanceDto, data: TypebotDto) { + logger.verbose('requested createTypebot from ' + instance.instanceName + ' instance'); + + if (!data.enabled) { + logger.verbose('typebot disabled'); + data.url = ''; + data.typebot = ''; + data.expire = 0; + data.sessions = []; + } else { + const saveData = await this.typebotService.find(instance); + + if (saveData.enabled) { + logger.verbose('typebot enabled'); + data.sessions = saveData.sessions; + } + } + + return this.typebotService.create(instance, data); + } + + public async findTypebot(instance: InstanceDto) { + logger.verbose('requested findTypebot from ' + instance.instanceName + ' instance'); + return this.typebotService.find(instance); + } +} diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts new file mode 100644 index 00000000..57798bdb --- /dev/null +++ b/src/whatsapp/dto/typebot.dto.ts @@ -0,0 +1,14 @@ +export class Session { + remoteJid?: string; + sessionId?: string; + createdAt?: number; + updateAt?: number; +} + +export class TypebotDto { + enabled?: boolean; + url: string; + typebot?: string; + expire?: number; + sessions?: Session[]; +} diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index 7462af2a..c44ffe7e 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -5,5 +5,6 @@ export * from './contact.model'; export * from './message.model'; export * from './rabbitmq.model'; export * from './settings.model'; +export * from './typebot.model'; export * from './webhook.model'; export * from './websocket.model'; diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts new file mode 100644 index 00000000..bff7092c --- /dev/null +++ b/src/whatsapp/models/typebot.model.ts @@ -0,0 +1,38 @@ +import { Schema } from 'mongoose'; + +import { dbserver } from '../../libs/db.connect'; + +class Session { + remoteJid?: string; + sessionId?: string; + createdAt?: number; + updateAt?: number; +} + +export class TypebotRaw { + _id?: string; + enabled?: boolean; + url: string; + typebot?: string; + expire?: number; + sessions?: Session[]; +} + +const typebotSchema = new Schema({ + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + url: { type: String, required: true }, + typebot: { type: String, required: true }, + expire: { type: Number, required: true }, + sessions: [ + { + remoteJid: { type: String, required: true }, + sessionId: { type: String, required: true }, + createdAt: { type: Number, required: true }, + updateAt: { type: Number, required: true }, + }, + ], +}); + +export const TypebotModel = dbserver?.model(TypebotRaw.name, typebotSchema, 'typebot'); +export type ITypebotModel = typeof TypebotModel; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 25cc83f0..e724ef02 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -12,6 +12,7 @@ import { MessageRepository } from './message.repository'; import { MessageUpRepository } from './messageUp.repository'; import { RabbitmqRepository } from './rabbitmq.repository'; import { SettingsRepository } from './settings.repository'; +import { TypebotRepository } from './typebot.repository'; import { WebhookRepository } from './webhook.repository'; import { WebsocketRepository } from './websocket.repository'; export class RepositoryBroker { @@ -25,6 +26,7 @@ export class RepositoryBroker { public readonly settings: SettingsRepository, public readonly websocket: WebsocketRepository, public readonly rabbitmq: RabbitmqRepository, + public readonly typebot: TypebotRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -57,6 +59,7 @@ export class RepositoryBroker { const settingsDir = join(storePath, 'settings'); const websocketDir = join(storePath, 'websocket'); const rabbitmqDir = join(storePath, 'rabbitmq'); + const typebotDir = join(storePath, 'typebot'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -99,6 +102,10 @@ export class RepositoryBroker { this.logger.verbose('creating rabbitmq dir: ' + rabbitmqDir); fs.mkdirSync(rabbitmqDir, { recursive: true }); } + if (!fs.existsSync(typebotDir)) { + this.logger.verbose('creating typebot dir: ' + typebotDir); + fs.mkdirSync(typebotDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/repository/typebot.repository.ts b/src/whatsapp/repository/typebot.repository.ts new file mode 100644 index 00000000..8653e9c9 --- /dev/null +++ b/src/whatsapp/repository/typebot.repository.ts @@ -0,0 +1,68 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ITypebotModel, TypebotRaw } from '../models'; + +export class TypebotRepository extends Repository { + constructor(private readonly typebotModel: ITypebotModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('TypebotRepository'); + + public async create(data: TypebotRaw, instance: string): Promise { + try { + this.logger.verbose('creating typebot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving typebot to db'); + const insert = await this.typebotModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('typebot saved to db: ' + insert.modifiedCount + ' typebot'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving typebot to store'); + + this.writeStore({ + path: join(this.storePath, 'typebot'), + fileName: instance, + data, + }); + + this.logger.verbose('typebot saved to store in path: ' + join(this.storePath, 'typebot') + '/' + instance); + + this.logger.verbose('typebot created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding typebot'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding typebot in db'); + return await this.typebotModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding typebot in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'typebot', instance + '.json'), { + encoding: 'utf-8', + }), + ) as TypebotRaw; + } catch (error) { + return { + enabled: false, + url: '', + typebot: '', + expire: 0, + sessions: [], + }; + } + } +} diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 1bc2fbae..f5ad08e8 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -11,6 +11,7 @@ import { InstanceRouter } from './instance.router'; import { RabbitmqRouter } from './rabbitmq.router'; import { MessageRouter } from './sendMessage.router'; import { SettingsRouter } from './settings.router'; +import { TypebotRouter } from './typebot.router'; import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; import { WebsocketRouter } from './websocket.router'; @@ -48,6 +49,7 @@ router .use('/chatwoot', new ChatwootRouter(...guards).router) .use('/settings', new SettingsRouter(...guards).router) .use('/websocket', new WebsocketRouter(...guards).router) - .use('/rabbitmq', new RabbitmqRouter(...guards).router); + .use('/rabbitmq', new RabbitmqRouter(...guards).router) + .use('/typebot', new TypebotRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/typebot.router.ts b/src/whatsapp/routers/typebot.router.ts new file mode 100644 index 00000000..4d770444 --- /dev/null +++ b/src/whatsapp/routers/typebot.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; +import { instanceNameSchema, typebotSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { TypebotDto } from '../dto/typebot.dto'; +import { typebotController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; + +const logger = new Logger('TypebotRouter'); + +export class TypebotRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setTypebot'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: typebotSchema, + ClassRef: TypebotDto, + execute: (instance, data) => typebotController.createTypebot(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findTypebot'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => typebotController.findTypebot(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts new file mode 100644 index 00000000..301cbe4f --- /dev/null +++ b/src/whatsapp/services/typebot.service.ts @@ -0,0 +1,336 @@ +import axios from 'axios'; + +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { Session, TypebotDto } from '../dto/typebot.dto'; +import { MessageRaw } from '../models'; +import { WAMonitoringService } from './monitor.service'; + +export class TypebotService { + constructor(private readonly waMonitor: WAMonitoringService) {} + + private readonly logger = new Logger(TypebotService.name); + + public create(instance: InstanceDto, data: TypebotDto) { + this.logger.verbose('create typebot: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setTypebot(data); + + return { typebot: { ...instance, typebot: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find typebot: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findTypebot(); + + if (Object.keys(result).length === 0) { + throw new Error('Typebot not found'); + } + + return result; + } catch (error) { + return { enabled: false, url: '', typebot: '', expire: 0, sessions: [] }; + } + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + imageMessage: msg.imageMessage?.caption, + videoMessage: msg.videoMessage?.caption, + extendedTextMessage: msg.extendedTextMessage?.text, + messageContextInfo: msg.messageContextInfo?.stanzaId, + stickerMessage: undefined, + documentMessage: msg.documentMessage?.caption, + documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { + this.logger.verbose('get conversation message'); + + const types = this.getTypeMessage(msg); + + const messageContent = this.getMessageContent(types); + + this.logger.verbose('conversation message: ' + messageContent); + + return messageContent; + } + + public async createNewSession(instance: InstanceDto, data: any) { + const id = Math.floor(Math.random() * 10000000000).toString(); + const reqData = { + sessionId: id, + startParams: { + typebot: data.typebot, + }, + }; + + const request = await axios.post(data.url + '/api/v1/sendMessage', reqData); + + if (request.data.sessionId) { + data.sessions.push({ + remoteJid: data.remoteJid, + sessionId: `${id}-${request.data.sessionId}`, + createdAt: Date.now(), + updateAt: Date.now(), + }); + + const typebotData = { + enabled: true, + url: data.url, + typebot: data.typebot, + expire: data.expire, + sessions: data.sessions, + }; + + this.create(instance, typebotData); + } + + return request.data; + } + + public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], closeSession?: boolean) { + processMessages(this.waMonitor.waInstances[instance.instanceName], messages) + .then(async () => { + if (closeSession) { + const typebotData = await this.find(instance); + + const session = typebotData.sessions.find((session) => session.remoteJid === remoteJid); + + if (session) { + typebotData.sessions.splice(typebotData.sessions.indexOf(session), 1); + + this.create(instance, typebotData); + } + } + }) + .catch((err) => { + console.error('Erro ao processar mensagens:', err); + }); + + async function processMessages(instance, messages) { + for (const message of messages) { + if (message.type === 'text') { + let formattedText = ''; + + for (const richText of message.content.richText) { + for (const element of richText.children) { + let text = ''; + if (element.text) { + text = element.text; + } + + if (element.bold) { + text = `*${text}*`; + } + + if (element.italic) { + text = `_${text}_`; + } + + if (element.underline) { + text = `~${text}~`; + } + + if (element.url) { + const linkText = element.children[0].text; + text = `[${linkText}](${element.url})`; + } + + formattedText += text; + } + formattedText += '\n'; + } + + formattedText = formattedText.replace(/\n$/, ''); + + await instance.textMessage({ + number: remoteJid.split('@')[0], + options: { + delay: 1200, + presence: 'composing', + linkPreview: false, + }, + textMessage: { + text: formattedText, + }, + }); + } + + if (message.type === 'image') { + await instance.mediaMessage({ + number: remoteJid.split('@')[0], + options: { + delay: 1200, + presence: 'composing', + }, + mediaMessage: { + mediatype: 'image', + media: message.content.url, + }, + }); + } + + if (message.type === 'video') { + await instance.mediaMessage({ + number: remoteJid.split('@')[0], + options: { + delay: 1200, + presence: 'composing', + }, + mediaMessage: { + mediatype: 'video', + media: message.content.url, + }, + }); + } + + if (message.type === 'audio') { + await instance.audioWhatsapp({ + number: remoteJid.split('@')[0], + options: { + delay: 1200, + presence: 'recording', + encoding: true, + }, + audioMessage: { + audio: message.content.url, + }, + }); + } + } + } + } + + public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: MessageRaw) { + const url = (await this.find(instance)).url; + const typebot = (await this.find(instance)).typebot; + const sessions = ((await this.find(instance)).sessions as Session[]) ?? []; + const expire = (await this.find(instance)).expire; + + const session = sessions.find((session) => session.remoteJid === remoteJid); + + if (session && expire && expire > 0) { + const now = Date.now(); + + const diff = now - session.updateAt; + + const diffInMinutes = Math.floor(diff / 1000 / 60); + + if (diffInMinutes > expire) { + sessions.splice(sessions.indexOf(session), 1); + + const data = await this.createNewSession(instance, { + url: url, + typebot: typebot, + expire: expire, + sessions: sessions, + remoteJid: remoteJid, + }); + + await this.sendWAMessage(instance, remoteJid, data.messages); + + return; + } + } + + if (!session) { + const data = await this.createNewSession(instance, { + url: url, + typebot: typebot, + expire: expire, + sessions: sessions, + remoteJid: remoteJid, + }); + + await this.sendWAMessage(instance, remoteJid, data.messages); + + return; + } + + sessions.map((session) => { + if (session.remoteJid === remoteJid) { + session.updateAt = Date.now(); + } + }); + + const typebotData = { + enabled: true, + url: url, + typebot: typebot, + expire: expire, + sessions, + }; + + this.create(instance, typebotData); + + const content = this.getConversationMessage(msg.message); + + if (!content) { + return; + } + + if (content.toLowerCase() === 'sair') { + sessions.splice(sessions.indexOf(session), 1); + + const typebotData = { + enabled: true, + url: url, + typebot: typebot, + expire: expire, + sessions, + }; + + this.create(instance, typebotData); + + return; + } + + const reqData = { + message: content, + sessionId: session.sessionId.split('-')[1], + }; + + const request = await axios.post(url + '/api/v1/sendMessage', reqData); + + if (!request.data.input) { + sessions.splice(sessions.indexOf(session), 1); + + await this.createNewSession(instance, { + url: url, + typebot: typebot, + expire: expire, + sessions: sessions, + remoteJid: remoteJid, + }); + } + + await this.sendWAMessage(instance, remoteJid, request.data.messages, !request.data.input); + + return; + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 59eacd39..a1237b49 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -111,7 +111,7 @@ import { SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { RabbitmqRaw, SettingsRaw } from '../models'; +import { RabbitmqRaw, SettingsRaw, TypebotRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; import { ChatwootRaw } from '../models/chatwoot.model'; import { ContactRaw } from '../models/contact.model'; @@ -125,6 +125,7 @@ import { RepositoryBroker } from '../repository/repository.manager'; import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; import { waMonitor } from '../whatsapp.module'; import { ChatwootService } from './chatwoot.service'; +import { TypebotService } from './typebot.service'; export class WAStartupService { constructor( @@ -146,6 +147,7 @@ export class WAStartupService { private readonly localSettings: wa.LocalSettings = {}; private readonly localWebsocket: wa.LocalWebsocket = {}; private readonly localRabbitmq: wa.LocalRabbitmq = {}; + private readonly localTypebot: wa.LocalTypebot = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -157,6 +159,8 @@ export class WAStartupService { private chatwootService = new ChatwootService(waMonitor, this.configService); + private typebotService = new TypebotService(waMonitor); + public set instanceName(name: string) { this.logger.verbose(`Initializing instance '${name}'`); if (!name) { @@ -483,6 +487,48 @@ export class WAStartupService { return data; } + private async loadTypebot() { + this.logger.verbose('Loading typebot'); + const data = await this.repository.typebot.find(this.instanceName); + + this.localTypebot.enabled = data?.enabled; + this.logger.verbose(`Typebot enabled: ${this.localTypebot.enabled}`); + + this.localTypebot.url = data?.url; + this.logger.verbose(`Typebot url: ${this.localTypebot.url}`); + + this.localTypebot.typebot = data?.typebot; + this.logger.verbose(`Typebot typebot: ${this.localTypebot.typebot}`); + + this.localTypebot.expire = data?.expire; + this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`); + + this.localTypebot.sessions = data?.sessions; + + this.logger.verbose('Typebot loaded'); + } + + public async setTypebot(data: TypebotRaw) { + this.logger.verbose('Setting typebot'); + await this.repository.typebot.create(data, this.instanceName); + this.logger.verbose(`Typebot typebot: ${data.typebot}`); + this.logger.verbose(`Typebot expire: ${data.expire}`); + Object.assign(this.localTypebot, data); + this.logger.verbose('Typebot set'); + } + + public async findTypebot() { + this.logger.verbose('Finding typebot'); + const data = await this.repository.typebot.find(this.instanceName); + + if (!data) { + this.logger.verbose('Typebot not found'); + throw new NotFoundException('Typebot not found'); + } + + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; @@ -943,6 +989,7 @@ export class WAStartupService { this.loadSettings(); this.loadWebsocket(); this.loadRabbitmq(); + this.loadTypebot(); this.instance.authState = await this.defineAuthState(); @@ -1250,6 +1297,14 @@ export class WAStartupService { ); } + if (this.localTypebot.enabled) { + await this.typebotService.sendTypebot( + { instanceName: this.instance.name }, + messageRaw.key.remoteJid, + messageRaw, + ); + } + this.logger.verbose('Inserting message in database'); await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index bf70ebfa..d54b0366 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -80,6 +80,20 @@ export declare namespace wa { events?: string[]; }; + type Session = { + remoteJid?: string; + sessionId?: string; + createdAt?: number; + }; + + export type LocalTypebot = { + enabled?: boolean; + url?: string; + typebot?: string; + expire?: number; + sessions?: Session[]; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 7000431a..2cb045ae 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -10,6 +10,7 @@ import { InstanceController } from './controllers/instance.controller'; import { RabbitmqController } from './controllers/rabbitmq.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; import { SettingsController } from './controllers/settings.controller'; +import { TypebotController } from './controllers/typebot.controller'; import { ViewsController } from './controllers/views.controller'; import { WebhookController } from './controllers/webhook.controller'; import { WebsocketController } from './controllers/websocket.controller'; @@ -22,6 +23,7 @@ import { MessageUpModel, RabbitmqModel, SettingsModel, + TypebotModel, WebhookModel, WebsocketModel, } from './models'; @@ -34,6 +36,7 @@ import { MessageUpRepository } from './repository/messageUp.repository'; import { RabbitmqRepository } from './repository/rabbitmq.repository'; import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; +import { TypebotRepository } from './repository/typebot.repository'; import { WebhookRepository } from './repository/webhook.repository'; import { WebsocketRepository } from './repository/websocket.repository'; import { AuthService } from './services/auth.service'; @@ -41,6 +44,7 @@ import { ChatwootService } from './services/chatwoot.service'; import { WAMonitoringService } from './services/monitor.service'; import { RabbitmqService } from './services/rabbitmq.service'; import { SettingsService } from './services/settings.service'; +import { TypebotService } from './services/typebot.service'; import { WebhookService } from './services/webhook.service'; import { WebsocketService } from './services/websocket.service'; @@ -50,6 +54,7 @@ const messageRepository = new MessageRepository(MessageModel, configService); const chatRepository = new ChatRepository(ChatModel, configService); const contactRepository = new ContactRepository(ContactModel, configService); const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService); +const typebotRepository = new TypebotRepository(TypebotModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); const websocketRepository = new WebsocketRepository(WebsocketModel, configService); const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService); @@ -67,6 +72,7 @@ export const repository = new RepositoryBroker( settingsRepository, websocketRepository, rabbitmqRepository, + typebotRepository, authRepository, configService, dbserver?.getClient(), @@ -78,6 +84,10 @@ export const waMonitor = new WAMonitoringService(eventEmitter, configService, re const authService = new AuthService(configService, waMonitor, repository); +const typebotService = new TypebotService(waMonitor); + +export const typebotController = new TypebotController(typebotService); + const webhookService = new WebhookService(waMonitor); export const webhookController = new WebhookController(webhookService); From d99ccd9df630ed3ee969eb92a04387aef6eccbbf Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 4 Aug 2023 15:03:08 -0300 Subject: [PATCH 125/177] Added Typebot integration --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a5aca7..afe8c3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Added env var QRCODE_COLOR * Added websocket to send events * Added rabbitmq to send events +* Added Typebot integration ### Fixed @@ -20,6 +21,7 @@ ### Integrations - Chatwoot: v2.18.0 - v3.0.0 +- Typebot: v2.16.0 - Manager Evolution API # 1.4.8 (2023-07-27 10:27) From 469e696ab79aef94a71b3ad9c2e72a398f452115 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 4 Aug 2023 16:15:59 -0300 Subject: [PATCH 126/177] Added Typebot integration --- src/whatsapp/services/typebot.service.ts | 45 +++++++++++++++++++----- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 301cbe4f..2bae03cd 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -113,10 +113,10 @@ export class TypebotService { return request.data; } - public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], closeSession?: boolean) { - processMessages(this.waMonitor.waInstances[instance.instanceName], messages) + public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], input: any[]) { + processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input) .then(async () => { - if (closeSession) { + if (!input) { const typebotData = await this.find(instance); const session = typebotData.sessions.find((session) => session.remoteJid === remoteJid); @@ -132,11 +132,13 @@ export class TypebotService { console.error('Erro ao processar mensagens:', err); }); - async function processMessages(instance, messages) { + async function processMessages(instance, messages, input) { for (const message of messages) { if (message.type === 'text') { let formattedText = ''; + let linkPreview = false; + for (const richText of message.content.richText) { for (const element of richText.children) { let text = ''; @@ -159,6 +161,7 @@ export class TypebotService { if (element.url) { const linkText = element.children[0].text; text = `[${linkText}](${element.url})`; + linkPreview = true; } formattedText += text; @@ -173,7 +176,7 @@ export class TypebotService { options: { delay: 1200, presence: 'composing', - linkPreview: false, + linkPreview: linkPreview, }, textMessage: { text: formattedText, @@ -223,6 +226,32 @@ export class TypebotService { }); } } + + if (input) { + if (input.type === 'choice input') { + let formattedText = ''; + + const items = input.items; + + for (const item of items) { + formattedText += `▶️ ${item.content}\n`; + } + + formattedText = formattedText.replace(/\n$/, ''); + + await instance.textMessage({ + number: remoteJid.split('@')[0], + options: { + delay: 1200, + presence: 'composing', + linkPreview: false, + }, + textMessage: { + text: formattedText, + }, + }); + } + } } } @@ -252,7 +281,7 @@ export class TypebotService { remoteJid: remoteJid, }); - await this.sendWAMessage(instance, remoteJid, data.messages); + await this.sendWAMessage(instance, remoteJid, data.messages, data.input); return; } @@ -267,7 +296,7 @@ export class TypebotService { remoteJid: remoteJid, }); - await this.sendWAMessage(instance, remoteJid, data.messages); + await this.sendWAMessage(instance, remoteJid, data.messages, data.input); return; } @@ -329,7 +358,7 @@ export class TypebotService { }); } - await this.sendWAMessage(instance, remoteJid, request.data.messages, !request.data.input); + await this.sendWAMessage(instance, remoteJid, request.data.messages, request.data.input); return; } From f3cb8c531b8efc9cc28285b9accbf1bf7c2ad1cf Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 12:10:33 -0300 Subject: [PATCH 127/177] feat: added proxy endpoint --- package.json | 3 +- src/validate/validate.schema.ts | 11 ++++ .../controllers/instance.controller.ts | 36 +++++++++++ src/whatsapp/controllers/proxy.controller.ts | 26 ++++++++ src/whatsapp/dto/instance.dto.ts | 5 ++ src/whatsapp/dto/proxy.dto.ts | 4 ++ src/whatsapp/models/index.ts | 1 + src/whatsapp/models/proxy.model.ts | 18 ++++++ src/whatsapp/repository/proxy.repository.ts | 62 +++++++++++++++++++ src/whatsapp/repository/repository.manager.ts | 7 +++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/routers/proxy.router.ts | 52 ++++++++++++++++ src/whatsapp/services/proxy.service.ts | 33 ++++++++++ src/whatsapp/services/whatsapp.service.ts | 52 +++++++++++++++- src/whatsapp/types/wa.types.ts | 5 ++ src/whatsapp/whatsapp.module.ts | 11 ++++ 16 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 src/whatsapp/controllers/proxy.controller.ts create mode 100644 src/whatsapp/dto/proxy.dto.ts create mode 100644 src/whatsapp/models/proxy.model.ts create mode 100644 src/whatsapp/repository/proxy.repository.ts create mode 100644 src/whatsapp/routers/proxy.router.ts create mode 100644 src/whatsapp/services/proxy.service.ts diff --git a/package.json b/package.json index bb469865..6f92aaf3 100644 --- a/package.json +++ b/package.json @@ -64,12 +64,13 @@ "js-yaml": "^4.1.0", "jsonschema": "^1.4.1", "jsonwebtoken": "^8.5.1", + "libphonenumber-js": "^1.10.39", "link-preview-js": "^3.0.4", "mongoose": "^6.10.5", "node-cache": "^5.1.2", "node-mime-types": "^1.1.0", "pino": "^8.11.0", - "proxy-agent": "^6.2.1", + "proxy-agent": "^6.3.0", "qrcode": "^1.5.1", "qrcode-terminal": "^0.12.0", "redis": "^4.6.5", diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 7f101a96..32e25fac 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -987,3 +987,14 @@ export const typebotSchema: JSONSchema7 = { required: ['enabled', 'url', 'typebot', 'expire'], ...isNotEmpty('enabled', 'url', 'typebot', 'expire'), }; + +export const proxySchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + proxy: { type: 'string' }, + }, + required: ['enabled', 'proxy'], + ...isNotEmpty('enabled', 'proxy'), +}; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 9c4a65df..b5d99687 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -13,6 +13,7 @@ import { ChatwootService } from '../services/chatwoot.service'; import { WAMonitoringService } from '../services/monitor.service'; import { RabbitmqService } from '../services/rabbitmq.service'; import { SettingsService } from '../services/settings.service'; +import { TypebotService } from '../services/typebot.service'; import { WebhookService } from '../services/webhook.service'; import { WebsocketService } from '../services/websocket.service'; import { WAStartupService } from '../services/whatsapp.service'; @@ -30,6 +31,7 @@ export class InstanceController { private readonly settingsService: SettingsService, private readonly websocketService: WebsocketService, private readonly rabbitmqService: RabbitmqService, + private readonly typebotService: TypebotService, private readonly cache: RedisCache, ) {} @@ -59,6 +61,9 @@ export class InstanceController { websocket_events, rabbitmq_enabled, rabbitmq_events, + typebot_url, + typebot, + typebot_expire, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -223,6 +228,25 @@ export class InstanceController { } } + if (typebot_url) { + try { + if (!isURL(typebot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in typebot_url'); + } + + this.logger.verbose('creating typebot'); + + this.typebotService.create(instance, { + enabled: true, + url: typebot_url, + typebot: typebot, + expire: typebot_expire, + }); + } catch (error) { + this.logger.log(error); + } + } + this.logger.verbose('creating settings'); const settings: wa.LocalSettings = { reject_call: reject_call || false, @@ -266,6 +290,12 @@ export class InstanceController { enabled: rabbitmq_enabled, events: rabbitmqEvents, }, + typebot: { + enabled: typebot_url ? true : false, + url: typebot_url, + typebot, + expire: typebot_expire, + }, settings, qrcode: getQrcode, }; @@ -349,6 +379,12 @@ export class InstanceController { enabled: rabbitmq_enabled, events: rabbitmqEvents, }, + typebot: { + enabled: typebot_url ? true : false, + url: typebot_url, + typebot, + expire: typebot_expire, + }, settings, chatwoot: { enabled: true, diff --git a/src/whatsapp/controllers/proxy.controller.ts b/src/whatsapp/controllers/proxy.controller.ts new file mode 100644 index 00000000..1656d830 --- /dev/null +++ b/src/whatsapp/controllers/proxy.controller.ts @@ -0,0 +1,26 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { ProxyDto } from '../dto/proxy.dto'; +import { ProxyService } from '../services/proxy.service'; + +const logger = new Logger('ProxyController'); + +export class ProxyController { + constructor(private readonly proxyService: ProxyService) {} + + public async createProxy(instance: InstanceDto, data: ProxyDto) { + logger.verbose('requested createProxy from ' + instance.instanceName + ' instance'); + + if (!data.enabled) { + logger.verbose('proxy disabled'); + data.proxy = ''; + } + + return this.proxyService.create(instance, data); + } + + public async findProxy(instance: InstanceDto) { + logger.verbose('requested findProxy from ' + instance.instanceName + ' instance'); + return this.proxyService.find(instance); + } +} diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 0788b9a7..a58a20d5 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -22,4 +22,9 @@ export class InstanceDto { websocket_events?: string[]; rabbitmq_enabled?: boolean; rabbitmq_events?: string[]; + typebot_url?: string; + typebot?: string; + typebot_expire?: number; + proxy_enabled?: boolean; + proxy_proxy?: string; } diff --git a/src/whatsapp/dto/proxy.dto.ts b/src/whatsapp/dto/proxy.dto.ts new file mode 100644 index 00000000..0b6b2e70 --- /dev/null +++ b/src/whatsapp/dto/proxy.dto.ts @@ -0,0 +1,4 @@ +export class ProxyDto { + enabled: boolean; + proxy: string; +} diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index c44ffe7e..5d71911d 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -3,6 +3,7 @@ export * from './chat.model'; export * from './chatwoot.model'; export * from './contact.model'; export * from './message.model'; +export * from './proxy.model'; export * from './rabbitmq.model'; export * from './settings.model'; export * from './typebot.model'; diff --git a/src/whatsapp/models/proxy.model.ts b/src/whatsapp/models/proxy.model.ts new file mode 100644 index 00000000..3dea4f0c --- /dev/null +++ b/src/whatsapp/models/proxy.model.ts @@ -0,0 +1,18 @@ +import { Schema } from 'mongoose'; + +import { dbserver } from '../../libs/db.connect'; + +export class ProxyRaw { + _id?: string; + enabled?: boolean; + proxy?: string; +} + +const proxySchema = new Schema({ + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + proxy: { type: String, required: true }, +}); + +export const ProxyModel = dbserver?.model(ProxyRaw.name, proxySchema, 'proxy'); +export type IProxyModel = typeof ProxyModel; diff --git a/src/whatsapp/repository/proxy.repository.ts b/src/whatsapp/repository/proxy.repository.ts new file mode 100644 index 00000000..169e798f --- /dev/null +++ b/src/whatsapp/repository/proxy.repository.ts @@ -0,0 +1,62 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { IProxyModel, ProxyRaw } from '../models'; + +export class ProxyRepository extends Repository { + constructor(private readonly proxyModel: IProxyModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('ProxyRepository'); + + public async create(data: ProxyRaw, instance: string): Promise { + try { + this.logger.verbose('creating proxy'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving proxy to db'); + const insert = await this.proxyModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('proxy saved to db: ' + insert.modifiedCount + ' proxy'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving proxy to store'); + + this.writeStore({ + path: join(this.storePath, 'proxy'), + fileName: instance, + data, + }); + + this.logger.verbose('proxy saved to store in path: ' + join(this.storePath, 'proxy') + '/' + instance); + + this.logger.verbose('proxy created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding proxy'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding proxy in db'); + return await this.proxyModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding proxy in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'proxy', instance + '.json'), { + encoding: 'utf-8', + }), + ) as ProxyRaw; + } catch (error) { + return {}; + } + } +} diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index e724ef02..2cd4931e 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -10,6 +10,7 @@ import { ChatwootRepository } from './chatwoot.repository'; import { ContactRepository } from './contact.repository'; import { MessageRepository } from './message.repository'; import { MessageUpRepository } from './messageUp.repository'; +import { ProxyRepository } from './proxy.repository'; import { RabbitmqRepository } from './rabbitmq.repository'; import { SettingsRepository } from './settings.repository'; import { TypebotRepository } from './typebot.repository'; @@ -27,6 +28,7 @@ export class RepositoryBroker { public readonly websocket: WebsocketRepository, public readonly rabbitmq: RabbitmqRepository, public readonly typebot: TypebotRepository, + public readonly proxy: ProxyRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -60,6 +62,7 @@ export class RepositoryBroker { const websocketDir = join(storePath, 'websocket'); const rabbitmqDir = join(storePath, 'rabbitmq'); const typebotDir = join(storePath, 'typebot'); + const proxyDir = join(storePath, 'proxy'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -106,6 +109,10 @@ export class RepositoryBroker { this.logger.verbose('creating typebot dir: ' + typebotDir); fs.mkdirSync(typebotDir, { recursive: true }); } + if (!fs.existsSync(proxyDir)) { + this.logger.verbose('creating proxy dir: ' + proxyDir); + fs.mkdirSync(proxyDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index f5ad08e8..a84e815d 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -8,6 +8,7 @@ import { ChatRouter } from './chat.router'; import { ChatwootRouter } from './chatwoot.router'; import { GroupRouter } from './group.router'; import { InstanceRouter } from './instance.router'; +import { ProxyRouter } from './proxy.router'; import { RabbitmqRouter } from './rabbitmq.router'; import { MessageRouter } from './sendMessage.router'; import { SettingsRouter } from './settings.router'; @@ -50,6 +51,7 @@ router .use('/settings', new SettingsRouter(...guards).router) .use('/websocket', new WebsocketRouter(...guards).router) .use('/rabbitmq', new RabbitmqRouter(...guards).router) - .use('/typebot', new TypebotRouter(...guards).router); + .use('/typebot', new TypebotRouter(...guards).router) + .use('/proxy', new ProxyRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/routers/proxy.router.ts b/src/whatsapp/routers/proxy.router.ts new file mode 100644 index 00000000..2ae0141b --- /dev/null +++ b/src/whatsapp/routers/proxy.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; +import { instanceNameSchema, proxySchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { ProxyDto } from '../dto/proxy.dto'; +import { proxyController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; + +const logger = new Logger('ProxyRouter'); + +export class ProxyRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setProxy'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: proxySchema, + ClassRef: ProxyDto, + execute: (instance, data) => proxyController.createProxy(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findProxy'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => proxyController.findProxy(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/services/proxy.service.ts b/src/whatsapp/services/proxy.service.ts new file mode 100644 index 00000000..c6631671 --- /dev/null +++ b/src/whatsapp/services/proxy.service.ts @@ -0,0 +1,33 @@ +import { Logger } from '../../config/logger.config'; +import { InstanceDto } from '../dto/instance.dto'; +import { ProxyDto } from '../dto/proxy.dto'; +import { ProxyRaw } from '../models'; +import { WAMonitoringService } from './monitor.service'; + +export class ProxyService { + constructor(private readonly waMonitor: WAMonitoringService) {} + + private readonly logger = new Logger(ProxyService.name); + + public create(instance: InstanceDto, data: ProxyDto) { + this.logger.verbose('create proxy: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setProxy(data); + + return { proxy: { ...instance, proxy: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find proxy: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findProxy(); + + if (Object.keys(result).length === 0) { + throw new Error('Proxy not found'); + } + + return result; + } catch (error) { + return { enabled: false, proxy: '' }; + } + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index a1237b49..f71300ea 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -44,6 +44,8 @@ import { getMIMEType } from 'node-mime-types'; import { release } from 'os'; import { join } from 'path'; import P from 'pino'; +import { ProxyAgent } from 'proxy-agent'; +// import { ProxyAgent } from 'proxy-agent'; import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; import qrcodeTerminal from 'qrcode-terminal'; import sharp from 'sharp'; @@ -111,7 +113,7 @@ import { SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { RabbitmqRaw, SettingsRaw, TypebotRaw } from '../models'; +import { ProxyRaw, RabbitmqRaw, SettingsRaw, TypebotRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; import { ChatwootRaw } from '../models/chatwoot.model'; import { ContactRaw } from '../models/contact.model'; @@ -148,6 +150,7 @@ export class WAStartupService { private readonly localWebsocket: wa.LocalWebsocket = {}; private readonly localRabbitmq: wa.LocalRabbitmq = {}; private readonly localTypebot: wa.LocalTypebot = {}; + private readonly localProxy: wa.LocalProxy = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -529,6 +532,41 @@ export class WAStartupService { return data; } + private async loadProxy() { + this.logger.verbose('Loading proxy'); + const data = await this.repository.proxy.find(this.instanceName); + + this.localProxy.enabled = data?.enabled; + this.logger.verbose(`Proxy enabled: ${this.localProxy.enabled}`); + + this.localProxy.proxy = data?.proxy; + this.logger.verbose(`Proxy proxy: ${this.localProxy.proxy}`); + + this.logger.verbose('Proxy loaded'); + } + + public async setProxy(data: ProxyRaw) { + this.logger.verbose('Setting proxy'); + await this.repository.proxy.create(data, this.instanceName); + this.logger.verbose(`Proxy proxy: ${data.proxy}`); + Object.assign(this.localProxy, data); + this.logger.verbose('Proxy set'); + + this.client?.ws?.close(); + } + + public async findProxy() { + this.logger.verbose('Finding proxy'); + const data = await this.repository.proxy.find(this.instanceName); + + if (!data) { + this.logger.verbose('Proxy not found'); + throw new NotFoundException('Proxy not found'); + } + + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; @@ -990,6 +1028,7 @@ export class WAStartupService { this.loadWebsocket(); this.loadRabbitmq(); this.loadTypebot(); + this.loadProxy(); this.instance.authState = await this.defineAuthState(); @@ -999,7 +1038,18 @@ export class WAStartupService { const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; this.logger.verbose('Browser: ' + JSON.stringify(browser)); + let options; + + if (this.localProxy.enabled) { + this.logger.verbose('Proxy enabled'); + options = { + agent: new ProxyAgent(this.localProxy.proxy as any), + fetchAgent: new ProxyAgent(this.localProxy.proxy as any), + }; + } + const socketConfig: UserFacingSocketConfig = { + ...options, auth: { creds: this.instance.authState.state.creds, keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d54b0366..84113b42 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -94,6 +94,11 @@ export declare namespace wa { sessions?: Session[]; }; + export type LocalProxy = { + enabled?: boolean; + proxy?: string; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 2cb045ae..d8ed5a62 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -7,6 +7,7 @@ import { ChatController } from './controllers/chat.controller'; import { ChatwootController } from './controllers/chatwoot.controller'; import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; +import { ProxyController } from './controllers/proxy.controller'; import { RabbitmqController } from './controllers/rabbitmq.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; import { SettingsController } from './controllers/settings.controller'; @@ -21,6 +22,7 @@ import { ContactModel, MessageModel, MessageUpModel, + ProxyModel, RabbitmqModel, SettingsModel, TypebotModel, @@ -33,6 +35,7 @@ import { ChatwootRepository } from './repository/chatwoot.repository'; import { ContactRepository } from './repository/contact.repository'; import { MessageRepository } from './repository/message.repository'; import { MessageUpRepository } from './repository/messageUp.repository'; +import { ProxyRepository } from './repository/proxy.repository'; import { RabbitmqRepository } from './repository/rabbitmq.repository'; import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; @@ -42,6 +45,7 @@ import { WebsocketRepository } from './repository/websocket.repository'; import { AuthService } from './services/auth.service'; import { ChatwootService } from './services/chatwoot.service'; import { WAMonitoringService } from './services/monitor.service'; +import { ProxyService } from './services/proxy.service'; import { RabbitmqService } from './services/rabbitmq.service'; import { SettingsService } from './services/settings.service'; import { TypebotService } from './services/typebot.service'; @@ -57,6 +61,7 @@ const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configSe const typebotRepository = new TypebotRepository(TypebotModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); const websocketRepository = new WebsocketRepository(WebsocketModel, configService); +const proxyRepository = new ProxyRepository(ProxyModel, configService); const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService); const chatwootRepository = new ChatwootRepository(ChatwootModel, configService); const settingsRepository = new SettingsRepository(SettingsModel, configService); @@ -73,6 +78,7 @@ export const repository = new RepositoryBroker( websocketRepository, rabbitmqRepository, typebotRepository, + proxyRepository, authRepository, configService, dbserver?.getClient(), @@ -96,6 +102,10 @@ const websocketService = new WebsocketService(waMonitor); export const websocketController = new WebsocketController(websocketService); +const proxyService = new ProxyService(waMonitor); + +export const proxyController = new ProxyController(proxyService); + const rabbitmqService = new RabbitmqService(waMonitor); export const rabbitmqController = new RabbitmqController(rabbitmqService); @@ -119,6 +129,7 @@ export const instanceController = new InstanceController( settingsService, websocketService, rabbitmqService, + typebotService, cache, ); export const viewsController = new ViewsController(waMonitor, configService); From a16b5f4644bb95a310a474b2b6e5bd68138d1fa0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 12:10:53 -0300 Subject: [PATCH 128/177] feat: added proxy endpoint --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afe8c3b9..1682dca9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Added websocket to send events * Added rabbitmq to send events * Added Typebot integration +* Added proxy endpoint ### Fixed From 7c5d94c19e3c4579201a7b073677927152f6cdc2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 15:43:57 -0300 Subject: [PATCH 129/177] feat: Added Typebot integration --- .DS_Store | Bin 6148 -> 6148 bytes src/validate/validate.schema.ts | 13 ++ .../controllers/instance.controller.ts | 8 ++ .../controllers/typebot.controller.ts | 5 + src/whatsapp/dto/instance.dto.ts | 2 + src/whatsapp/dto/typebot.dto.ts | 3 + src/whatsapp/models/typebot.model.ts | 6 + src/whatsapp/routers/typebot.router.ts | 18 ++- src/whatsapp/services/typebot.service.ts | 135 ++++++++++-------- src/whatsapp/services/whatsapp.service.ts | 11 +- src/whatsapp/types/wa.types.ts | 2 + 11 files changed, 140 insertions(+), 63 deletions(-) diff --git a/.DS_Store b/.DS_Store index f07b5fd410a708405b4339fdbe299d449393688a..caa91ed2bf7099a4dcefae8fb599c2a42bb93461 100644 GIT binary patch delta 82 zcmZoMXfc=|#>B`mF;Q%yo}wrV0|Nsi1A_nqLn=d2PP$=ma(-^X#Kh%{ESp=Hnprm% iR4{I4=iui6>ewvE{GE9+zlbFVP!C8G)8+t?EzAHF%Mxz@ delta 197 zcmZoMXfc=|#>B)qu~2NHo+2j)0|Nsi1A_p=#F+J)H!!j=)`LV?7*ZHA8HyQ7a?%Zh zlk;;6fMN^`?8_yP<#O{~T#|C~lYn9zNerf+TV;+qqROY>l`qIZGMncCP%8r)gUe>T_YKu2y~$oQRkGQWr=2hfc`#K5pQKx7Lu0IOXpivR!s diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 32e25fac..81a61127 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -983,11 +983,24 @@ export const typebotSchema: JSONSchema7 = { url: { type: 'string' }, typebot: { type: 'string' }, expire: { type: 'integer' }, + delay_message: { type: 'integer' }, + unknown_message: { type: 'string' }, }, required: ['enabled', 'url', 'typebot', 'expire'], ...isNotEmpty('enabled', 'url', 'typebot', 'expire'), }; +export const typebotStatusSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + remoteJid: { type: 'string' }, + status: { type: 'string', enum: ['opened', 'closed', 'paused'] }, + }, + required: ['remoteJid', 'status'], + ...isNotEmpty('remoteJid', 'status'), +}; + export const proxySchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index b5d99687..883e5431 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -64,6 +64,8 @@ export class InstanceController { typebot_url, typebot, typebot_expire, + typebot_delay_message, + typebot_unknown_message, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -241,6 +243,8 @@ export class InstanceController { url: typebot_url, typebot: typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }); } catch (error) { this.logger.log(error); @@ -295,6 +299,8 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }, settings, qrcode: getQrcode, @@ -384,6 +390,8 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }, settings, chatwoot: { diff --git a/src/whatsapp/controllers/typebot.controller.ts b/src/whatsapp/controllers/typebot.controller.ts index aff33511..0cda7d57 100644 --- a/src/whatsapp/controllers/typebot.controller.ts +++ b/src/whatsapp/controllers/typebot.controller.ts @@ -33,4 +33,9 @@ export class TypebotController { logger.verbose('requested findTypebot from ' + instance.instanceName + ' instance'); return this.typebotService.find(instance); } + + public async changeStatus(instance: InstanceDto, data: any) { + logger.verbose('requested changeStatus from ' + instance.instanceName + ' instance'); + return this.typebotService.changeStatus(instance, data); + } } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index a58a20d5..a93fed73 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -25,6 +25,8 @@ export class InstanceDto { typebot_url?: string; typebot?: string; typebot_expire?: number; + typebot_delay_message?: number; + typebot_unknown_message?: string; proxy_enabled?: boolean; proxy_proxy?: string; } diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts index 57798bdb..9c8759dc 100644 --- a/src/whatsapp/dto/typebot.dto.ts +++ b/src/whatsapp/dto/typebot.dto.ts @@ -1,6 +1,7 @@ export class Session { remoteJid?: string; sessionId?: string; + status?: string; createdAt?: number; updateAt?: number; } @@ -10,5 +11,7 @@ export class TypebotDto { url: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; } diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts index bff7092c..5358d0c2 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -5,6 +5,7 @@ import { dbserver } from '../../libs/db.connect'; class Session { remoteJid?: string; sessionId?: string; + status?: string; createdAt?: number; updateAt?: number; } @@ -15,6 +16,8 @@ export class TypebotRaw { url: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; } @@ -24,10 +27,13 @@ const typebotSchema = new Schema({ url: { type: String, required: true }, typebot: { type: String, required: true }, expire: { type: Number, required: true }, + delay_message: { type: Number, required: true }, + unknown_message: { type: String, required: true }, sessions: [ { remoteJid: { type: String, required: true }, sessionId: { type: String, required: true }, + status: { type: String, required: true }, createdAt: { type: Number, required: true }, updateAt: { type: Number, required: true }, }, diff --git a/src/whatsapp/routers/typebot.router.ts b/src/whatsapp/routers/typebot.router.ts index 4d770444..68bb6395 100644 --- a/src/whatsapp/routers/typebot.router.ts +++ b/src/whatsapp/routers/typebot.router.ts @@ -1,7 +1,7 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; -import { instanceNameSchema, typebotSchema } from '../../validate/validate.schema'; +import { instanceNameSchema, typebotSchema, typebotStatusSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { TypebotDto } from '../dto/typebot.dto'; @@ -44,6 +44,22 @@ export class TypebotRouter extends RouterBroker { execute: (instance) => typebotController.findTypebot(instance), }); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('changeStatus'), ...guards, async (req, res) => { + logger.verbose('request received in findTypebot'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: typebotStatusSchema, + ClassRef: InstanceDto, + execute: (instance, data) => typebotController.changeStatus(instance, data), + }); + res.status(HttpStatus.OK).json(response); }); } diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 2bae03cd..491459bb 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -33,23 +33,57 @@ export class TypebotService { } } + public async changeStatus(instance: InstanceDto, data: any) { + const remoteJid = data.remoteJid; + const status = data.status; + + const findData = await this.find(instance); + + const session = findData.sessions.find((session) => session.remoteJid === remoteJid); + + if (session) { + if (status === 'closed') { + findData.sessions.splice(findData.sessions.indexOf(session), 1); + + const typebotData = { + enabled: true, + url: findData.url, + typebot: findData.typebot, + expire: findData.expire, + sessions: findData.sessions, + }; + + this.create(instance, typebotData); + + return { typebot: { ...instance, typebot: typebotData } }; + } + + findData.sessions.map((session) => { + if (session.remoteJid === remoteJid) { + session.status = status; + } + }); + } + + const typebotData = { + enabled: true, + url: findData.url, + typebot: findData.typebot, + expire: findData.expire, + sessions: findData.sessions, + }; + + this.create(instance, typebotData); + + return { typebot: { ...instance, typebot: typebotData } }; + } + private getTypeMessage(msg: any) { this.logger.verbose('get type message'); const types = { conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: undefined, - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage, - liveLocationMessage: msg.liveLocationMessage, }; this.logger.verbose('type message: ' + types); @@ -86,6 +120,10 @@ export class TypebotService { sessionId: id, startParams: { typebot: data.typebot, + prefilledVariables: { + remoteJid: data.remoteJid, + pushName: data.pushName, + }, }, }; @@ -95,6 +133,7 @@ export class TypebotService { data.sessions.push({ remoteJid: data.remoteJid, sessionId: `${id}-${request.data.sessionId}`, + status: 'opened', createdAt: Date.now(), updateAt: Date.now(), }); @@ -114,23 +153,9 @@ export class TypebotService { } public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], input: any[]) { - processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input) - .then(async () => { - if (!input) { - const typebotData = await this.find(instance); - - const session = typebotData.sessions.find((session) => session.remoteJid === remoteJid); - - if (session) { - typebotData.sessions.splice(typebotData.sessions.indexOf(session), 1); - - this.create(instance, typebotData); - } - } - }) - .catch((err) => { - console.error('Erro ao processar mensagens:', err); - }); + processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input).catch((err) => { + console.error('Erro ao processar mensagens:', err); + }); async function processMessages(instance, messages, input) { for (const message of messages) { @@ -174,7 +199,7 @@ export class TypebotService { await instance.textMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', linkPreview: linkPreview, }, @@ -188,7 +213,7 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -202,7 +227,7 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -216,7 +241,7 @@ export class TypebotService { await instance.audioWhatsapp({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'recording', encoding: true, }, @@ -279,6 +304,7 @@ export class TypebotService { expire: expire, sessions: sessions, remoteJid: remoteJid, + pushName: msg.pushName, }); await this.sendWAMessage(instance, remoteJid, data.messages, data.input); @@ -287,6 +313,10 @@ export class TypebotService { } } + if (session && session.status !== 'opened') { + return; + } + if (!session) { const data = await this.createNewSession(instance, { url: url, @@ -294,6 +324,7 @@ export class TypebotService { expire: expire, sessions: sessions, remoteJid: remoteJid, + pushName: msg.pushName, }); await this.sendWAMessage(instance, remoteJid, data.messages, data.input); @@ -320,22 +351,18 @@ export class TypebotService { const content = this.getConversationMessage(msg.message); if (!content) { - return; - } - - if (content.toLowerCase() === 'sair') { - sessions.splice(sessions.indexOf(session), 1); - - const typebotData = { - enabled: true, - url: url, - typebot: typebot, - expire: expire, - sessions, - }; - - this.create(instance, typebotData); - + if (this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message) { + this.waMonitor.waInstances[instance.instanceName].textMessage({ + number: remoteJid.split('@')[0], + options: { + delay: this.waMonitor.waInstances[instance.instanceName].localTypebot.delay_message || 1000, + presence: 'composing', + }, + textMessage: { + text: this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message, + }, + }); + } return; } @@ -346,18 +373,6 @@ export class TypebotService { const request = await axios.post(url + '/api/v1/sendMessage', reqData); - if (!request.data.input) { - sessions.splice(sessions.indexOf(session), 1); - - await this.createNewSession(instance, { - url: url, - typebot: typebot, - expire: expire, - sessions: sessions, - remoteJid: remoteJid, - }); - } - await this.sendWAMessage(instance, remoteJid, request.data.messages, request.data.input); return; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index f71300ea..241555ff 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -45,7 +45,6 @@ import { release } from 'os'; import { join } from 'path'; import P from 'pino'; import { ProxyAgent } from 'proxy-agent'; -// import { ProxyAgent } from 'proxy-agent'; import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; import qrcodeTerminal from 'qrcode-terminal'; import sharp from 'sharp'; @@ -149,7 +148,7 @@ export class WAStartupService { private readonly localSettings: wa.LocalSettings = {}; private readonly localWebsocket: wa.LocalWebsocket = {}; private readonly localRabbitmq: wa.LocalRabbitmq = {}; - private readonly localTypebot: wa.LocalTypebot = {}; + public readonly localTypebot: wa.LocalTypebot = {}; private readonly localProxy: wa.LocalProxy = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); @@ -506,6 +505,12 @@ export class WAStartupService { this.localTypebot.expire = data?.expire; this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`); + this.localTypebot.delay_message = data?.delay_message; + this.logger.verbose(`Typebot delay_message: ${this.localTypebot.delay_message}`); + + this.localTypebot.unknown_message = data?.unknown_message; + this.logger.verbose(`Typebot unknown_message: ${this.localTypebot.unknown_message}`); + this.localTypebot.sessions = data?.sessions; this.logger.verbose('Typebot loaded'); @@ -516,6 +521,8 @@ export class WAStartupService { await this.repository.typebot.create(data, this.instanceName); this.logger.verbose(`Typebot typebot: ${data.typebot}`); this.logger.verbose(`Typebot expire: ${data.expire}`); + this.logger.verbose(`Typebot sessions: ${data.delay_message}`); + this.logger.verbose(`Typebot sessions: ${data.unknown_message}`); Object.assign(this.localTypebot, data); this.logger.verbose('Typebot set'); } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 84113b42..b20165d9 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -91,6 +91,8 @@ export declare namespace wa { url?: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; }; From b502ebd23ac86e784fbac06471d30032a2462521 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 18:54:12 -0300 Subject: [PATCH 130/177] feat: Added Typebot integration --- Docker/.env.example | 8 ++-- Dockerfile | 2 + src/config/env.config.ts | 8 ++++ src/dev-env.yml | 3 ++ src/libs/socket.server.ts | 33 +++++++------ .../controllers/instance.controller.ts | 8 +++- src/whatsapp/dto/instance.dto.ts | 1 + src/whatsapp/dto/typebot.dto.ts | 1 + src/whatsapp/models/typebot.model.ts | 2 + src/whatsapp/services/typebot.service.ts | 46 +++++++++++++++++-- src/whatsapp/services/whatsapp.service.ts | 11 +++-- src/whatsapp/types/wa.types.ts | 1 + 12 files changed, 98 insertions(+), 26 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index 0f4f2972..bf21a71c 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -31,7 +31,7 @@ CLEAN_STORE_CONTACTS=true CLEAN_STORE_CHATS=true # Permanent data storage -DATABASE_ENABLED=true +DATABASE_ENABLED=false DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true DATABASE_CONNECTION_DB_PREFIX_NAME=evdocker @@ -42,13 +42,15 @@ DATABASE_SAVE_MESSAGE_UPDATE=false DATABASE_SAVE_DATA_CONTACTS=false DATABASE_SAVE_DATA_CHATS=false -REDIS_ENABLED=true +REDIS_ENABLED=false REDIS_URI=redis://redis:6379 REDIS_PREFIX_KEY=evdocker -RABBITMQ_ENABLED=true +RABBITMQ_ENABLED=false RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 +WEBSOCKET_ENABLED=false + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created ## Define a global webhook that will listen for enabled events from all instances diff --git a/Dockerfile b/Dockerfile index 4484b8b8..c9975782 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,6 +54,8 @@ ENV REDIS_PREFIX_KEY=evolution ENV RABBITMQ_ENABLED=false ENV RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 +ENV WEBSOCKET_ENABLED=false + ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 8ddb4e2c..4f28dbd5 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -66,6 +66,10 @@ export type Rabbitmq = { URI: string; }; +export type Websocket = { + ENABLED: boolean; +}; + export type EventsWebhook = { APPLICATION_STARTUP: boolean; QRCODE_UPDATED: boolean; @@ -122,6 +126,7 @@ export interface Env { DATABASE: Database; REDIS: Redis; RABBITMQ: Rabbitmq; + WEBSOCKET: Websocket; LOG: Log; DEL_INSTANCE: DelInstance; WEBHOOK: Webhook; @@ -211,6 +216,9 @@ export class ConfigService { ENABLED: process.env?.RABBITMQ_ENABLED === 'true', URI: process.env.RABBITMQ_URI, }, + WEBSOCKET: { + ENABLED: process.env?.WEBSOCKET_ENABLED === 'true', + }, LOG: { LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], COLOR: process.env?.LOG_COLOR === 'true', diff --git a/src/dev-env.yml b/src/dev-env.yml index 02cb0730..235ec1b7 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -83,6 +83,9 @@ RABBITMQ: ENABLED: false URI: "amqp://guest:guest@localhost:5672" +WEBSOCKET: + ENABLED: false + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created WEBHOOK: diff --git a/src/libs/socket.server.ts b/src/libs/socket.server.ts index 367a3933..9da11b0a 100644 --- a/src/libs/socket.server.ts +++ b/src/libs/socket.server.ts @@ -1,7 +1,7 @@ import { Server } from 'http'; import { Server as SocketIO } from 'socket.io'; -import { configService, Cors } from '../config/env.config'; +import { configService, Cors, Websocket } from '../config/env.config'; import { Logger } from '../config/logger.config'; const logger = new Logger('Socket'); @@ -11,22 +11,25 @@ let io: SocketIO; const cors = configService.get('CORS').ORIGIN; export const initIO = (httpServer: Server) => { - io = new SocketIO(httpServer, { - cors: { - origin: cors, - }, - }); - - io.on('connection', (socket) => { - logger.info('User connected'); - - socket.on('disconnect', () => { - logger.info('User disconnected'); + if (configService.get('WEBSOCKET').ENABLED) { + io = new SocketIO(httpServer, { + cors: { + origin: cors, + }, }); - }); - logger.info('Socket.io initialized'); - return io; + io.on('connection', (socket) => { + logger.info('User connected'); + + socket.on('disconnect', () => { + logger.info('User disconnected'); + }); + }); + + logger.info('Socket.io initialized'); + return io; + } + return null; }; export const getIO = (): SocketIO => { diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 883e5431..2a904761 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -64,6 +64,7 @@ export class InstanceController { typebot_url, typebot, typebot_expire, + typebot_keyword_finish, typebot_delay_message, typebot_unknown_message, }: InstanceDto) { @@ -243,6 +244,7 @@ export class InstanceController { url: typebot_url, typebot: typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }); @@ -286,7 +288,7 @@ export class InstanceController { webhook_by_events, events: webhookEvents, }, - websocker: { + websocket: { enabled: websocket_enabled, events: websocketEvents, }, @@ -299,6 +301,7 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }, @@ -377,7 +380,7 @@ export class InstanceController { webhook_by_events, events: webhookEvents, }, - websocker: { + websocket: { enabled: websocket_enabled, events: websocketEvents, }, @@ -390,6 +393,7 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index a93fed73..cffe0303 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -25,6 +25,7 @@ export class InstanceDto { typebot_url?: string; typebot?: string; typebot_expire?: number; + typebot_keyword_finish?: string; typebot_delay_message?: number; typebot_unknown_message?: string; proxy_enabled?: boolean; diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts index 9c8759dc..cda5ae58 100644 --- a/src/whatsapp/dto/typebot.dto.ts +++ b/src/whatsapp/dto/typebot.dto.ts @@ -11,6 +11,7 @@ export class TypebotDto { url: string; typebot?: string; expire?: number; + keyword_finish?: string; delay_message?: number; unknown_message?: string; sessions?: Session[]; diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts index 5358d0c2..5b005294 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -16,6 +16,7 @@ export class TypebotRaw { url: string; typebot?: string; expire?: number; + keyword_finish?: string; delay_message?: number; unknown_message?: string; sessions?: Session[]; @@ -27,6 +28,7 @@ const typebotSchema = new Schema({ url: { type: String, required: true }, typebot: { type: String, required: true }, expire: { type: Number, required: true }, + keyword_finish: { type: String, required: true }, delay_message: { type: Number, required: true }, unknown_message: { type: String, required: true }, sessions: [ diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 491459bb..22cdd9b8 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -50,6 +50,9 @@ export class TypebotService { url: findData.url, typebot: findData.typebot, expire: findData.expire, + keyword_finish: findData.keyword_finish, + delay_message: findData.delay_message, + unknown_message: findData.unknown_message, sessions: findData.sessions, }; @@ -70,6 +73,9 @@ export class TypebotService { url: findData.url, typebot: findData.typebot, expire: findData.expire, + keyword_finish: findData.keyword_finish, + delay_message: findData.delay_message, + unknown_message: findData.unknown_message, sessions: findData.sessions, }; @@ -143,6 +149,9 @@ export class TypebotService { url: data.url, typebot: data.typebot, expire: data.expire, + keyword_finish: data.keyword_finish, + delay_message: data.delay_message, + unknown_message: data.unknown_message, sessions: data.sessions, }; @@ -285,6 +294,9 @@ export class TypebotService { const typebot = (await this.find(instance)).typebot; const sessions = ((await this.find(instance)).sessions as Session[]) ?? []; const expire = (await this.find(instance)).expire; + const keyword_finish = (await this.find(instance)).keyword_finish; + const delay_message = (await this.find(instance)).delay_message; + const unknown_message = (await this.find(instance)).unknown_message; const session = sessions.find((session) => session.remoteJid === remoteJid); @@ -302,6 +314,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -322,6 +337,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -343,6 +361,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions, }; @@ -351,21 +372,40 @@ export class TypebotService { const content = this.getConversationMessage(msg.message); if (!content) { - if (this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message) { + if (unknown_message) { this.waMonitor.waInstances[instance.instanceName].textMessage({ number: remoteJid.split('@')[0], options: { - delay: this.waMonitor.waInstances[instance.instanceName].localTypebot.delay_message || 1000, + delay: delay_message || 1000, presence: 'composing', }, textMessage: { - text: this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message, + text: unknown_message, }, }); } return; } + if (content.toLowerCase() === keyword_finish.toLowerCase()) { + sessions.splice(sessions.indexOf(session), 1); + + const typebotData = { + enabled: true, + url: url, + typebot: typebot, + expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, + sessions, + }; + + this.create(instance, typebotData); + + return; + } + const reqData = { message: content, sessionId: session.sessionId.split('-')[1], diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 241555ff..6d24b61d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -61,6 +61,7 @@ import { QrCode, Redis, Webhook, + Websocket, } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; @@ -505,6 +506,9 @@ export class WAStartupService { this.localTypebot.expire = data?.expire; this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`); + this.localTypebot.keyword_finish = data?.keyword_finish; + this.logger.verbose(`Typebot keyword_finish: ${this.localTypebot.keyword_finish}`); + this.localTypebot.delay_message = data?.delay_message; this.logger.verbose(`Typebot delay_message: ${this.localTypebot.delay_message}`); @@ -521,8 +525,9 @@ export class WAStartupService { await this.repository.typebot.create(data, this.instanceName); this.logger.verbose(`Typebot typebot: ${data.typebot}`); this.logger.verbose(`Typebot expire: ${data.expire}`); - this.logger.verbose(`Typebot sessions: ${data.delay_message}`); - this.logger.verbose(`Typebot sessions: ${data.unknown_message}`); + this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`); + this.logger.verbose(`Typebot delay_message: ${data.delay_message}`); + this.logger.verbose(`Typebot unknown_message: ${data.unknown_message}`); Object.assign(this.localTypebot, data); this.logger.verbose('Typebot set'); } @@ -618,7 +623,7 @@ export class WAStartupService { } } - if (this.localWebsocket.enabled) { + if (this.configService.get('WEBSOCKET').ENABLED && this.localWebsocket.enabled) { this.logger.verbose('Sending data to websocket on channel: ' + this.instance.name); if (Array.isArray(websocketLocal) && websocketLocal.includes(we)) { this.logger.verbose('Sending data to websocket on event: ' + event); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index b20165d9..893b5f87 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -91,6 +91,7 @@ export declare namespace wa { url?: string; typebot?: string; expire?: number; + keyword_finish?: string; delay_message?: number; unknown_message?: string; sessions?: Session[]; From ad819bf3ba6f08879522ac647bcc87b9ca4d3b88 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 19:03:15 -0300 Subject: [PATCH 131/177] feat: Added Typebot integration --- .DS_Store | Bin 6148 -> 6148 bytes Extras/appsmith/manager.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.DS_Store b/.DS_Store index caa91ed2bf7099a4dcefae8fb599c2a42bb93461..bc7339d20c06947ceac4918cf883130305e8fcad 100644 GIT binary patch delta 227 zcmZoMXfc=|#>B)qu~2NHo+2kF0|Nsi1A_p=#F+J)H!!j=)`LV?7*ZHA8HyQ7a?%Zh zlk;;6fMN^`?8_yP<#O{~T#|C~lYn9zNerf+TV;+qqROY>l`qIZGMncCP%8r)gUe(g z##Tu-23Lj(h7yJ%hD3(qvf!e;ocz3WpgiN|g^c%EHnVf^a{#>nB`mF;Q%yo}wrV0|Nsi1A_nqLn=d2PP$=ma(-^X#Kh%{ER$Q9x;L9L oUt-zpz&wv}Gdl-A2THh-_g70FlEKE&u=k diff --git a/Extras/appsmith/manager.json b/Extras/appsmith/manager.json index 6ba96e76..0c26ec23 100644 --- a/Extras/appsmith/manager.json +++ b/Extras/appsmith/manager.json @@ -1 +1 @@ -{"clientSchemaVersion":1.0,"serverSchemaVersion":6.0,"exportedApplication":{"name":"EvolutionAPI Public","isPublic":true,"pages":[{"id":"Home","isDefault":true}],"publishedPages":[{"id":"Home","isDefault":true}],"viewMode":false,"appIsExample":false,"unreadCommentThreads":0.0,"color":"#F5D1D1","icon":"bar-graph","slug":"evolutionapi-public","unpublishedAppLayout":{"type":"DESKTOP"},"publishedAppLayout":{"type":"DESKTOP"},"unpublishedCustomJSLibs":[],"publishedCustomJSLibs":[],"evaluationVersion":2.0,"applicationVersion":2.0,"collapseInvisibleWidgets":true,"isManualUpdate":false,"deleted":false},"datasourceList":[],"customJSLibList":[],"pageList":[{"unpublishedPage":{"name":"Home","slug":"home","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":80.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":97.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"Actions","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Actions","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run();\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":2.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":149.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1490.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1490.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":3.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"}],"displayName":"JSON Form","bottomRow":147.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1490.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":42.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"4","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"publishedPage":{"name":"Home","slug":"home","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":80.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":97.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"Actions","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Actions","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run();\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":2.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{fetch_Instances.run();\nstoreValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\ncloseModal('ModalConfig').then(() => {\n showAlert('successful login', 'success');\n});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":149.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1490.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1490.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":3.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"}],"displayName":"JSON Form","bottomRow":147.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1490.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":42.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore}},\n \"always_online\": {{Find_Settings.data.always_online}},\n \"read_messages\": {{Find_Settings.data.read_messages}},\n \"read_status\": {{Find_Settings.data.read_status}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"4","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56"}],"actionList":[{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_fetch_Instances","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788"},{"pluginType":"JS","pluginId":"js-plugin","unpublishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Scripts.verifyConfig","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Connect","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"publishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"id":"Home_Restart","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"publishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"id":"Home_Logout","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"publishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"id":"Home_Delete","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"publishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"id":"Home_Create_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"publishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"id":"Home_Find_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"publishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"id":"Home_Find_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"publishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"id":"Home_Find_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"publishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"id":"Home_Set_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"publishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"id":"Home_Set_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormChatwoot.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormChatwoot.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"publishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormChatwoot.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormChatwoot.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"id":"Home_Set_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"publishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"id":"Home_Fetch_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"publishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"id":"Home_Update_ProfileName","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"publishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"id":"Home_Update_ProfileStatus","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"publishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"id":"Home_Update_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"publishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"id":"Home_Remove_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"publishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"id":"Home_Fetch_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"publishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"id":"Home_Update_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64"}],"actionCollectionList":[{"unpublishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"publishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"id":"Home_Scripts","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e"}],"updatedResources":{"customJSLibList":[],"actionList":["Delete##ENTITY_SEPARATOR##Home","Scripts.verifyConfig##ENTITY_SEPARATOR##Home","Find_Chatwoot##ENTITY_SEPARATOR##Home","Logout##ENTITY_SEPARATOR##Home","Connect##ENTITY_SEPARATOR##Home","Fetch_Instance##ENTITY_SEPARATOR##Home","Set_Chatwoot##ENTITY_SEPARATOR##Home","Update_ProfileName##ENTITY_SEPARATOR##Home","Remove_ProfilePicture##ENTITY_SEPARATOR##Home","Create_Instance##ENTITY_SEPARATOR##Home","Fetch_PrivacySettings##ENTITY_SEPARATOR##Home","Restart##ENTITY_SEPARATOR##Home","Update_ProfileStatus##ENTITY_SEPARATOR##Home","Find_Webhook##ENTITY_SEPARATOR##Home","Update_ProfilePicture##ENTITY_SEPARATOR##Home","Find_Settings##ENTITY_SEPARATOR##Home","fetch_Instances##ENTITY_SEPARATOR##Home","Set_Settings##ENTITY_SEPARATOR##Home","Set_Webhook##ENTITY_SEPARATOR##Home","Update_PrivacySettings##ENTITY_SEPARATOR##Home"],"pageList":["Home"],"actionCollectionList":["Scripts##ENTITY_SEPARATOR##Home"]},"editModeTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false},"publishedTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false}} \ No newline at end of file +{"clientSchemaVersion":1.0,"serverSchemaVersion":6.0,"exportedApplication":{"name":"EvolutionAPI Public","isPublic":true,"pages":[{"id":"Home","isDefault":true}],"publishedPages":[{"id":"Home","isDefault":true}],"viewMode":false,"appIsExample":false,"unreadCommentThreads":0.0,"color":"#F5D1D1","icon":"smartphone","slug":"evolutionapi-public","unpublishedAppLayout":{"type":"DESKTOP"},"publishedAppLayout":{"type":"DESKTOP"},"unpublishedCustomJSLibs":[],"publishedCustomJSLibs":[],"evaluationVersion":2.0,"applicationVersion":2.0,"collapseInvisibleWidgets":true,"isManualUpdate":false,"deleted":false},"datasourceList":[],"customJSLibList":[],"pageList":[{"unpublishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":82.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":41.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":27.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Number Input","sourceData":1.0,"isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"publishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":82.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":41.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":27.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Number Input","sourceData":1.0,"isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56"}],"actionList":[{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_fetch_Instances","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788"},{"pluginType":"JS","pluginId":"js-plugin","unpublishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Scripts.verifyConfig","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Connect","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"publishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"id":"Home_Restart","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"publishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"id":"Home_Logout","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"publishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"id":"Home_Delete","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"publishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"id":"Home_Create_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"publishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"id":"Home_Find_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"publishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"id":"Home_Find_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"publishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"id":"Home_Find_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"publishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"id":"Home_Set_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"publishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"id":"Home_Set_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"publishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"id":"Home_Set_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"publishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"id":"Home_Fetch_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"publishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"id":"Home_Update_ProfileName","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"publishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"id":"Home_Update_ProfileStatus","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"publishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"id":"Home_Update_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"publishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"id":"Home_Remove_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"publishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"id":"Home_Fetch_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"publishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"id":"Home_Update_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"publishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"id":"Home_Find_Websocket","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafad875b7a111cf894430"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"publishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"id":"Home_Find_Rabbitmq","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafaf475b7a111cf894432"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"publishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"id":"Home_Set_Websocket","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafb0275b7a111cf894434"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"publishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"id":"Home_Set_Rabbitmq","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafb2175b7a111cf894436"}],"actionCollectionList":[{"unpublishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"publishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"id":"Home_Scripts","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e"}],"updatedResources":{"customJSLibList":[],"actionList":["Delete##ENTITY_SEPARATOR##Home","Find_Websocket##ENTITY_SEPARATOR##Home","Scripts.verifyConfig##ENTITY_SEPARATOR##Home","Find_Chatwoot##ENTITY_SEPARATOR##Home","Logout##ENTITY_SEPARATOR##Home","Connect##ENTITY_SEPARATOR##Home","Fetch_Instance##ENTITY_SEPARATOR##Home","Set_Chatwoot##ENTITY_SEPARATOR##Home","Update_ProfileName##ENTITY_SEPARATOR##Home","Set_Websocket##ENTITY_SEPARATOR##Home","Remove_ProfilePicture##ENTITY_SEPARATOR##Home","Create_Instance##ENTITY_SEPARATOR##Home","Fetch_PrivacySettings##ENTITY_SEPARATOR##Home","Restart##ENTITY_SEPARATOR##Home","Update_ProfileStatus##ENTITY_SEPARATOR##Home","Find_Webhook##ENTITY_SEPARATOR##Home","Update_ProfilePicture##ENTITY_SEPARATOR##Home","Find_Settings##ENTITY_SEPARATOR##Home","Set_Rabbitmq##ENTITY_SEPARATOR##Home","fetch_Instances##ENTITY_SEPARATOR##Home","Set_Settings##ENTITY_SEPARATOR##Home","Find_Rabbitmq##ENTITY_SEPARATOR##Home","Set_Webhook##ENTITY_SEPARATOR##Home","Update_PrivacySettings##ENTITY_SEPARATOR##Home"],"pageList":["Home"],"actionCollectionList":["Scripts##ENTITY_SEPARATOR##Home"]},"editModeTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false},"publishedTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false}} \ No newline at end of file From da568e4ea55c0fe9be8eb1cb13bfac3b25ec7ba7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 7 Aug 2023 19:46:34 -0300 Subject: [PATCH 132/177] feat: Added version in logs --- src/config/logger.config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index a5ca6a23..382772a3 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -1,6 +1,8 @@ import dayjs from 'dayjs'; +import fs from 'fs'; import { configService, Log } from './env.config'; +const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const formatDateLog = (timestamp: number) => dayjs(timestamp) @@ -73,6 +75,7 @@ export class Logger { console.log( /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], '[Evolution API]', + `v${packageJson.version}`, Command.BRIGHT + Color[type], process.pid.toString(), Command.RESET, From f32e259d2ff5cb67dd33f783d3e3bea4bf56c3e5 Mon Sep 17 00:00:00 2001 From: Helio Elias Date: Tue, 8 Aug 2023 21:06:58 -0300 Subject: [PATCH 133/177] Fix isURL function to by pass url with localhost, when webhook is enable --- src/install-evolution-api-ws.ts | 15 --------------- src/uninstall-evolution-api-ws.ts | 16 ---------------- src/whatsapp/services/whatsapp.service.ts | 2 +- 3 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 src/install-evolution-api-ws.ts delete mode 100644 src/uninstall-evolution-api-ws.ts diff --git a/src/install-evolution-api-ws.ts b/src/install-evolution-api-ws.ts deleted file mode 100644 index 1faadbf9..00000000 --- a/src/install-evolution-api-ws.ts +++ /dev/null @@ -1,15 +0,0 @@ -import nodeWindows from 'node-windows'; -import path from 'path'; - -const svc = new nodeWindows.Service({ - name: 'EvolutionAPIServer', - description: - 'WhatsApp-Api-NodeJs - This project is based on the CodeChat. The original project is an implementation of Baileys', - script: path.join(__dirname, 'main.js'), -}); - -svc.on('install', () => { - svc.start(); -}); - -svc.install(); diff --git a/src/uninstall-evolution-api-ws.ts b/src/uninstall-evolution-api-ws.ts deleted file mode 100644 index 4311f503..00000000 --- a/src/uninstall-evolution-api-ws.ts +++ /dev/null @@ -1,16 +0,0 @@ -import nodeWindows from 'node-windows'; -import path from 'path'; - -const svc = new nodeWindows.Service({ - name: 'EvolutionAPIServer', - description: - 'WhatsApp-Api-NodeJs - This project is based on the CodeChat. The original project is an implementation of Baileys', - script: path.join(__dirname, 'main.js'), -}); - -svc.on('uninstall', () => { - console.log('Uninstall complete.'); - console.log('The service exists: ', svc.exists); -}); - -svc.uninstall(); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6de7d847..dc82a516 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -453,7 +453,7 @@ export class WAStartupService { } try { - if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { + if (this.localWebhook.enabled && isURL(this.localWebhook.url, { require_tld: false })) { const httpService = axios.create({ baseURL }); const postData = { event, From 6e401eecdef2ae450f9713965fe5dc382c01446c Mon Sep 17 00:00:00 2001 From: Allyson de Paula Date: Wed, 9 Aug 2023 16:56:38 -0300 Subject: [PATCH 134/177] Bugfix Internal Error 500: fetchInstances (apikey not found) --- src/whatsapp/controllers/instance.controller.ts | 3 ++- src/whatsapp/services/monitor.service.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 2b62af23..900df29a 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -286,12 +286,13 @@ export class InstanceController { } public async fetchInstances({ instanceName }: InstanceDto) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); if (instanceName) { + this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); this.logger.verbose('instanceName: ' + instanceName); return this.waMonitor.instanceInfo(instanceName); } + this.logger.verbose('requested fetchInstances (all instances)'); return this.waMonitor.instanceInfo(); } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 50f671d9..9df6a0e3 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -115,7 +115,7 @@ export class WAMonitoringService { if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; instanceData.instance['chatwoot'] = chatwoot; } @@ -134,7 +134,7 @@ export class WAMonitoringService { if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; instanceData.instance['chatwoot'] = chatwoot; } From 07ad5756ebca66e0bfa621086dbd619f2f37633e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 9 Aug 2023 16:57:23 -0300 Subject: [PATCH 135/177] fix: Fixed issue that did not output base64 averages --- .DS_Store | Bin 6148 -> 6148 bytes CHANGELOG.md | 1 + src/config/logger.config.ts | 1 + src/whatsapp/services/whatsapp.service.ts | 8 ++++++++ 4 files changed, 10 insertions(+) diff --git a/.DS_Store b/.DS_Store index bc7339d20c06947ceac4918cf883130305e8fcad..9880dac3989431d51dbcb1b03b08b34ce3c75340 100644 GIT binary patch delta 82 zcmZoMXfc=|#>B`mF;Q%yo}wr#0|Nsi1A_nqLn=d2PP$=ma(-^X#Kh%{teabynprm% iR4{I4=iui6>ey_^{GE9+zlbFVP!C8G)8+t?EzAHI_7af* delta 197 zcmZoMXfc=|#>B)qu~2NHo+2kF0|Nsi1A_p=#F+J)4=}PY)`LV?7*ZHA8HyQ7a?%Zh zlk;;6fMN^`?8_yP<#O{~T#|C~lYn9zNerf+TV;+qqROY>l`qIZGMncCP%8r)gUe>T_YKu2!g$oQRkGQWr=2hfc`#K5pQKx7Lu0JxPZtpET3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1682dca9..8edec3a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Adjustment in the saving of contacts, saving the information of the number and Jid * Update Dockerfile * If you pass empty events in create instance and set webhook it is understood as all +* Fixed issue that did not output base64 averages ### Integrations diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index 382772a3..221ee098 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -75,6 +75,7 @@ export class Logger { console.log( /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type], '[Evolution API]', + Command.BRIGHT + Color[type], `v${packageJson.version}`, Command.BRIGHT + Color[type], process.pid.toString(), diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6d24b61d..9d76364a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2178,6 +2178,14 @@ export class WAStartupService { this.logger.verbose('File name: ' + mediaMessage.fileName); } + if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) { + mediaMessage.fileName = 'image.png'; + } + + if (mediaMessage.mediatype === 'video' && !mediaMessage.fileName) { + mediaMessage.fileName = 'video.mp4'; + } + let mimetype: string; if (isURL(mediaMessage.media)) { From c364d3fdcac21197897abce5ec539c0bf35fe99f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 11 Aug 2023 20:49:39 -0300 Subject: [PATCH 136/177] feat: Added Typebot integration --- Extras/typebot/typebot-example.json | 1 + src/whatsapp/services/typebot.service.ts | 1 + src/whatsapp/services/whatsapp.service.ts | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Extras/typebot/typebot-example.json diff --git a/Extras/typebot/typebot-example.json b/Extras/typebot/typebot-example.json new file mode 100644 index 00000000..93ababc4 --- /dev/null +++ b/Extras/typebot/typebot-example.json @@ -0,0 +1 @@ +{"id":"l27ft2bq9a7tke15i7m64d9o","version":"3","createdAt":"2023-08-04T17:27:18.072Z","updatedAt":"2023-08-11T21:38:15.669Z","icon":null,"name":"[Dgcode] [whatsapp] Pesquisa Satisfacao","folderId":"cll1fzkfy0008pa65kgz3tm86","groups":[{"id":"c76ucoughhenpernmadu7ibg","title":"Start","blocks":[{"id":"qn40kjwtw1he3l1bujt3bnje","type":"start","label":"Start","groupId":"c76ucoughhenpernmadu7ibg","outgoingEdgeId":"aovnigvk665gzhyzg7bxhvn0"}],"graphCoordinates":{"x":-126.43,"y":220.29}},{"id":"nog2woqmvhssnnjlcpwd41k5","title":"Apresentação","blocks":[{"id":"potdr8jwrn6mnkjipynqjmhh","type":"Set variable","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"type":"Random ID","variableId":"vsu5or5sxes9lyuhsgcl3cuyd"}},{"id":"jp1v0u6lucs72qn8h2y0krll","type":"Google Sheets","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"action":"Insert a row","sheetId":"0","cellsToInsert":[{"id":"e7h6q8pa9q9p2xv4owpfkwa4","value":"{{ID}}","column":"ID"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"mcpyoq8x28bnwp23g7h1dbc1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Olá! Bem-vindo(a) à nossa "},{"bold":true,"text":"pesquisa de satisfação"},{"text":"."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o0731ch0epj2vm2c5aoxyvw1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Meu nome é "},{"bold":true,"text":"🤖 Mike"},{"text":", estou aqui para ouvir sua opinião e experiência com nossos serviços."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"hgqbj5kmosz64cb435xqh0am","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é fundamental para nos ajudar a melhorar!"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"cbvgdo0jknjyzmvwe6o614ni","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Vamos começar?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"nmhkn4jod3evk08tbq5vw3s3","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual o seu nome?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o8ijci5gdfsp6fpv07kwh8br","type":"text input","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o seu nome"},"variableId":"vo40px5r6wg9vhs9fixd45kzn"}},{"id":"etbdi8paer56f82p6xc379um","type":"Google Sheets","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{name}}","column":"Nome"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"hqxrso204tkg5p71o96hduaz"}],"graphCoordinates":{"x":771.26,"y":213}},{"id":"j5co2kcotxafuxhzlj7u0qnn","title":"Qual seu email?","blocks":[{"id":"he1367t9ssao735kidd86mna","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, agora me informe seu endereço de email?"}]}]},"groupId":"j5co2kcotxafuxhzlj7u0qnn"},{"id":"qb8nwfs52g168tmnvp257b44","type":"email input","groupId":"j5co2kcotxafuxhzlj7u0qnn","options":{"labels":{"button":"Enviar","placeholder":"Digite o seu email"},"variableId":"vr75l1drc5uoxvisje0hio5ph","retryMessageContent":"Email incorreto!"}},{"id":"m0tqedan6l1j5jr6fb9wfdm7","type":"Google Sheets","groupId":"j5co2kcotxafuxhzlj7u0qnn","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{email}}","column":"Email"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"ghbmp8sjr88b30phgi89qkjl"}],"graphCoordinates":{"x":1236.92,"y":204.84}},{"id":"wtd0o382phaji7i7u2n8pody","title":"Pergunta 1","blocks":[{"id":"zr69lw3bcmmkgahqq8og7shw","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, qual é o seu nível de satisfação geral com os serviços que nossa empresa fornece?"}]}]},"groupId":"wtd0o382phaji7i7u2n8pody"},{"id":"ku0zpu43cbbnd7y0ai71ptde","type":"rating input","groupId":"wtd0o382phaji7i7u2n8pody","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vbfl3sqze2wzicn9l1n9ckjs4"}},{"id":"l2s8irgrtrxfwy97v2gclajy","type":"Google Sheets","groupId":"wtd0o382phaji7i7u2n8pody","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question1}}","column":"Pergunta 1"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"d2m2uo2gvnqzqw7m3hqp78zk"}],"graphCoordinates":{"x":1692.4,"y":194.19}},{"id":"ylerbfc1l2o62j68g8ghegxt","title":"Pergunta 2","blocks":[{"id":"l19jgtpln9al473dudr0gbzn","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, em que medida nossa empresa atendeu às suas expectativas em termos de qualidade do serviço prestado?"}]}]},"groupId":"ylerbfc1l2o62j68g8ghegxt"},{"id":"kfxuc6p58cdzy1xcyp4i4ra7","type":"rating input","groupId":"ylerbfc1l2o62j68g8ghegxt","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vkgl2bfdbyms1dyc1s6efx678"}},{"id":"v6vdddy19ncfhrkeettwr123","type":"Google Sheets","groupId":"ylerbfc1l2o62j68g8ghegxt","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question2}}","column":"Pergunta 2"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"oylxp0jgu571sjsgqevol5yi"}],"graphCoordinates":{"x":2156.14,"y":190.76}},{"id":"lbieknd0qp42pogsby5l82ww","title":"Pergunta 3","blocks":[{"id":"y43s12dnoxh772c9o3pmnhxf","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você teve alguma dificuldade em se comunicar com nossa equipe de suporte ao cliente?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"lbieknd0qp42pogsby5l82ww"},{"id":"fb6ckchqp8vx9ypig07we6q4","type":"text input","groupId":"lbieknd0qp42pogsby5l82ww","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"rj84ja6d3mgouspwhrkeadz7","type":"Google Sheets","groupId":"lbieknd0qp42pogsby5l82ww","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question3}}","column":"Pergunta 3"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"b538q1mt18l6oddo397nh1m4","type":"Condition","items":[{"id":"dwhc3ptqvktlgfvl17xg79s5","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"w6ao5pi6wt0966tobkned56m"},{"id":"cod3tkt16ry8ixm5u7rwxzm9","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"wlfmh2g3j5avj75sa9q6rsab"}],"groupId":"lbieknd0qp42pogsby5l82ww","outgoingEdgeId":"ehcwqdrkc4025pui2y1s9390"}],"graphCoordinates":{"x":2605.34,"y":189.93}},{"id":"qzhp25b9f2lvt4yeniqvjkav","title":"Pergunta 4","blocks":[{"id":"pos7njae2r35r29kcbyxtz2j","type":"text","content":{"richText":[{"type":"p","children":[{"text":"{{name}}, por favor, descreva o problema para que possamos melhorar."}]}]},"groupId":"qzhp25b9f2lvt4yeniqvjkav"},{"id":"ce2eodve0e4f2rubk4wv5jf1","type":"text input","groupId":"qzhp25b9f2lvt4yeniqvjkav","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Descreva o problema"},"variableId":"vd6fm2i9shcdjz8bhhwbsdh6t"}},{"id":"e75om4ccho8uob245t2wethw","type":"Google Sheets","groupId":"qzhp25b9f2lvt4yeniqvjkav","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question4}}","column":"Pergunta 4"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"fe7xrdj315gebr22f0eylupl"}],"graphCoordinates":{"x":3041.23,"y":187.11}},{"id":"c8kh8eee1m3wyy372v4n6m1i","title":"Pergunta 5","blocks":[{"id":"txqi87lwinpa0p5of0xmqxu6","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, como você avalia a capacidade da nossa empresa de cumprir os prazos acordados?"}]}]},"groupId":"c8kh8eee1m3wyy372v4n6m1i"},{"id":"mg2tmcmwnx3tap0hs4b7e0la","type":"rating input","groupId":"c8kh8eee1m3wyy372v4n6m1i","options":{"labels":{"button":"Enviar"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vz6lvahwo15dosvckdtkxduly"}},{"id":"cciytmy1bulw32j24ndbq39r","type":"Google Sheets","groupId":"c8kh8eee1m3wyy372v4n6m1i","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question5}}","column":"Pergunta 5"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"dlfg76etmcqs3sgxplnisbf1"}],"graphCoordinates":{"x":3501.8,"y":179.58}},{"id":"tn8bcyughy9dsxhmjngrosvj","title":"Pergunta 6","blocks":[{"id":"aema350m33n9dljopcsxn8q5","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você recomendaria nossos serviços para outras pessoas ou empresas?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"tn8bcyughy9dsxhmjngrosvj"},{"id":"wk4bkxbxcfu9skrzn8p8077u","type":"text input","groupId":"tn8bcyughy9dsxhmjngrosvj","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"uucahcq4zwadysop7n9ktbms","type":"Google Sheets","groupId":"tn8bcyughy9dsxhmjngrosvj","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question6}}","column":"Pergunta 6"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"n3j2dxaalkljl020o0o61ef9","type":"Condition","items":[{"id":"ifhm8cj8lsulhrarnfda2oal","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"yu9762ttf5jn3bmhd6uzrsv8"},{"id":"gxp6j3ouga4r0t8364tn8axs","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"ji1y2o1hldhemto0ymwou09c"}],"groupId":"tn8bcyughy9dsxhmjngrosvj","outgoingEdgeId":"d3u83fikqplfy9ntva3sm7eg"}],"graphCoordinates":{"x":3926.41,"y":186.15}},{"id":"nzkhdw3hdv550aepsxvk2a0u","title":"Pergunta 7","blocks":[{"id":"io90onrpfrokejgkps94r3dj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Que pena {{name}}, por gentileza, nos conte o motivo?"}]}]},"groupId":"nzkhdw3hdv550aepsxvk2a0u"},{"id":"dj7dbgyjqk0a5u3jn6kzykb2","type":"text input","groupId":"nzkhdw3hdv550aepsxvk2a0u","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o motivo"},"variableId":"vept0w6tr0w7eyyi52hgq1r3c"}},{"id":"i10wbfctp4dzroie3310rra0","type":"Google Sheets","groupId":"nzkhdw3hdv550aepsxvk2a0u","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question7}}","column":"Pergunta 7"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"vu3k1pxfilhmz59malpqvj1u"}],"graphCoordinates":{"x":4352.64,"y":194.04}},{"id":"jdz9w8vrz09vefk4wqrf0vwl","title":"Pergunta 8","blocks":[{"id":"hndzyb58fqxudykajr22skla","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Existe alguma sugestão que você gostaria de nos dar para melhorar nossos serviços?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},{"id":"ol9l8fdb3q65auykrn383q6d","type":"text input","groupId":"jdz9w8vrz09vefk4wqrf0vwl","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"qhxod01c7mdlfrxr5cy0xgoj","type":"Google Sheets","groupId":"jdz9w8vrz09vefk4wqrf0vwl","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question8}}","column":"Pergunta 8"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"zderh9hqjkpuz58p79szfa1i","type":"Condition","items":[{"id":"lur26nqa8dv7m4jmmljpyyf1","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"x2fzu1uuukp9cgmdzecp7mgk"},{"id":"aoj7e49zimwxng4o7bd6u00s","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"mb1fg83gijikrafud2ml6zbn"}],"groupId":"jdz9w8vrz09vefk4wqrf0vwl","outgoingEdgeId":"amyrx4i2rm3cjksym5zvwd50"}],"graphCoordinates":{"x":4768.69,"y":201.49}},{"id":"c4k1ftb4rbynkb01ulwuh4qh","title":"Pergunta 9","blocks":[{"id":"jqn5de3i29ygjyf6usbj117t","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual seria a sua sugestão?"}]}]},"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},{"id":"wfucksh3yaeq21l7mnlnsx75","type":"text input","groupId":"c4k1ftb4rbynkb01ulwuh4qh","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua sugestão"},"variableId":"vhygxyvhu5l6r2uws1cbthmxm"}},{"id":"kt1w6r6mucelx2odhnka5td1","type":"Google Sheets","groupId":"c4k1ftb4rbynkb01ulwuh4qh","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question9}}","column":"Pergunta 9"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"imbs12h9gb2dpmrb19yvx71u"}],"graphCoordinates":{"x":5233.77,"y":205.27}},{"id":"vvyooiddvdbon0t21bvzdr7q","title":"Finalização","blocks":[{"id":"efk089lhks1ev4khy38caner","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Então {{name}}, agradecemos muito por dedicar um tempo para nos fornecer seu feedback."}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"pvu3g8vpqdi3aecu2u0in2d0","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é muito importante para nós, e trabalharemos arduamente para melhorar ainda mais nossos serviços!"}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"wqe9r1ivjf0ikubqichufzsg","type":"Webhook","groupId":"vvyooiddvdbon0t21bvzdr7q","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[]},"webhookId":"i3g1959ev6fl9s61ir8hn1we"}],"graphCoordinates":{"x":7067.06,"y":231.55}},{"id":"ffm0s2y4head3auw808hwfnx","title":"Retorna Pergunta 3","blocks":[{"id":"ox70407atqtf1kwrszis4cix","type":"Set variable","groupId":"ffm0s2y4head3auw808hwfnx","options":{"type":"Empty","variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"bcwkrcxtsc8drzwynb2igu0g","type":"Jump","groupId":"ffm0s2y4head3auw808hwfnx","options":{"groupId":"lbieknd0qp42pogsby5l82ww"}}],"graphCoordinates":{"x":3031.03,"y":754.83}},{"id":"cf8r0wx0sgw6c9v79ebja1tj","title":"Retorna Pergunta 6","blocks":[{"id":"e02yfpbpj298m1q9y4tb905i","type":"Set variable","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"type":"Empty","variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"wjfe41oxiik0jgwcye7sczeu","type":"Jump","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"groupId":"tn8bcyughy9dsxhmjngrosvj"}}],"graphCoordinates":{"x":4360.16,"y":732.74}},{"id":"b7zfnwcxvu28s98ii03isdae","title":"Retorna Pergunta 8","blocks":[{"id":"j1xmpy60ggf162ej9a0rti4f","type":"Set variable","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"type":"Empty","variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"lk06yb9dvrctn2u9tx35n12c","type":"Jump","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"}}],"graphCoordinates":{"x":5213.21,"y":778}},{"id":"z0idhsnqisrd695z0j1tnqvw","title":"Retorna Pergunta 10","blocks":[{"id":"gs96ig682082mj4igcjjuh76","type":"Set variable","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"type":"Empty","variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"tihlp1xm8mvpdm3d0dqkwwx6","type":"Jump","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"}}],"graphCoordinates":{"x":6100.86,"y":819.65}},{"id":"qsrkmfsr04kayulair47gmn0","title":"Gera QRCODE pix","blocks":[{"id":"qs1uxqm8jqla9uui43ofms65","type":"Webhook","groupId":"qsrkmfsr04kayulair47gmn0","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[{"id":"gcia6kdba4yydt14klsg8h6x","bodyPath":"data.qrcode_base64","variableId":"vamn8ortov9nk1y04vczo375h"}]},"webhookId":"ajx8mv7trd50mbv2uj6fr3x5"},{"id":"sz447ty7t4vreto9bf07h52i","type":"Set variable","groupId":"qsrkmfsr04kayulair47gmn0","options":{"type":"Custom","variableId":"vamn8ortov9nk1y04vczo375h","expressionToEvaluate":"if({{remoteJid}}){\n return {{qrcode}}.replace('data:image/png;base64,', ''); \n}else{\n return {{qrcode}}\n}\n"}},{"id":"c3wp5ic2wx9emj6kkii42xpj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Aqui está qrcode para sua contribuição de R$ {{question11}}, caso tenha dificuldade na leitura utilize a nossa chave:"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"Telefone: 7499879409"}]},{"type":"p","children":[{"text":"Em nome de: Davidson Oliveira Gomes"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"jncggap4fivalzgntw3bfaom","type":"image","content":{"url":"{{qrcode}}"},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"chiz9utw18jvui4c2r0vsiqp","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito obrigado pela sua contribuição!"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0","outgoingEdgeId":"cwlt91vwhr7gvgx0qx2mnxtr"}],"graphCoordinates":{"x":6607.75,"y":229.53}},{"id":"cs5kjnrcsh4bjiuvwf99agho","title":"Pergunta 10","blocks":[{"id":"axpk3aoauusbiy8av70fc2fo","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Gostaria de fazer uma contribuição?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"cs5kjnrcsh4bjiuvwf99agho"},{"id":"q136n37ja1g5dyhdeisur4rg","type":"text input","groupId":"cs5kjnrcsh4bjiuvwf99agho","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua resposta"},"variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"m3sx9dam0ngbyni52l5b8b34","type":"Google Sheets","groupId":"cs5kjnrcsh4bjiuvwf99agho","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question10}}","column":"Pergunta 10"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"xza6e0p4hgkfz1wvwcjss48s","type":"Condition","items":[{"id":"m5mvt5ecw81eevl428n56aji","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"fe1wk4fc1xzt7mefasb2qzqz"},{"id":"bpcidulg0g7v8pwh3w9my880","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"xg1zkpvob8ilx2r8p0kv604d"}],"groupId":"cs5kjnrcsh4bjiuvwf99agho","outgoingEdgeId":"o746eh96sq2j7juionfql73t"}],"graphCoordinates":{"x":5708.94,"y":210.9}},{"id":"tq60r6azxrmn17b4y7mjovf5","title":"Pergunta 11","blocks":[{"id":"o5fspfge731wt6m781nzjsll","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, quanto você deseja contribuir?"}]}]},"groupId":"tq60r6azxrmn17b4y7mjovf5"},{"id":"khncvmg5fcjsmu8tlmf8in6m","type":"number input","groupId":"tq60r6azxrmn17b4y7mjovf5","options":{"max":5000,"min":1,"step":1,"labels":{"button":"Enviar","placeholder":"Digite um numero"},"variableId":"vhoqah2c0blbx92bfmd4gjnyx"}},{"id":"xcd54kvlpao5si54yuvle8y8","type":"Google Sheets","groupId":"tq60r6azxrmn17b4y7mjovf5","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question11}}","column":"Pergunta 11"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"t1r05l9c3n3n377bdt8adu2x"}],"graphCoordinates":{"x":6158.94,"y":224.91}},{"id":"h0svx6gyzgjsclr9hbpo04v6","title":"Configurações Iniciais","blocks":[{"id":"na4zglpatkg8ejqcap8lcv69","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vp1ask55v2r58ukom5lek5hej","expressionToEvaluate":"https://8338-2804-910-16a-ff01-bd73-9d18-5395-c820.ngrok-free.app"}},{"id":"t2bdxy8x8fsn29yijk02ti43","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vtsldvs2u8ui93tktazy77djw","expressionToEvaluate":"8EAA51D7-F658-409D-9C9C-0A68DDC783DD1"}},{"id":"rt5h0lk6jaoh5hzag0s5hidd","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vkg1qlinovziltaloqhso2cw7","expressionToEvaluate":"https://pix.dgcode.com.br"}},{"id":"mh758b8y8288t56s6wz73mht","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vpjyy2e2ha6mu5x10q0nowuz3","expressionToEvaluate":"Davidson Oliveira Gomes"}},{"id":"ri9kv80djsej7r51m8xfjhuk","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vicsm3nkvhssvfhgss2xce2ad","expressionToEvaluate":"Telefone"}},{"id":"ye4teva02mnxph0rvfszdnsn","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vlmflx32cjlz457h0uzdi706g","expressionToEvaluate":"74999879409"}},{"id":"hfz4hqzfe6wgje96ezb5kann","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"veesfw943copg17w2qzdln9be","expressionToEvaluate":"Irece"}},{"id":"nd3yk369k7j73kws6exos0jw","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vavwvk4wgst506zdioplg4u8p","expressionToEvaluate":"TypeBot"},"outgoingEdgeId":"mb90csrzzep8qz2opcxmw736"}],"graphCoordinates":{"x":312.08,"y":218.28}}],"variables":[{"id":"vo40px5r6wg9vhs9fixd45kzn","name":"name"},{"id":"vr75l1drc5uoxvisje0hio5ph","name":"email"},{"id":"vzhsu0uc4suqoz38kv3q891ma","name":"question3"},{"id":"vbfl3sqze2wzicn9l1n9ckjs4","name":"question1"},{"id":"vkgl2bfdbyms1dyc1s6efx678","name":"question2"},{"id":"vd6fm2i9shcdjz8bhhwbsdh6t","name":"question4"},{"id":"vz6lvahwo15dosvckdtkxduly","name":"question5"},{"id":"vndjnalmnb3ez9beeon5tzrgq","name":"question6"},{"id":"vept0w6tr0w7eyyi52hgq1r3c","name":"question7"},{"id":"vy5it60mewmth7mayzhlgmzf0","name":"question8"},{"id":"vhygxyvhu5l6r2uws1cbthmxm","name":"question9"},{"id":"vrdwfo2lpoei2fzlzazh4pp61","name":"pushName"},{"id":"vz1uq7t77aivpi5crwy6ifact","name":"remoteJid"},{"id":"vsu5or5sxes9lyuhsgcl3cuyd","name":"ID"},{"id":"vamn8ortov9nk1y04vczo375h","name":"qrcode"},{"id":"vx6p4ivk4mnssvbhl30c5zng9","name":"question10"},{"id":"vhoqah2c0blbx92bfmd4gjnyx","name":"question11"},{"id":"vpjyy2e2ha6mu5x10q0nowuz3","name":"me"},{"id":"vicsm3nkvhssvfhgss2xce2ad","name":"typePIX"},{"id":"vavwvk4wgst506zdioplg4u8p","name":"reference"},{"id":"vlmflx32cjlz457h0uzdi706g","name":"keyPIX"},{"id":"vkg1qlinovziltaloqhso2cw7","name":"apiURL"},{"id":"veesfw943copg17w2qzdln9be","name":"city"},{"id":"vp1ask55v2r58ukom5lek5hej","name":"evolutionURL"},{"id":"vtsldvs2u8ui93tktazy77djw","name":"evolutionToken"}],"edges":[{"id":"w6ao5pi6wt0966tobkned56m","to":{"groupId":"qzhp25b9f2lvt4yeniqvjkav"},"from":{"itemId":"dwhc3ptqvktlgfvl17xg79s5","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"wlfmh2g3j5avj75sa9q6rsab","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"itemId":"cod3tkt16ry8ixm5u7rwxzm9","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"yu9762ttf5jn3bmhd6uzrsv8","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"itemId":"ifhm8cj8lsulhrarnfda2oal","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ji1y2o1hldhemto0ymwou09c","to":{"groupId":"nzkhdw3hdv550aepsxvk2a0u"},"from":{"itemId":"gxp6j3ouga4r0t8364tn8axs","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"x2fzu1uuukp9cgmdzecp7mgk","to":{"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},"from":{"itemId":"lur26nqa8dv7m4jmmljpyyf1","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"d3u83fikqplfy9ntva3sm7eg","to":{"groupId":"cf8r0wx0sgw6c9v79ebja1tj"},"from":{"blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ehcwqdrkc4025pui2y1s9390","to":{"groupId":"ffm0s2y4head3auw808hwfnx"},"from":{"blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"hqxrso204tkg5p71o96hduaz","to":{"groupId":"j5co2kcotxafuxhzlj7u0qnn"},"from":{"blockId":"etbdi8paer56f82p6xc379um","groupId":"nog2woqmvhssnnjlcpwd41k5"}},{"id":"ghbmp8sjr88b30phgi89qkjl","to":{"groupId":"wtd0o382phaji7i7u2n8pody"},"from":{"blockId":"m0tqedan6l1j5jr6fb9wfdm7","groupId":"j5co2kcotxafuxhzlj7u0qnn"}},{"id":"d2m2uo2gvnqzqw7m3hqp78zk","to":{"groupId":"ylerbfc1l2o62j68g8ghegxt"},"from":{"blockId":"l2s8irgrtrxfwy97v2gclajy","groupId":"wtd0o382phaji7i7u2n8pody"}},{"id":"oylxp0jgu571sjsgqevol5yi","to":{"groupId":"lbieknd0qp42pogsby5l82ww"},"from":{"blockId":"v6vdddy19ncfhrkeettwr123","groupId":"ylerbfc1l2o62j68g8ghegxt"}},{"id":"fe7xrdj315gebr22f0eylupl","to":{"groupId":"c8kh8eee1m3wyy372v4n6m1i"},"from":{"blockId":"e75om4ccho8uob245t2wethw","groupId":"qzhp25b9f2lvt4yeniqvjkav"}},{"id":"dlfg76etmcqs3sgxplnisbf1","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"blockId":"cciytmy1bulw32j24ndbq39r","groupId":"c8kh8eee1m3wyy372v4n6m1i"}},{"id":"vu3k1pxfilhmz59malpqvj1u","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"blockId":"i10wbfctp4dzroie3310rra0","groupId":"nzkhdw3hdv550aepsxvk2a0u"}},{"id":"imbs12h9gb2dpmrb19yvx71u","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"blockId":"kt1w6r6mucelx2odhnka5td1","groupId":"c4k1ftb4rbynkb01ulwuh4qh"}},{"id":"mb1fg83gijikrafud2ml6zbn","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"itemId":"aoj7e49zimwxng4o7bd6u00s","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"amyrx4i2rm3cjksym5zvwd50","to":{"groupId":"b7zfnwcxvu28s98ii03isdae"},"from":{"blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"o746eh96sq2j7juionfql73t","to":{"groupId":"z0idhsnqisrd695z0j1tnqvw"},"from":{"blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"fe1wk4fc1xzt7mefasb2qzqz","to":{"groupId":"tq60r6azxrmn17b4y7mjovf5"},"from":{"itemId":"m5mvt5ecw81eevl428n56aji","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"xg1zkpvob8ilx2r8p0kv604d","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"itemId":"bpcidulg0g7v8pwh3w9my880","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"t1r05l9c3n3n377bdt8adu2x","to":{"groupId":"qsrkmfsr04kayulair47gmn0"},"from":{"blockId":"xcd54kvlpao5si54yuvle8y8","groupId":"tq60r6azxrmn17b4y7mjovf5"}},{"id":"cwlt91vwhr7gvgx0qx2mnxtr","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"blockId":"chiz9utw18jvui4c2r0vsiqp","groupId":"qsrkmfsr04kayulair47gmn0"}},{"id":"aovnigvk665gzhyzg7bxhvn0","to":{"groupId":"h0svx6gyzgjsclr9hbpo04v6"},"from":{"blockId":"qn40kjwtw1he3l1bujt3bnje","groupId":"c76ucoughhenpernmadu7ibg"}},{"id":"mb90csrzzep8qz2opcxmw736","to":{"groupId":"nog2woqmvhssnnjlcpwd41k5"},"from":{"blockId":"nd3yk369k7j73kws6exos0jw","groupId":"h0svx6gyzgjsclr9hbpo04v6"}}],"theme":{"chat":{"inputs":{"color":"#ffffff","backgroundColor":"#1e293b","placeholderColor":"#9095A0"},"buttons":{"color":"#ffffff","backgroundColor":"#1a5fff"},"roundness":"large","hostAvatar":{"isEnabled":true},"guestAvatar":{"isEnabled":false},"hostBubbles":{"color":"#ffffff","backgroundColor":"#1e293b"},"guestBubbles":{"color":"#FFFFFF","backgroundColor":"#FF8E21"}},"general":{"font":"Open Sans","background":{"type":"Color","content":"#171923"}}},"selectedThemeTemplateId":"typebot-dark","settings":{"general":{"isBrandingEnabled":false},"metadata":{"imageUrl":"https://i.imgur.com/48TjKBb.jpg","description":"Sua opinião é fundamental para nos ajudar a melhorar!"},"typingEmulation":{"speed":300,"enabled":true,"maxDelay":1.5}},"publicId":"dgcode-pesquisa-satisfacao-whatsapp-7m64d9o","customDomain":null,"workspaceId":"clktt8c1y0001qa66zyg5tt23","resultsTablePreferences":null,"isArchived":false,"isClosed":false} \ No newline at end of file diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 22cdd9b8..ce307509 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -129,6 +129,7 @@ export class TypebotService { prefilledVariables: { remoteJid: data.remoteJid, pushName: data.pushName, + instanceName: instance.instanceName, }, }, }; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 9d76364a..1534a346 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1359,7 +1359,7 @@ export class WAStartupService { ); } - if (this.localTypebot.enabled) { + if (this.localTypebot.enabled && messageRaw.key.remoteJid.includes('@s.whatsapp.net')) { await this.typebotService.sendTypebot( { instanceName: this.instance.name }, messageRaw.key.remoteJid, From 907a0ee1354247bbaa8eff3a4b682dabd0bc6b24 Mon Sep 17 00:00:00 2001 From: Allyson de Paula Date: Sat, 12 Aug 2023 15:05:10 -0300 Subject: [PATCH 137/177] Proxy test --- package.json | 1 + src/whatsapp/services/whatsapp.service.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/package.json b/package.json index 54511a9c..384db0fd 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "qrcode-terminal": "^0.12.0", "redis": "^4.6.5", "sharp": "^0.30.7", + "socks-proxy-agent": "^8.0.1", "uuid": "^9.0.0" }, "devDependencies": { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6de7d847..8d439d45 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -121,6 +121,7 @@ import { RepositoryBroker } from '../repository/repository.manager'; import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; import { waMonitor } from '../whatsapp.module'; import { ChatwootService } from './chatwoot.service'; +import { SocksProxyAgent } from 'socks-proxy-agent'; export class WAStartupService { constructor( @@ -874,6 +875,7 @@ export class WAStartupService { return message; }, + // agent: new SocksProxyAgent('socks5://192.168.1.4:1080'), }; this.endSession = false; From 3a14fc373afd034b640005d6ac6de2883e1f86c0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 17 Aug 2023 18:19:46 -0300 Subject: [PATCH 138/177] adjust params rabbitmq --- src/whatsapp/services/whatsapp.service.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1534a346..0a951add 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -599,11 +599,23 @@ export class WAStartupService { if (Array.isArray(rabbitmqLocal) && rabbitmqLocal.includes(we)) { const exchangeName = 'evolution_exchange'; - amqp.assertExchange(exchangeName, 'topic', { durable: false }); + amqp.assertExchange(exchangeName, 'topic', { + durable: true, + 'auto-delete': false, + arguments: { + 'x-queue-type': 'quorum', + }, + }); const queueName = `${this.instanceName}.${event}`; - amqp.assertQueue(queueName, { durable: false }); + amqp.assertQueue(queueName, { + durable: true, + 'auto-delete': false, + arguments: { + 'x-queue-type': 'quorum', + }, + }); amqp.bindQueue(queueName, exchangeName, event); @@ -666,6 +678,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + sender: this.wuid, server_url: serverUrl, apikey: (expose && instanceApikey) || null, }; @@ -685,6 +698,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + sender: this.wuid, server_url: serverUrl, }; @@ -734,6 +748,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + sender: this.wuid, server_url: serverUrl, }; @@ -752,6 +767,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + sender: this.wuid, server_url: serverUrl, }; From deb07d2b7fda739a592090a1dba9e50fb04f9406 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 08:44:13 -0300 Subject: [PATCH 139/177] Messages sent by the api now arrive in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8edec3a0..ea364cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * Update Dockerfile * If you pass empty events in create instance and set webhook it is understood as all * Fixed issue that did not output base64 averages +* Messages sent by the api now arrive in chatwoot ### Integrations diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 0a951add..f2fad12c 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -678,6 +678,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + ISODatetime: new Date().toISOString(), sender: this.wuid, server_url: serverUrl, apikey: (expose && instanceApikey) || null, @@ -1991,13 +1992,9 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - // if (this.localChatwoot.enabled) { - // this.chatwootService.eventWhatsapp( - // Events.SEND_MESSAGE, - // { instanceName: this.instance.name }, - // messageRaw, - // ); - // } + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp(Events.SEND_MESSAGE, { instanceName: this.instance.name }, messageRaw); + } this.logger.verbose('Inserting message in database'); await this.repository.message.insert( From 680c92ecec2d1e3785694ba71595754d9e9d3870 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 09:25:34 -0300 Subject: [PATCH 140/177] Messages sent by the api now arrive in chatwoot --- src/whatsapp/services/whatsapp.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index f2fad12c..b71d8762 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -611,9 +611,9 @@ export class WAStartupService { amqp.assertQueue(queueName, { durable: true, - 'auto-delete': false, + autoDelete: false, arguments: { - 'x-queue-type': 'quorum', + queueType: 'quorum', }, }); From c4d41134b866cd3b0ed921963a7d83b652c0a2b0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 09:33:17 -0300 Subject: [PATCH 141/177] Messages sent by the api now arrive in chatwoot --- src/libs/amqp.server.ts | 8 +++++++- src/whatsapp/services/whatsapp.service.ts | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 86819c80..6f4af528 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -24,7 +24,13 @@ export const initAMQP = () => { const exchangeName = 'evolution_exchange'; - channel.assertExchange(exchangeName, 'topic', { durable: false }); + channel.assertExchange(exchangeName, 'topic', { + durable: true, + autoDelete: false, + arguments: { + queueType: 'quorum', + }, + }); amqpChannel = channel; logger.info('AMQP initialized'); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index b71d8762..597af126 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -601,9 +601,9 @@ export class WAStartupService { amqp.assertExchange(exchangeName, 'topic', { durable: true, - 'auto-delete': false, + autoDelete: false, arguments: { - 'x-queue-type': 'quorum', + queueType: 'quorum', }, }); From 201e6f7e7bb20e41c6080322425a866d9241828d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 10:38:32 -0300 Subject: [PATCH 142/177] Added rabbitmq to send events --- src/libs/amqp.server.ts | 4 +--- src/whatsapp/services/whatsapp.service.ts | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 6f4af528..cc0f13b5 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -27,10 +27,8 @@ export const initAMQP = () => { channel.assertExchange(exchangeName, 'topic', { durable: true, autoDelete: false, - arguments: { - queueType: 'quorum', - }, }); + amqpChannel = channel; logger.info('AMQP initialized'); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 597af126..49f51c44 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -597,14 +597,11 @@ export class WAStartupService { if (amqp) { if (Array.isArray(rabbitmqLocal) && rabbitmqLocal.includes(we)) { - const exchangeName = 'evolution_exchange'; + const exchangeName = this.instanceName ?? 'evolution_exchange'; amqp.assertExchange(exchangeName, 'topic', { durable: true, autoDelete: false, - arguments: { - queueType: 'quorum', - }, }); const queueName = `${this.instanceName}.${event}`; @@ -613,7 +610,7 @@ export class WAStartupService { durable: true, autoDelete: false, arguments: { - queueType: 'quorum', + 'x-queue-type': 'quorum', }, }); From 6f99784224650a7d7eb5d4af33da000803553ef3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 11:38:50 -0300 Subject: [PATCH 143/177] Added Typebot integration --- src/main.ts | 4 +- src/whatsapp/services/typebot.service.ts | 48 ++++++++++++++++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main.ts b/src/main.ts index adc868af..75dd95b3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,7 +27,9 @@ function bootstrap() { cors({ origin(requestOrigin, callback) { const { ORIGIN } = configService.get('CORS'); - !requestOrigin ? (requestOrigin = '*') : undefined; + if (ORIGIN.includes('*')) { + return callback(null, true); + } if (ORIGIN.indexOf(requestOrigin) !== -1) { return callback(null, true); } diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index ce307509..78cbdb1f 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -1,3 +1,4 @@ +import { delay } from '@whiskeysockets/baileys'; import axios from 'axios'; import { Logger } from '../../config/logger.config'; @@ -162,13 +163,34 @@ export class TypebotService { return request.data; } - public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], input: any[]) { - processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input).catch((err) => { - console.error('Erro ao processar mensagens:', err); - }); + public async sendWAMessage( + instance: InstanceDto, + remoteJid: string, + messages: any[], + input: any[], + clientSideActions: any[], + ) { + processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input, clientSideActions).catch( + (err) => { + console.error('Erro ao processar mensagens:', err); + }, + ); - async function processMessages(instance, messages, input) { + function findItemAndGetSecondsToWait(array, targetId) { + if (!array) return null; + + for (const item of array) { + if (item.lastBubbleBlockId === targetId) { + return item.wait?.secondsToWaitFor; + } + } + return null; + } + + async function processMessages(instance, messages, input, clientSideActions) { for (const message of messages) { + const wait = findItemAndGetSecondsToWait(clientSideActions, message.id); + if (message.type === 'text') { let formattedText = ''; @@ -260,6 +282,10 @@ export class TypebotService { }, }); } + + if (wait) { + await delay(wait * 1000); + } } if (input) { @@ -323,7 +349,7 @@ export class TypebotService { pushName: msg.pushName, }); - await this.sendWAMessage(instance, remoteJid, data.messages, data.input); + await this.sendWAMessage(instance, remoteJid, data.messages, data.input, data.clientSideActions); return; } @@ -346,7 +372,7 @@ export class TypebotService { pushName: msg.pushName, }); - await this.sendWAMessage(instance, remoteJid, data.messages, data.input); + await this.sendWAMessage(instance, remoteJid, data.messages, data.input, data.clientSideActions); return; } @@ -414,7 +440,13 @@ export class TypebotService { const request = await axios.post(url + '/api/v1/sendMessage', reqData); - await this.sendWAMessage(instance, remoteJid, request.data.messages, request.data.input); + await this.sendWAMessage( + instance, + remoteJid, + request.data.messages, + request.data.input, + request.data.clientSideActions, + ); return; } From 31325d09993f5af4db33bf34e52f1090fd1d91cd Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 11:58:41 -0300 Subject: [PATCH 144/177] Added Typebot integration --- src/whatsapp/services/typebot.service.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 78cbdb1f..1179cad1 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -1,4 +1,3 @@ -import { delay } from '@whiskeysockets/baileys'; import axios from 'axios'; import { Logger } from '../../config/logger.config'; @@ -231,7 +230,8 @@ export class TypebotService { await instance.textMessage({ number: remoteJid.split('@')[0], options: { - delay: instance.localTypebot.delay_message || 1000, + // delay: instance.localTypebot.delay_message || 1000, + delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', linkPreview: linkPreview, }, @@ -245,7 +245,8 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: instance.localTypebot.delay_message || 1000, + // delay: instance.localTypebot.delay_message || 1000, + delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -259,7 +260,8 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: instance.localTypebot.delay_message || 1000, + // delay: instance.localTypebot.delay_message || 1000, + delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -273,7 +275,8 @@ export class TypebotService { await instance.audioWhatsapp({ number: remoteJid.split('@')[0], options: { - delay: instance.localTypebot.delay_message || 1000, + // delay: instance.localTypebot.delay_message || 1000, + delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'recording', encoding: true, }, @@ -282,10 +285,6 @@ export class TypebotService { }, }); } - - if (wait) { - await delay(wait * 1000); - } } if (input) { From 0d16a7aab0fa4d9cf07cf435d0de14445f0dea5f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 11:59:04 -0300 Subject: [PATCH 145/177] Added Typebot integration --- src/whatsapp/services/typebot.service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 1179cad1..43178c34 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -230,7 +230,6 @@ export class TypebotService { await instance.textMessage({ number: remoteJid.split('@')[0], options: { - // delay: instance.localTypebot.delay_message || 1000, delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', linkPreview: linkPreview, @@ -245,7 +244,6 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - // delay: instance.localTypebot.delay_message || 1000, delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', }, @@ -260,7 +258,6 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - // delay: instance.localTypebot.delay_message || 1000, delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'composing', }, @@ -275,7 +272,6 @@ export class TypebotService { await instance.audioWhatsapp({ number: remoteJid.split('@')[0], options: { - // delay: instance.localTypebot.delay_message || 1000, delay: wait ? wait * 1000 : instance.localTypebot.delay_message || 1000, presence: 'recording', encoding: true, From dd2caf720cedf28965aa0ee468c821e6516314c2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 12:24:05 -0300 Subject: [PATCH 146/177] Added Typebot integration --- src/validate/validate.schema.ts | 12 ++++++ .../controllers/typebot.controller.ts | 5 +++ src/whatsapp/routers/typebot.router.ts | 25 ++++++++++- src/whatsapp/services/typebot.service.ts | 42 +++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 81a61127..bce05660 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -1001,6 +1001,18 @@ export const typebotStatusSchema: JSONSchema7 = { ...isNotEmpty('remoteJid', 'status'), }; +export const typebotStartSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + remoteJid: { type: 'string' }, + url: { type: 'string' }, + typebot: { type: 'string' }, + }, + required: ['remoteJid', 'url', 'typebot'], + ...isNotEmpty('remoteJid', 'url', 'typebot'), +}; + export const proxySchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/typebot.controller.ts b/src/whatsapp/controllers/typebot.controller.ts index 0cda7d57..53dc967f 100644 --- a/src/whatsapp/controllers/typebot.controller.ts +++ b/src/whatsapp/controllers/typebot.controller.ts @@ -38,4 +38,9 @@ export class TypebotController { logger.verbose('requested changeStatus from ' + instance.instanceName + ' instance'); return this.typebotService.changeStatus(instance, data); } + + public async startTypebot(instance: InstanceDto, data: any) { + logger.verbose('requested startTypebot from ' + instance.instanceName + ' instance'); + return this.typebotService.startTypebot(instance, data); + } } diff --git a/src/whatsapp/routers/typebot.router.ts b/src/whatsapp/routers/typebot.router.ts index 68bb6395..0f785de3 100644 --- a/src/whatsapp/routers/typebot.router.ts +++ b/src/whatsapp/routers/typebot.router.ts @@ -1,7 +1,12 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; -import { instanceNameSchema, typebotSchema, typebotStatusSchema } from '../../validate/validate.schema'; +import { + instanceNameSchema, + typebotSchema, + typebotStartSchema, + typebotStatusSchema, +} from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { TypebotDto } from '../dto/typebot.dto'; @@ -47,7 +52,7 @@ export class TypebotRouter extends RouterBroker { res.status(HttpStatus.OK).json(response); }) .post(this.routerPath('changeStatus'), ...guards, async (req, res) => { - logger.verbose('request received in findTypebot'); + logger.verbose('request received in changeStatusTypebot'); logger.verbose('request body: '); logger.verbose(req.body); @@ -60,6 +65,22 @@ export class TypebotRouter extends RouterBroker { execute: (instance, data) => typebotController.changeStatus(instance, data), }); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('start'), ...guards, async (req, res) => { + logger.verbose('request received in startTypebot'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: typebotStartSchema, + ClassRef: InstanceDto, + execute: (instance, data) => typebotController.startTypebot(instance, data), + }); + res.status(HttpStatus.OK).json(response); }); } diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 43178c34..1128bb0d 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -84,6 +84,48 @@ export class TypebotService { return { typebot: { ...instance, typebot: typebotData } }; } + public async startTypebot(instance: InstanceDto, data: any) { + const remoteJid = data.remoteJid; + const url = data.url; + const typebot = data.typebot; + + const id = Math.floor(Math.random() * 10000000000).toString(); + + const reqData = { + sessionId: id, + startParams: { + typebot: data.typebot, + prefilledVariables: { + remoteJid: data.remoteJid, + pushName: data.pushName, + instanceName: instance.instanceName, + }, + }, + }; + console.log(reqData); + + const request = await axios.post(data.url + '/api/v1/sendMessage', reqData); + + await this.sendWAMessage( + instance, + remoteJid, + request.data.messages, + request.data.input, + request.data.clientSideActions, + ); + + return { + typebot: { + ...instance, + typebot: { + url: url, + remoteJid: remoteJid, + typebot: typebot, + }, + }, + }; + } + private getTypeMessage(msg: any) { this.logger.verbose('get type message'); From 04b9a070c43a5974e84d7aee50c01f1bc7083c99 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 12:46:46 -0300 Subject: [PATCH 147/177] Added send and date_time in webhook data --- src/whatsapp/services/whatsapp.service.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 49f51c44..d11946ee 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -587,6 +587,9 @@ export class WAStartupService { const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); + const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds + const localISOTime = new Date(Date.now() - tzoffset).toISOString(); + const now = localISOTime; const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); @@ -621,6 +624,8 @@ export class WAStartupService { instance: this.instance.name, data, server_url: serverUrl, + date_time: now, + sender: this.wuid, }; if (expose && instanceApikey) { @@ -643,6 +648,8 @@ export class WAStartupService { instance: this.instance.name, data, server_url: serverUrl, + date_time: now, + sender: this.wuid, }; if (expose && instanceApikey) { @@ -675,7 +682,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, - ISODatetime: new Date().toISOString(), + date_time: now, sender: this.wuid, server_url: serverUrl, apikey: (expose && instanceApikey) || null, @@ -696,6 +703,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + date_time: now, sender: this.wuid, server_url: serverUrl, }; @@ -746,6 +754,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + date_time: now, sender: this.wuid, server_url: serverUrl, }; @@ -765,6 +774,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + date_time: now, sender: this.wuid, server_url: serverUrl, }; From 5c247e3d2c56493f68f1a8eaaa39af7a6774b6d7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 12:46:47 -0300 Subject: [PATCH 148/177] Added send and date_time in webhook data --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea364cfb..d9f2d6f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Added rabbitmq to send events * Added Typebot integration * Added proxy endpoint +* Added send and date_time in webhook data ### Fixed From deb8f2a0b70f6fedf3559f46b2281d84355af02f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 18 Aug 2023 12:48:30 -0300 Subject: [PATCH 149/177] Added send and date_time in webhook data --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9f2d6f5..059dd781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.5.0 (homolog) +# 1.5.0 (2023-08-18 12:47) ### Feature From a2cd57d9c66bcd706cfcb3f8a465829dad7afd52 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 19 Aug 2023 10:42:41 -0300 Subject: [PATCH 150/177] feat: Inegration with Chama AI --- src/main.ts | 2 + src/validate/validate.schema.ts | 14 ++ .../controllers/chamaai.controller.ts | 29 +++ src/whatsapp/dto/chamaai.dto.ts | 7 + src/whatsapp/models/chamaai.model.ts | 24 +++ src/whatsapp/models/index.ts | 1 + src/whatsapp/repository/chamaai.repository.ts | 62 ++++++ src/whatsapp/repository/repository.manager.ts | 7 + src/whatsapp/routers/chamaai.router.ts | 52 +++++ src/whatsapp/routers/index.router.ts | 4 +- src/whatsapp/services/chamaai.service.ts | 196 ++++++++++++++++++ src/whatsapp/services/whatsapp.service.ts | 65 +++++- src/whatsapp/types/wa.types.ts | 8 + src/whatsapp/whatsapp.module.ts | 10 + 14 files changed, 477 insertions(+), 4 deletions(-) create mode 100644 src/whatsapp/controllers/chamaai.controller.ts create mode 100644 src/whatsapp/dto/chamaai.dto.ts create mode 100644 src/whatsapp/models/chamaai.model.ts create mode 100644 src/whatsapp/repository/chamaai.repository.ts create mode 100644 src/whatsapp/routers/chamaai.router.ts create mode 100644 src/whatsapp/services/chamaai.service.ts diff --git a/src/main.ts b/src/main.ts index 75dd95b3..2095bd4c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -47,6 +47,8 @@ function bootstrap() { app.set('views', join(ROOT_DIR, 'views')); app.use(express.static(join(ROOT_DIR, 'public'))); + app.use('/store', express.static(join(ROOT_DIR, 'store'))); + app.use('/', router); app.use( diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index bce05660..ebfed66a 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -1023,3 +1023,17 @@ export const proxySchema: JSONSchema7 = { required: ['enabled', 'proxy'], ...isNotEmpty('enabled', 'proxy'), }; + +export const chamaaiSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + enabled: { type: 'boolean', enum: [true, false] }, + url: { type: 'string' }, + token: { type: 'string' }, + waNumber: { type: 'string' }, + answerByAudio: { type: 'boolean', enum: [true, false] }, + }, + required: ['enabled', 'url', 'token', 'waNumber', 'answerByAudio'], + ...isNotEmpty('enabled', 'url', 'token', 'waNumber', 'answerByAudio'), +}; diff --git a/src/whatsapp/controllers/chamaai.controller.ts b/src/whatsapp/controllers/chamaai.controller.ts new file mode 100644 index 00000000..e9cafb50 --- /dev/null +++ b/src/whatsapp/controllers/chamaai.controller.ts @@ -0,0 +1,29 @@ +import { Logger } from '../../config/logger.config'; +import { ChamaaiDto } from '../dto/chamaai.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChamaaiService } from '../services/chamaai.service'; + +const logger = new Logger('ChamaaiController'); + +export class ChamaaiController { + constructor(private readonly chamaaiService: ChamaaiService) {} + + public async createChamaai(instance: InstanceDto, data: ChamaaiDto) { + logger.verbose('requested createChamaai from ' + instance.instanceName + ' instance'); + + if (!data.enabled) { + logger.verbose('chamaai disabled'); + data.url = ''; + data.token = ''; + data.waNumber = ''; + data.answerByAudio = false; + } + + return this.chamaaiService.create(instance, data); + } + + public async findChamaai(instance: InstanceDto) { + logger.verbose('requested findChamaai from ' + instance.instanceName + ' instance'); + return this.chamaaiService.find(instance); + } +} diff --git a/src/whatsapp/dto/chamaai.dto.ts b/src/whatsapp/dto/chamaai.dto.ts new file mode 100644 index 00000000..2c71a07d --- /dev/null +++ b/src/whatsapp/dto/chamaai.dto.ts @@ -0,0 +1,7 @@ +export class ChamaaiDto { + enabled: boolean; + url: string; + token: string; + waNumber: string; + answerByAudio: boolean; +} diff --git a/src/whatsapp/models/chamaai.model.ts b/src/whatsapp/models/chamaai.model.ts new file mode 100644 index 00000000..d3d10aff --- /dev/null +++ b/src/whatsapp/models/chamaai.model.ts @@ -0,0 +1,24 @@ +import { Schema } from 'mongoose'; + +import { dbserver } from '../../libs/db.connect'; + +export class ChamaaiRaw { + _id?: string; + enabled?: boolean; + url?: string; + token?: string; + waNumber?: string; + answerByAudio?: boolean; +} + +const chamaaiSchema = new Schema({ + _id: { type: String, _id: true }, + enabled: { type: Boolean, required: true }, + url: { type: String, required: true }, + token: { type: String, required: true }, + waNumber: { type: String, required: true }, + answerByAudio: { type: Boolean, required: true }, +}); + +export const ChamaaiModel = dbserver?.model(ChamaaiRaw.name, chamaaiSchema, 'chamaai'); +export type IChamaaiModel = typeof ChamaaiModel; diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index 5d71911d..e79093f9 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -1,4 +1,5 @@ export * from './auth.model'; +export * from './chamaai.model'; export * from './chat.model'; export * from './chatwoot.model'; export * from './contact.model'; diff --git a/src/whatsapp/repository/chamaai.repository.ts b/src/whatsapp/repository/chamaai.repository.ts new file mode 100644 index 00000000..a2009f41 --- /dev/null +++ b/src/whatsapp/repository/chamaai.repository.ts @@ -0,0 +1,62 @@ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +import { ConfigService } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ChamaaiRaw, IChamaaiModel } from '../models'; + +export class ChamaaiRepository extends Repository { + constructor(private readonly chamaaiModel: IChamaaiModel, private readonly configService: ConfigService) { + super(configService); + } + + private readonly logger = new Logger('ChamaaiRepository'); + + public async create(data: ChamaaiRaw, instance: string): Promise { + try { + this.logger.verbose('creating chamaai'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('saving chamaai to db'); + const insert = await this.chamaaiModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); + + this.logger.verbose('chamaai saved to db: ' + insert.modifiedCount + ' chamaai'); + return { insertCount: insert.modifiedCount }; + } + + this.logger.verbose('saving chamaai to store'); + + this.writeStore({ + path: join(this.storePath, 'chamaai'), + fileName: instance, + data, + }); + + this.logger.verbose('chamaai saved to store in path: ' + join(this.storePath, 'chamaai') + '/' + instance); + + this.logger.verbose('chamaai created'); + return { insertCount: 1 }; + } catch (error) { + return error; + } + } + + public async find(instance: string): Promise { + try { + this.logger.verbose('finding chamaai'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding chamaai in db'); + return await this.chamaaiModel.findOne({ _id: instance }); + } + + this.logger.verbose('finding chamaai in store'); + return JSON.parse( + readFileSync(join(this.storePath, 'chamaai', instance + '.json'), { + encoding: 'utf-8', + }), + ) as ChamaaiRaw; + } catch (error) { + return {}; + } + } +} diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 2cd4931e..1c16fdef 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -5,6 +5,7 @@ import { join } from 'path'; import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { AuthRepository } from './auth.repository'; +import { ChamaaiRepository } from './chamaai.repository'; import { ChatRepository } from './chat.repository'; import { ChatwootRepository } from './chatwoot.repository'; import { ContactRepository } from './contact.repository'; @@ -29,6 +30,7 @@ export class RepositoryBroker { public readonly rabbitmq: RabbitmqRepository, public readonly typebot: TypebotRepository, public readonly proxy: ProxyRepository, + public readonly chamaai: ChamaaiRepository, public readonly auth: AuthRepository, private configService: ConfigService, dbServer?: MongoClient, @@ -63,6 +65,7 @@ export class RepositoryBroker { const rabbitmqDir = join(storePath, 'rabbitmq'); const typebotDir = join(storePath, 'typebot'); const proxyDir = join(storePath, 'proxy'); + const chamaaiDir = join(storePath, 'chamaai'); const tempDir = join(storePath, 'temp'); if (!fs.existsSync(authDir)) { @@ -113,6 +116,10 @@ export class RepositoryBroker { this.logger.verbose('creating proxy dir: ' + proxyDir); fs.mkdirSync(proxyDir, { recursive: true }); } + if (!fs.existsSync(chamaaiDir)) { + this.logger.verbose('creating chamaai dir: ' + chamaaiDir); + fs.mkdirSync(chamaaiDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/routers/chamaai.router.ts b/src/whatsapp/routers/chamaai.router.ts new file mode 100644 index 00000000..e8021306 --- /dev/null +++ b/src/whatsapp/routers/chamaai.router.ts @@ -0,0 +1,52 @@ +import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; +import { chamaaiSchema, instanceNameSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { ChamaaiDto } from '../dto/chamaai.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { chamaaiController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; + +const logger = new Logger('ChamaaiRouter'); + +export class ChamaaiRouter extends RouterBroker { + constructor(...guards: RequestHandler[]) { + super(); + this.router + .post(this.routerPath('set'), ...guards, async (req, res) => { + logger.verbose('request received in setChamaai'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: chamaaiSchema, + ClassRef: ChamaaiDto, + execute: (instance, data) => chamaaiController.createChamaai(instance, data), + }); + + res.status(HttpStatus.CREATED).json(response); + }) + .get(this.routerPath('find'), ...guards, async (req, res) => { + logger.verbose('request received in findChamaai'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: instanceNameSchema, + ClassRef: InstanceDto, + execute: (instance) => chamaaiController.findChamaai(instance), + }); + + res.status(HttpStatus.OK).json(response); + }); + } + + public readonly router = Router(); +} diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index a84e815d..f67c936a 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -4,6 +4,7 @@ import fs from 'fs'; import { Auth, configService } from '../../config/env.config'; import { authGuard } from '../guards/auth.guard'; import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard'; +import { ChamaaiRouter } from './chamaai.router'; import { ChatRouter } from './chat.router'; import { ChatwootRouter } from './chatwoot.router'; import { GroupRouter } from './group.router'; @@ -52,6 +53,7 @@ router .use('/websocket', new WebsocketRouter(...guards).router) .use('/rabbitmq', new RabbitmqRouter(...guards).router) .use('/typebot', new TypebotRouter(...guards).router) - .use('/proxy', new ProxyRouter(...guards).router); + .use('/proxy', new ProxyRouter(...guards).router) + .use('/chamaai', new ChamaaiRouter(...guards).router); export { HttpStatus, router }; diff --git a/src/whatsapp/services/chamaai.service.ts b/src/whatsapp/services/chamaai.service.ts new file mode 100644 index 00000000..9e42ffca --- /dev/null +++ b/src/whatsapp/services/chamaai.service.ts @@ -0,0 +1,196 @@ +import axios from 'axios'; +import { writeFileSync } from 'fs'; +import path from 'path'; + +import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { ChamaaiDto } from '../dto/chamaai.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChamaaiRaw } from '../models'; +import { WAMonitoringService } from './monitor.service'; + +export class ChamaaiService { + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {} + + private readonly logger = new Logger(ChamaaiService.name); + + public create(instance: InstanceDto, data: ChamaaiDto) { + this.logger.verbose('create chamaai: ' + instance.instanceName); + this.waMonitor.waInstances[instance.instanceName].setChamaai(data); + + return { chamaai: { ...instance, chamaai: data } }; + } + + public async find(instance: InstanceDto): Promise { + try { + this.logger.verbose('find chamaai: ' + instance.instanceName); + const result = await this.waMonitor.waInstances[instance.instanceName].findChamaai(); + + if (Object.keys(result).length === 0) { + throw new Error('Chamaai not found'); + } + + return result; + } catch (error) { + return { enabled: false, url: '', token: '', waNumber: '', answerByAudio: false }; + } + } + + private getTypeMessage(msg: any) { + this.logger.verbose('get type message'); + + const types = { + conversation: msg.conversation, + extendedTextMessage: msg.extendedTextMessage?.text, + }; + + this.logger.verbose('type message: ' + types); + + return types; + } + + private getMessageContent(types: any) { + this.logger.verbose('get message content'); + const typeKey = Object.keys(types).find((key) => types[key] !== undefined); + + const result = typeKey ? types[typeKey] : undefined; + + this.logger.verbose('message content: ' + result); + + return result; + } + + private getConversationMessage(msg: any) { + this.logger.verbose('get conversation message'); + + const types = this.getTypeMessage(msg); + + const messageContent = this.getMessageContent(types); + + this.logger.verbose('conversation message: ' + messageContent); + + return messageContent; + } + + private calculateTypingTime(text: string) { + const wordsPerMinute = 100; + + const wordCount = text.split(' ').length; + const typingTimeInMinutes = wordCount / wordsPerMinute; + const typingTimeInMilliseconds = typingTimeInMinutes * 60; + return typingTimeInMilliseconds; + } + + private convertToMilliseconds(count: number) { + const averageCharactersPerSecond = 10; + const characterCount = count; + const speakingTimeInSeconds = characterCount / averageCharactersPerSecond; + return speakingTimeInSeconds; + } + + public async sendChamaai(instance: InstanceDto, remoteJid: string, msg: any) { + const content = this.getConversationMessage(msg.message); + const msgType = msg.messageType; + const find = await this.find(instance); + const url = find.url; + const token = find.token; + const waNumber = find.waNumber; + const answerByAudio = find.answerByAudio; + + if (!content && msgType !== 'audioMessage') { + return; + } + + let data; + let endpoint; + + if (msgType === 'audioMessage') { + const downloadBase64 = await this.waMonitor.waInstances[instance.instanceName].getBase64FromMediaMessage({ + message: { + ...msg, + }, + }); + + const random = Math.random().toString(36).substring(7); + const nameFile = `${random}.ogg`; + + const fileData = Buffer.from(downloadBase64.base64, 'base64'); + + const fileName = `${path.join( + this.waMonitor.waInstances[instance.instanceName].storePath, + 'temp', + `${nameFile}`, + )}`; + + writeFileSync(fileName, fileData, 'utf8'); + + const urlServer = this.configService.get('SERVER').URL; + + const url = `${urlServer}/store/temp/${nameFile}`; + + data = { + waNumber: waNumber, + audioUrl: url, + queryNumber: remoteJid.split('@')[0], + answerByAudio: answerByAudio, + }; + endpoint = 'processMessageAudio'; + } else { + data = { + waNumber: waNumber, + question: content, + queryNumber: remoteJid.split('@')[0], + answerByAudio: answerByAudio, + }; + endpoint = 'processMessageText'; + } + + const request = await axios.post(`${url}/${endpoint}`, data, { + headers: { + Authorization: `${token}`, + }, + }); + + console.log(request.data); + + const answer = request.data?.answer; + + const type = request.data?.type; + + const characterCount = request.data?.characterCount; + + if (answer) { + if (type === 'text') { + this.waMonitor.waInstances[instance.instanceName].textMessage({ + number: remoteJid.split('@')[0], + options: { + delay: this.calculateTypingTime(answer) * 1000 || 1000, + presence: 'composing', + linkPreview: false, + quoted: { + key: msg.key, + message: msg.message, + }, + }, + textMessage: { + text: answer, + }, + }); + } + + if (type === 'audio') { + this.waMonitor.waInstances[instance.instanceName].audioWhatsapp({ + number: remoteJid.split('@')[0], + options: { + delay: characterCount ? this.convertToMilliseconds(characterCount) * 1000 || 1000 : 1000, + presence: 'recording', + encoding: true, + }, + audioMessage: { + audio: answer, + }, + }); + } + } + } +} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d11946ee..445069a5 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -113,7 +113,7 @@ import { SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { ProxyRaw, RabbitmqRaw, SettingsRaw, TypebotRaw } from '../models'; +import { ChamaaiRaw, ProxyRaw, RabbitmqRaw, SettingsRaw, TypebotRaw } from '../models'; import { ChatRaw } from '../models/chat.model'; import { ChatwootRaw } from '../models/chatwoot.model'; import { ContactRaw } from '../models/contact.model'; @@ -126,6 +126,7 @@ import { MessageUpQuery } from '../repository/messageUp.repository'; import { RepositoryBroker } from '../repository/repository.manager'; import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; import { waMonitor } from '../whatsapp.module'; +import { ChamaaiService } from './chamaai.service'; import { ChatwootService } from './chatwoot.service'; import { TypebotService } from './typebot.service'; @@ -151,6 +152,7 @@ export class WAStartupService { private readonly localRabbitmq: wa.LocalRabbitmq = {}; public readonly localTypebot: wa.LocalTypebot = {}; private readonly localProxy: wa.LocalProxy = {}; + private readonly localChamaai: wa.LocalChamaai = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); private readonly msgRetryCounterCache: CacheStore = new NodeCache(); @@ -164,6 +166,8 @@ export class WAStartupService { private typebotService = new TypebotService(waMonitor); + private chamaaiService = new ChamaaiService(waMonitor, this.configService); + public set instanceName(name: string) { this.logger.verbose(`Initializing instance '${name}'`); if (!name) { @@ -579,6 +583,52 @@ export class WAStartupService { return data; } + private async loadChamaai() { + this.logger.verbose('Loading chamaai'); + const data = await this.repository.chamaai.find(this.instanceName); + + this.localChamaai.enabled = data?.enabled; + this.logger.verbose(`Chamaai enabled: ${this.localChamaai.enabled}`); + + this.localChamaai.url = data?.url; + this.logger.verbose(`Chamaai url: ${this.localChamaai.url}`); + + this.localChamaai.token = data?.token; + this.logger.verbose(`Chamaai token: ${this.localChamaai.token}`); + + this.localChamaai.waNumber = data?.waNumber; + this.logger.verbose(`Chamaai waNumber: ${this.localChamaai.waNumber}`); + + this.localChamaai.answerByAudio = data?.answerByAudio; + this.logger.verbose(`Chamaai answerByAudio: ${this.localChamaai.answerByAudio}`); + + this.logger.verbose('Chamaai loaded'); + } + + public async setChamaai(data: ChamaaiRaw) { + this.logger.verbose('Setting chamaai'); + await this.repository.chamaai.create(data, this.instanceName); + this.logger.verbose(`Chamaai url: ${data.url}`); + this.logger.verbose(`Chamaai token: ${data.token}`); + this.logger.verbose(`Chamaai waNumber: ${data.waNumber}`); + this.logger.verbose(`Chamaai answerByAudio: ${data.answerByAudio}`); + + Object.assign(this.localChamaai, data); + this.logger.verbose('Chamaai set'); + } + + public async findChamaai() { + this.logger.verbose('Finding chamaai'); + const data = await this.repository.chamaai.find(this.instanceName); + + if (!data) { + this.logger.verbose('Chamaai not found'); + throw new NotFoundException('Chamaai not found'); + } + + return data; + } + public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; @@ -1065,6 +1115,7 @@ export class WAStartupService { this.loadRabbitmq(); this.loadTypebot(); this.loadProxy(); + this.loadChamaai(); this.instance.authState = await this.defineAuthState(); @@ -1383,7 +1434,7 @@ export class WAStartupService { ); } - if (this.localTypebot.enabled && messageRaw.key.remoteJid.includes('@s.whatsapp.net')) { + if (this.localTypebot.enabled && messageRaw.key.fromMe === false) { await this.typebotService.sendTypebot( { instanceName: this.instance.name }, messageRaw.key.remoteJid, @@ -1391,6 +1442,14 @@ export class WAStartupService { ); } + if (this.localChamaai.enabled && messageRaw.key.fromMe === false) { + await this.chamaaiService.sendChamaai( + { instanceName: this.instance.name }, + messageRaw.key.remoteJid, + messageRaw, + ); + } + this.logger.verbose('Inserting message in database'); await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); @@ -2315,7 +2374,7 @@ export class WAStartupService { return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); } - private async processAudio(audio: string, number: string) { + public async processAudio(audio: string, number: string) { this.logger.verbose('Processing audio'); let tempAudioPath: string; let outputAudio: string; diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 893b5f87..72718b65 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -102,6 +102,14 @@ export declare namespace wa { proxy?: string; }; + export type LocalChamaai = { + enabled?: boolean; + url?: string; + token?: string; + waNumber?: string; + answerByAudio?: boolean; + }; + export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused'; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index d8ed5a62..a37e98ef 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -3,6 +3,7 @@ import { eventEmitter } from '../config/event.config'; import { Logger } from '../config/logger.config'; import { dbserver } from '../libs/db.connect'; import { RedisCache } from '../libs/redis.client'; +import { ChamaaiController } from './controllers/chamaai.controller'; import { ChatController } from './controllers/chat.controller'; import { ChatwootController } from './controllers/chatwoot.controller'; import { GroupController } from './controllers/group.controller'; @@ -17,6 +18,7 @@ import { WebhookController } from './controllers/webhook.controller'; import { WebsocketController } from './controllers/websocket.controller'; import { AuthModel, + ChamaaiModel, ChatModel, ChatwootModel, ContactModel, @@ -30,6 +32,7 @@ import { WebsocketModel, } from './models'; import { AuthRepository } from './repository/auth.repository'; +import { ChamaaiRepository } from './repository/chamaai.repository'; import { ChatRepository } from './repository/chat.repository'; import { ChatwootRepository } from './repository/chatwoot.repository'; import { ContactRepository } from './repository/contact.repository'; @@ -43,6 +46,7 @@ import { TypebotRepository } from './repository/typebot.repository'; import { WebhookRepository } from './repository/webhook.repository'; import { WebsocketRepository } from './repository/websocket.repository'; import { AuthService } from './services/auth.service'; +import { ChamaaiService } from './services/chamaai.service'; import { ChatwootService } from './services/chatwoot.service'; import { WAMonitoringService } from './services/monitor.service'; import { ProxyService } from './services/proxy.service'; @@ -62,6 +66,7 @@ const typebotRepository = new TypebotRepository(TypebotModel, configService); const webhookRepository = new WebhookRepository(WebhookModel, configService); const websocketRepository = new WebsocketRepository(WebsocketModel, configService); const proxyRepository = new ProxyRepository(ProxyModel, configService); +const chamaaiRepository = new ChamaaiRepository(ChamaaiModel, configService); const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService); const chatwootRepository = new ChatwootRepository(ChatwootModel, configService); const settingsRepository = new SettingsRepository(SettingsModel, configService); @@ -79,6 +84,7 @@ export const repository = new RepositoryBroker( rabbitmqRepository, typebotRepository, proxyRepository, + chamaaiRepository, authRepository, configService, dbserver?.getClient(), @@ -106,6 +112,10 @@ const proxyService = new ProxyService(waMonitor); export const proxyController = new ProxyController(proxyService); +const chamaaiService = new ChamaaiService(waMonitor, configService); + +export const chamaaiController = new ChamaaiController(chamaaiService); + const rabbitmqService = new RabbitmqService(waMonitor); export const rabbitmqController = new RabbitmqController(rabbitmqService); From b7218a05be69314f355577303f5c655a2982ce11 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 19 Aug 2023 15:13:35 -0300 Subject: [PATCH 151/177] feat: Inegration with Chama AI --- src/whatsapp/services/chamaai.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/chamaai.service.ts b/src/whatsapp/services/chamaai.service.ts index 9e42ffca..ffa2d5a6 100644 --- a/src/whatsapp/services/chamaai.service.ts +++ b/src/whatsapp/services/chamaai.service.ts @@ -82,7 +82,7 @@ export class ChamaaiService { } private convertToMilliseconds(count: number) { - const averageCharactersPerSecond = 10; + const averageCharactersPerSecond = 15; const characterCount = count; const speakingTimeInSeconds = characterCount / averageCharactersPerSecond; return speakingTimeInSeconds; From 03637b2d4d8640733294be31b35eb6a396ee1195 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 23 Aug 2023 07:27:40 -0300 Subject: [PATCH 152/177] Added listening_from_me option in Set Typebot --- CHANGELOG.md | 10 +++++ Dockerfile | 2 +- Extras/typebot/typebot-example.json | 2 +- package.json | 2 +- src/config/env.config.ts | 39 ++++++++++++------- src/validate/validate.schema.ts | 5 ++- .../controllers/instance.controller.ts | 4 ++ src/whatsapp/dto/instance.dto.ts | 1 + src/whatsapp/dto/typebot.dto.ts | 1 + src/whatsapp/models/typebot.model.ts | 2 + src/whatsapp/services/chamaai.service.ts | 2 - src/whatsapp/services/chatwoot.service.ts | 16 ++++---- src/whatsapp/services/monitor.service.ts | 5 +++ src/whatsapp/services/typebot.service.ts | 23 +++++++---- src/whatsapp/services/whatsapp.service.ts | 18 ++++++--- src/whatsapp/types/wa.types.ts | 1 + 16 files changed, 90 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 059dd781..23129582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 1.5.1 (homolog) + +### Feature + +* Added listening_from_me option in Set Typebot + +### Fixed + +* Fix looping connection messages in chatwoot + # 1.5.0 (2023-08-18 12:47) ### Feature diff --git a/Dockerfile b/Dockerfile index c9975782..3777091f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:16.18-alpine -LABEL version="1.5.0" description="Api to control whatsapp features through http requests." +LABEL version="1.5.1" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" diff --git a/Extras/typebot/typebot-example.json b/Extras/typebot/typebot-example.json index 93ababc4..c45cd509 100644 --- a/Extras/typebot/typebot-example.json +++ b/Extras/typebot/typebot-example.json @@ -1 +1 @@ -{"id":"l27ft2bq9a7tke15i7m64d9o","version":"3","createdAt":"2023-08-04T17:27:18.072Z","updatedAt":"2023-08-11T21:38:15.669Z","icon":null,"name":"[Dgcode] [whatsapp] Pesquisa Satisfacao","folderId":"cll1fzkfy0008pa65kgz3tm86","groups":[{"id":"c76ucoughhenpernmadu7ibg","title":"Start","blocks":[{"id":"qn40kjwtw1he3l1bujt3bnje","type":"start","label":"Start","groupId":"c76ucoughhenpernmadu7ibg","outgoingEdgeId":"aovnigvk665gzhyzg7bxhvn0"}],"graphCoordinates":{"x":-126.43,"y":220.29}},{"id":"nog2woqmvhssnnjlcpwd41k5","title":"Apresentação","blocks":[{"id":"potdr8jwrn6mnkjipynqjmhh","type":"Set variable","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"type":"Random ID","variableId":"vsu5or5sxes9lyuhsgcl3cuyd"}},{"id":"jp1v0u6lucs72qn8h2y0krll","type":"Google Sheets","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"action":"Insert a row","sheetId":"0","cellsToInsert":[{"id":"e7h6q8pa9q9p2xv4owpfkwa4","value":"{{ID}}","column":"ID"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"mcpyoq8x28bnwp23g7h1dbc1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Olá! Bem-vindo(a) à nossa "},{"bold":true,"text":"pesquisa de satisfação"},{"text":"."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o0731ch0epj2vm2c5aoxyvw1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Meu nome é "},{"bold":true,"text":"🤖 Mike"},{"text":", estou aqui para ouvir sua opinião e experiência com nossos serviços."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"hgqbj5kmosz64cb435xqh0am","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é fundamental para nos ajudar a melhorar!"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"cbvgdo0jknjyzmvwe6o614ni","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Vamos começar?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"nmhkn4jod3evk08tbq5vw3s3","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual o seu nome?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o8ijci5gdfsp6fpv07kwh8br","type":"text input","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o seu nome"},"variableId":"vo40px5r6wg9vhs9fixd45kzn"}},{"id":"etbdi8paer56f82p6xc379um","type":"Google Sheets","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{name}}","column":"Nome"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"hqxrso204tkg5p71o96hduaz"}],"graphCoordinates":{"x":771.26,"y":213}},{"id":"j5co2kcotxafuxhzlj7u0qnn","title":"Qual seu email?","blocks":[{"id":"he1367t9ssao735kidd86mna","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, agora me informe seu endereço de email?"}]}]},"groupId":"j5co2kcotxafuxhzlj7u0qnn"},{"id":"qb8nwfs52g168tmnvp257b44","type":"email input","groupId":"j5co2kcotxafuxhzlj7u0qnn","options":{"labels":{"button":"Enviar","placeholder":"Digite o seu email"},"variableId":"vr75l1drc5uoxvisje0hio5ph","retryMessageContent":"Email incorreto!"}},{"id":"m0tqedan6l1j5jr6fb9wfdm7","type":"Google Sheets","groupId":"j5co2kcotxafuxhzlj7u0qnn","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{email}}","column":"Email"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"ghbmp8sjr88b30phgi89qkjl"}],"graphCoordinates":{"x":1236.92,"y":204.84}},{"id":"wtd0o382phaji7i7u2n8pody","title":"Pergunta 1","blocks":[{"id":"zr69lw3bcmmkgahqq8og7shw","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, qual é o seu nível de satisfação geral com os serviços que nossa empresa fornece?"}]}]},"groupId":"wtd0o382phaji7i7u2n8pody"},{"id":"ku0zpu43cbbnd7y0ai71ptde","type":"rating input","groupId":"wtd0o382phaji7i7u2n8pody","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vbfl3sqze2wzicn9l1n9ckjs4"}},{"id":"l2s8irgrtrxfwy97v2gclajy","type":"Google Sheets","groupId":"wtd0o382phaji7i7u2n8pody","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question1}}","column":"Pergunta 1"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"d2m2uo2gvnqzqw7m3hqp78zk"}],"graphCoordinates":{"x":1692.4,"y":194.19}},{"id":"ylerbfc1l2o62j68g8ghegxt","title":"Pergunta 2","blocks":[{"id":"l19jgtpln9al473dudr0gbzn","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, em que medida nossa empresa atendeu às suas expectativas em termos de qualidade do serviço prestado?"}]}]},"groupId":"ylerbfc1l2o62j68g8ghegxt"},{"id":"kfxuc6p58cdzy1xcyp4i4ra7","type":"rating input","groupId":"ylerbfc1l2o62j68g8ghegxt","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vkgl2bfdbyms1dyc1s6efx678"}},{"id":"v6vdddy19ncfhrkeettwr123","type":"Google Sheets","groupId":"ylerbfc1l2o62j68g8ghegxt","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question2}}","column":"Pergunta 2"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"oylxp0jgu571sjsgqevol5yi"}],"graphCoordinates":{"x":2156.14,"y":190.76}},{"id":"lbieknd0qp42pogsby5l82ww","title":"Pergunta 3","blocks":[{"id":"y43s12dnoxh772c9o3pmnhxf","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você teve alguma dificuldade em se comunicar com nossa equipe de suporte ao cliente?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"lbieknd0qp42pogsby5l82ww"},{"id":"fb6ckchqp8vx9ypig07we6q4","type":"text input","groupId":"lbieknd0qp42pogsby5l82ww","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"rj84ja6d3mgouspwhrkeadz7","type":"Google Sheets","groupId":"lbieknd0qp42pogsby5l82ww","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question3}}","column":"Pergunta 3"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"b538q1mt18l6oddo397nh1m4","type":"Condition","items":[{"id":"dwhc3ptqvktlgfvl17xg79s5","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"w6ao5pi6wt0966tobkned56m"},{"id":"cod3tkt16ry8ixm5u7rwxzm9","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"wlfmh2g3j5avj75sa9q6rsab"}],"groupId":"lbieknd0qp42pogsby5l82ww","outgoingEdgeId":"ehcwqdrkc4025pui2y1s9390"}],"graphCoordinates":{"x":2605.34,"y":189.93}},{"id":"qzhp25b9f2lvt4yeniqvjkav","title":"Pergunta 4","blocks":[{"id":"pos7njae2r35r29kcbyxtz2j","type":"text","content":{"richText":[{"type":"p","children":[{"text":"{{name}}, por favor, descreva o problema para que possamos melhorar."}]}]},"groupId":"qzhp25b9f2lvt4yeniqvjkav"},{"id":"ce2eodve0e4f2rubk4wv5jf1","type":"text input","groupId":"qzhp25b9f2lvt4yeniqvjkav","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Descreva o problema"},"variableId":"vd6fm2i9shcdjz8bhhwbsdh6t"}},{"id":"e75om4ccho8uob245t2wethw","type":"Google Sheets","groupId":"qzhp25b9f2lvt4yeniqvjkav","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question4}}","column":"Pergunta 4"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"fe7xrdj315gebr22f0eylupl"}],"graphCoordinates":{"x":3041.23,"y":187.11}},{"id":"c8kh8eee1m3wyy372v4n6m1i","title":"Pergunta 5","blocks":[{"id":"txqi87lwinpa0p5of0xmqxu6","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, como você avalia a capacidade da nossa empresa de cumprir os prazos acordados?"}]}]},"groupId":"c8kh8eee1m3wyy372v4n6m1i"},{"id":"mg2tmcmwnx3tap0hs4b7e0la","type":"rating input","groupId":"c8kh8eee1m3wyy372v4n6m1i","options":{"labels":{"button":"Enviar"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vz6lvahwo15dosvckdtkxduly"}},{"id":"cciytmy1bulw32j24ndbq39r","type":"Google Sheets","groupId":"c8kh8eee1m3wyy372v4n6m1i","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question5}}","column":"Pergunta 5"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"dlfg76etmcqs3sgxplnisbf1"}],"graphCoordinates":{"x":3501.8,"y":179.58}},{"id":"tn8bcyughy9dsxhmjngrosvj","title":"Pergunta 6","blocks":[{"id":"aema350m33n9dljopcsxn8q5","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você recomendaria nossos serviços para outras pessoas ou empresas?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"tn8bcyughy9dsxhmjngrosvj"},{"id":"wk4bkxbxcfu9skrzn8p8077u","type":"text input","groupId":"tn8bcyughy9dsxhmjngrosvj","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"uucahcq4zwadysop7n9ktbms","type":"Google Sheets","groupId":"tn8bcyughy9dsxhmjngrosvj","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question6}}","column":"Pergunta 6"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"n3j2dxaalkljl020o0o61ef9","type":"Condition","items":[{"id":"ifhm8cj8lsulhrarnfda2oal","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"yu9762ttf5jn3bmhd6uzrsv8"},{"id":"gxp6j3ouga4r0t8364tn8axs","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"ji1y2o1hldhemto0ymwou09c"}],"groupId":"tn8bcyughy9dsxhmjngrosvj","outgoingEdgeId":"d3u83fikqplfy9ntva3sm7eg"}],"graphCoordinates":{"x":3926.41,"y":186.15}},{"id":"nzkhdw3hdv550aepsxvk2a0u","title":"Pergunta 7","blocks":[{"id":"io90onrpfrokejgkps94r3dj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Que pena {{name}}, por gentileza, nos conte o motivo?"}]}]},"groupId":"nzkhdw3hdv550aepsxvk2a0u"},{"id":"dj7dbgyjqk0a5u3jn6kzykb2","type":"text input","groupId":"nzkhdw3hdv550aepsxvk2a0u","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o motivo"},"variableId":"vept0w6tr0w7eyyi52hgq1r3c"}},{"id":"i10wbfctp4dzroie3310rra0","type":"Google Sheets","groupId":"nzkhdw3hdv550aepsxvk2a0u","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question7}}","column":"Pergunta 7"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"vu3k1pxfilhmz59malpqvj1u"}],"graphCoordinates":{"x":4352.64,"y":194.04}},{"id":"jdz9w8vrz09vefk4wqrf0vwl","title":"Pergunta 8","blocks":[{"id":"hndzyb58fqxudykajr22skla","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Existe alguma sugestão que você gostaria de nos dar para melhorar nossos serviços?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},{"id":"ol9l8fdb3q65auykrn383q6d","type":"text input","groupId":"jdz9w8vrz09vefk4wqrf0vwl","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"qhxod01c7mdlfrxr5cy0xgoj","type":"Google Sheets","groupId":"jdz9w8vrz09vefk4wqrf0vwl","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question8}}","column":"Pergunta 8"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"zderh9hqjkpuz58p79szfa1i","type":"Condition","items":[{"id":"lur26nqa8dv7m4jmmljpyyf1","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"x2fzu1uuukp9cgmdzecp7mgk"},{"id":"aoj7e49zimwxng4o7bd6u00s","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"mb1fg83gijikrafud2ml6zbn"}],"groupId":"jdz9w8vrz09vefk4wqrf0vwl","outgoingEdgeId":"amyrx4i2rm3cjksym5zvwd50"}],"graphCoordinates":{"x":4768.69,"y":201.49}},{"id":"c4k1ftb4rbynkb01ulwuh4qh","title":"Pergunta 9","blocks":[{"id":"jqn5de3i29ygjyf6usbj117t","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual seria a sua sugestão?"}]}]},"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},{"id":"wfucksh3yaeq21l7mnlnsx75","type":"text input","groupId":"c4k1ftb4rbynkb01ulwuh4qh","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua sugestão"},"variableId":"vhygxyvhu5l6r2uws1cbthmxm"}},{"id":"kt1w6r6mucelx2odhnka5td1","type":"Google Sheets","groupId":"c4k1ftb4rbynkb01ulwuh4qh","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question9}}","column":"Pergunta 9"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"imbs12h9gb2dpmrb19yvx71u"}],"graphCoordinates":{"x":5233.77,"y":205.27}},{"id":"vvyooiddvdbon0t21bvzdr7q","title":"Finalização","blocks":[{"id":"efk089lhks1ev4khy38caner","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Então {{name}}, agradecemos muito por dedicar um tempo para nos fornecer seu feedback."}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"pvu3g8vpqdi3aecu2u0in2d0","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é muito importante para nós, e trabalharemos arduamente para melhorar ainda mais nossos serviços!"}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"wqe9r1ivjf0ikubqichufzsg","type":"Webhook","groupId":"vvyooiddvdbon0t21bvzdr7q","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[]},"webhookId":"i3g1959ev6fl9s61ir8hn1we"}],"graphCoordinates":{"x":7067.06,"y":231.55}},{"id":"ffm0s2y4head3auw808hwfnx","title":"Retorna Pergunta 3","blocks":[{"id":"ox70407atqtf1kwrszis4cix","type":"Set variable","groupId":"ffm0s2y4head3auw808hwfnx","options":{"type":"Empty","variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"bcwkrcxtsc8drzwynb2igu0g","type":"Jump","groupId":"ffm0s2y4head3auw808hwfnx","options":{"groupId":"lbieknd0qp42pogsby5l82ww"}}],"graphCoordinates":{"x":3031.03,"y":754.83}},{"id":"cf8r0wx0sgw6c9v79ebja1tj","title":"Retorna Pergunta 6","blocks":[{"id":"e02yfpbpj298m1q9y4tb905i","type":"Set variable","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"type":"Empty","variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"wjfe41oxiik0jgwcye7sczeu","type":"Jump","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"groupId":"tn8bcyughy9dsxhmjngrosvj"}}],"graphCoordinates":{"x":4360.16,"y":732.74}},{"id":"b7zfnwcxvu28s98ii03isdae","title":"Retorna Pergunta 8","blocks":[{"id":"j1xmpy60ggf162ej9a0rti4f","type":"Set variable","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"type":"Empty","variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"lk06yb9dvrctn2u9tx35n12c","type":"Jump","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"}}],"graphCoordinates":{"x":5213.21,"y":778}},{"id":"z0idhsnqisrd695z0j1tnqvw","title":"Retorna Pergunta 10","blocks":[{"id":"gs96ig682082mj4igcjjuh76","type":"Set variable","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"type":"Empty","variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"tihlp1xm8mvpdm3d0dqkwwx6","type":"Jump","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"}}],"graphCoordinates":{"x":6100.86,"y":819.65}},{"id":"qsrkmfsr04kayulair47gmn0","title":"Gera QRCODE pix","blocks":[{"id":"qs1uxqm8jqla9uui43ofms65","type":"Webhook","groupId":"qsrkmfsr04kayulair47gmn0","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[{"id":"gcia6kdba4yydt14klsg8h6x","bodyPath":"data.qrcode_base64","variableId":"vamn8ortov9nk1y04vczo375h"}]},"webhookId":"ajx8mv7trd50mbv2uj6fr3x5"},{"id":"sz447ty7t4vreto9bf07h52i","type":"Set variable","groupId":"qsrkmfsr04kayulair47gmn0","options":{"type":"Custom","variableId":"vamn8ortov9nk1y04vczo375h","expressionToEvaluate":"if({{remoteJid}}){\n return {{qrcode}}.replace('data:image/png;base64,', ''); \n}else{\n return {{qrcode}}\n}\n"}},{"id":"c3wp5ic2wx9emj6kkii42xpj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Aqui está qrcode para sua contribuição de R$ {{question11}}, caso tenha dificuldade na leitura utilize a nossa chave:"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"Telefone: 7499879409"}]},{"type":"p","children":[{"text":"Em nome de: Davidson Oliveira Gomes"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"jncggap4fivalzgntw3bfaom","type":"image","content":{"url":"{{qrcode}}"},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"chiz9utw18jvui4c2r0vsiqp","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito obrigado pela sua contribuição!"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0","outgoingEdgeId":"cwlt91vwhr7gvgx0qx2mnxtr"}],"graphCoordinates":{"x":6607.75,"y":229.53}},{"id":"cs5kjnrcsh4bjiuvwf99agho","title":"Pergunta 10","blocks":[{"id":"axpk3aoauusbiy8av70fc2fo","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Gostaria de fazer uma contribuição?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"cs5kjnrcsh4bjiuvwf99agho"},{"id":"q136n37ja1g5dyhdeisur4rg","type":"text input","groupId":"cs5kjnrcsh4bjiuvwf99agho","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua resposta"},"variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"m3sx9dam0ngbyni52l5b8b34","type":"Google Sheets","groupId":"cs5kjnrcsh4bjiuvwf99agho","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question10}}","column":"Pergunta 10"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"}},{"id":"xza6e0p4hgkfz1wvwcjss48s","type":"Condition","items":[{"id":"m5mvt5ecw81eevl428n56aji","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"fe1wk4fc1xzt7mefasb2qzqz"},{"id":"bpcidulg0g7v8pwh3w9my880","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"xg1zkpvob8ilx2r8p0kv604d"}],"groupId":"cs5kjnrcsh4bjiuvwf99agho","outgoingEdgeId":"o746eh96sq2j7juionfql73t"}],"graphCoordinates":{"x":5708.94,"y":210.9}},{"id":"tq60r6azxrmn17b4y7mjovf5","title":"Pergunta 11","blocks":[{"id":"o5fspfge731wt6m781nzjsll","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, quanto você deseja contribuir?"}]}]},"groupId":"tq60r6azxrmn17b4y7mjovf5"},{"id":"khncvmg5fcjsmu8tlmf8in6m","type":"number input","groupId":"tq60r6azxrmn17b4y7mjovf5","options":{"max":5000,"min":1,"step":1,"labels":{"button":"Enviar","placeholder":"Digite um numero"},"variableId":"vhoqah2c0blbx92bfmd4gjnyx"}},{"id":"xcd54kvlpao5si54yuvle8y8","type":"Google Sheets","groupId":"tq60r6azxrmn17b4y7mjovf5","options":{"action":"Update a row","filter":{"comparisons":[{"id":"w2o1z5ire06bqcg8b53kzct8","value":"{{ID}}","column":"ID","comparisonOperator":"Equal to"}],"logicalOperator":"AND"},"sheetId":"0","cellsToUpsert":[{"id":"cn2vxka7p4a590r61ia7kwzg","value":"{{question11}}","column":"Pergunta 11"}],"credentialsId":"clkvo2r8h0003mk664r70mype","spreadsheetId":"1qFqRjMIJXc6BLoJSqrpIw-aF3pVjVav64lQo-SBmoBs"},"outgoingEdgeId":"t1r05l9c3n3n377bdt8adu2x"}],"graphCoordinates":{"x":6158.94,"y":224.91}},{"id":"h0svx6gyzgjsclr9hbpo04v6","title":"Configurações Iniciais","blocks":[{"id":"na4zglpatkg8ejqcap8lcv69","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vp1ask55v2r58ukom5lek5hej","expressionToEvaluate":"https://8338-2804-910-16a-ff01-bd73-9d18-5395-c820.ngrok-free.app"}},{"id":"t2bdxy8x8fsn29yijk02ti43","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vtsldvs2u8ui93tktazy77djw","expressionToEvaluate":"8EAA51D7-F658-409D-9C9C-0A68DDC783DD1"}},{"id":"rt5h0lk6jaoh5hzag0s5hidd","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vkg1qlinovziltaloqhso2cw7","expressionToEvaluate":"https://pix.dgcode.com.br"}},{"id":"mh758b8y8288t56s6wz73mht","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vpjyy2e2ha6mu5x10q0nowuz3","expressionToEvaluate":"Davidson Oliveira Gomes"}},{"id":"ri9kv80djsej7r51m8xfjhuk","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vicsm3nkvhssvfhgss2xce2ad","expressionToEvaluate":"Telefone"}},{"id":"ye4teva02mnxph0rvfszdnsn","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vlmflx32cjlz457h0uzdi706g","expressionToEvaluate":"74999879409"}},{"id":"hfz4hqzfe6wgje96ezb5kann","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"veesfw943copg17w2qzdln9be","expressionToEvaluate":"Irece"}},{"id":"nd3yk369k7j73kws6exos0jw","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vavwvk4wgst506zdioplg4u8p","expressionToEvaluate":"TypeBot"},"outgoingEdgeId":"mb90csrzzep8qz2opcxmw736"}],"graphCoordinates":{"x":312.08,"y":218.28}}],"variables":[{"id":"vo40px5r6wg9vhs9fixd45kzn","name":"name"},{"id":"vr75l1drc5uoxvisje0hio5ph","name":"email"},{"id":"vzhsu0uc4suqoz38kv3q891ma","name":"question3"},{"id":"vbfl3sqze2wzicn9l1n9ckjs4","name":"question1"},{"id":"vkgl2bfdbyms1dyc1s6efx678","name":"question2"},{"id":"vd6fm2i9shcdjz8bhhwbsdh6t","name":"question4"},{"id":"vz6lvahwo15dosvckdtkxduly","name":"question5"},{"id":"vndjnalmnb3ez9beeon5tzrgq","name":"question6"},{"id":"vept0w6tr0w7eyyi52hgq1r3c","name":"question7"},{"id":"vy5it60mewmth7mayzhlgmzf0","name":"question8"},{"id":"vhygxyvhu5l6r2uws1cbthmxm","name":"question9"},{"id":"vrdwfo2lpoei2fzlzazh4pp61","name":"pushName"},{"id":"vz1uq7t77aivpi5crwy6ifact","name":"remoteJid"},{"id":"vsu5or5sxes9lyuhsgcl3cuyd","name":"ID"},{"id":"vamn8ortov9nk1y04vczo375h","name":"qrcode"},{"id":"vx6p4ivk4mnssvbhl30c5zng9","name":"question10"},{"id":"vhoqah2c0blbx92bfmd4gjnyx","name":"question11"},{"id":"vpjyy2e2ha6mu5x10q0nowuz3","name":"me"},{"id":"vicsm3nkvhssvfhgss2xce2ad","name":"typePIX"},{"id":"vavwvk4wgst506zdioplg4u8p","name":"reference"},{"id":"vlmflx32cjlz457h0uzdi706g","name":"keyPIX"},{"id":"vkg1qlinovziltaloqhso2cw7","name":"apiURL"},{"id":"veesfw943copg17w2qzdln9be","name":"city"},{"id":"vp1ask55v2r58ukom5lek5hej","name":"evolutionURL"},{"id":"vtsldvs2u8ui93tktazy77djw","name":"evolutionToken"}],"edges":[{"id":"w6ao5pi6wt0966tobkned56m","to":{"groupId":"qzhp25b9f2lvt4yeniqvjkav"},"from":{"itemId":"dwhc3ptqvktlgfvl17xg79s5","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"wlfmh2g3j5avj75sa9q6rsab","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"itemId":"cod3tkt16ry8ixm5u7rwxzm9","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"yu9762ttf5jn3bmhd6uzrsv8","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"itemId":"ifhm8cj8lsulhrarnfda2oal","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ji1y2o1hldhemto0ymwou09c","to":{"groupId":"nzkhdw3hdv550aepsxvk2a0u"},"from":{"itemId":"gxp6j3ouga4r0t8364tn8axs","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"x2fzu1uuukp9cgmdzecp7mgk","to":{"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},"from":{"itemId":"lur26nqa8dv7m4jmmljpyyf1","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"d3u83fikqplfy9ntva3sm7eg","to":{"groupId":"cf8r0wx0sgw6c9v79ebja1tj"},"from":{"blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ehcwqdrkc4025pui2y1s9390","to":{"groupId":"ffm0s2y4head3auw808hwfnx"},"from":{"blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"hqxrso204tkg5p71o96hduaz","to":{"groupId":"j5co2kcotxafuxhzlj7u0qnn"},"from":{"blockId":"etbdi8paer56f82p6xc379um","groupId":"nog2woqmvhssnnjlcpwd41k5"}},{"id":"ghbmp8sjr88b30phgi89qkjl","to":{"groupId":"wtd0o382phaji7i7u2n8pody"},"from":{"blockId":"m0tqedan6l1j5jr6fb9wfdm7","groupId":"j5co2kcotxafuxhzlj7u0qnn"}},{"id":"d2m2uo2gvnqzqw7m3hqp78zk","to":{"groupId":"ylerbfc1l2o62j68g8ghegxt"},"from":{"blockId":"l2s8irgrtrxfwy97v2gclajy","groupId":"wtd0o382phaji7i7u2n8pody"}},{"id":"oylxp0jgu571sjsgqevol5yi","to":{"groupId":"lbieknd0qp42pogsby5l82ww"},"from":{"blockId":"v6vdddy19ncfhrkeettwr123","groupId":"ylerbfc1l2o62j68g8ghegxt"}},{"id":"fe7xrdj315gebr22f0eylupl","to":{"groupId":"c8kh8eee1m3wyy372v4n6m1i"},"from":{"blockId":"e75om4ccho8uob245t2wethw","groupId":"qzhp25b9f2lvt4yeniqvjkav"}},{"id":"dlfg76etmcqs3sgxplnisbf1","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"blockId":"cciytmy1bulw32j24ndbq39r","groupId":"c8kh8eee1m3wyy372v4n6m1i"}},{"id":"vu3k1pxfilhmz59malpqvj1u","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"blockId":"i10wbfctp4dzroie3310rra0","groupId":"nzkhdw3hdv550aepsxvk2a0u"}},{"id":"imbs12h9gb2dpmrb19yvx71u","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"blockId":"kt1w6r6mucelx2odhnka5td1","groupId":"c4k1ftb4rbynkb01ulwuh4qh"}},{"id":"mb1fg83gijikrafud2ml6zbn","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"itemId":"aoj7e49zimwxng4o7bd6u00s","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"amyrx4i2rm3cjksym5zvwd50","to":{"groupId":"b7zfnwcxvu28s98ii03isdae"},"from":{"blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"o746eh96sq2j7juionfql73t","to":{"groupId":"z0idhsnqisrd695z0j1tnqvw"},"from":{"blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"fe1wk4fc1xzt7mefasb2qzqz","to":{"groupId":"tq60r6azxrmn17b4y7mjovf5"},"from":{"itemId":"m5mvt5ecw81eevl428n56aji","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"xg1zkpvob8ilx2r8p0kv604d","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"itemId":"bpcidulg0g7v8pwh3w9my880","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"t1r05l9c3n3n377bdt8adu2x","to":{"groupId":"qsrkmfsr04kayulair47gmn0"},"from":{"blockId":"xcd54kvlpao5si54yuvle8y8","groupId":"tq60r6azxrmn17b4y7mjovf5"}},{"id":"cwlt91vwhr7gvgx0qx2mnxtr","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"blockId":"chiz9utw18jvui4c2r0vsiqp","groupId":"qsrkmfsr04kayulair47gmn0"}},{"id":"aovnigvk665gzhyzg7bxhvn0","to":{"groupId":"h0svx6gyzgjsclr9hbpo04v6"},"from":{"blockId":"qn40kjwtw1he3l1bujt3bnje","groupId":"c76ucoughhenpernmadu7ibg"}},{"id":"mb90csrzzep8qz2opcxmw736","to":{"groupId":"nog2woqmvhssnnjlcpwd41k5"},"from":{"blockId":"nd3yk369k7j73kws6exos0jw","groupId":"h0svx6gyzgjsclr9hbpo04v6"}}],"theme":{"chat":{"inputs":{"color":"#ffffff","backgroundColor":"#1e293b","placeholderColor":"#9095A0"},"buttons":{"color":"#ffffff","backgroundColor":"#1a5fff"},"roundness":"large","hostAvatar":{"isEnabled":true},"guestAvatar":{"isEnabled":false},"hostBubbles":{"color":"#ffffff","backgroundColor":"#1e293b"},"guestBubbles":{"color":"#FFFFFF","backgroundColor":"#FF8E21"}},"general":{"font":"Open Sans","background":{"type":"Color","content":"#171923"}}},"selectedThemeTemplateId":"typebot-dark","settings":{"general":{"isBrandingEnabled":false},"metadata":{"imageUrl":"https://i.imgur.com/48TjKBb.jpg","description":"Sua opinião é fundamental para nos ajudar a melhorar!"},"typingEmulation":{"speed":300,"enabled":true,"maxDelay":1.5}},"publicId":"dgcode-pesquisa-satisfacao-whatsapp-7m64d9o","customDomain":null,"workspaceId":"clktt8c1y0001qa66zyg5tt23","resultsTablePreferences":null,"isArchived":false,"isClosed":false} \ No newline at end of file +{"id":"l27ft2bq9a7tke15i7m64d9o","version":"3","createdAt":"2023-08-04T17:27:18.072Z","updatedAt":"2023-08-20T13:35:33.073Z","icon":null,"name":"[Dgcode] [whatsapp] Pesquisa Satisfacao","folderId":"cll1fzkfy0008pa65kgz3tm86","groups":[{"id":"c76ucoughhenpernmadu7ibg","title":"Start","blocks":[{"id":"qn40kjwtw1he3l1bujt3bnje","type":"start","label":"Start","groupId":"c76ucoughhenpernmadu7ibg","outgoingEdgeId":"aovnigvk665gzhyzg7bxhvn0"}],"graphCoordinates":{"x":-126.43,"y":220.29}},{"id":"nog2woqmvhssnnjlcpwd41k5","title":"Apresentação","blocks":[{"id":"potdr8jwrn6mnkjipynqjmhh","type":"Set variable","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"type":"Random ID","variableId":"vsu5or5sxes9lyuhsgcl3cuyd"}},{"id":"mcpyoq8x28bnwp23g7h1dbc1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Olá! {{pushName}} Bem-vindo(a) à nossa "},{"bold":true,"text":"pesquisa de satisfação"},{"text":"."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o0731ch0epj2vm2c5aoxyvw1","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Meu nome é "},{"bold":true,"text":"🤖 Mike"},{"text":", estou aqui para ouvir sua opinião e experiência com nossos serviços."}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"twx683ok814enh3bwlaexe0t","type":"Wait","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"secondsToWaitFor":"5"}},{"id":"hgqbj5kmosz64cb435xqh0am","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é fundamental para nos ajudar a melhorar!"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"cbvgdo0jknjyzmvwe6o614ni","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Vamos começar?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"vpj58atr9o534tjhhu0l0t0b","type":"Wait","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"secondsToWaitFor":"5"}},{"id":"nmhkn4jod3evk08tbq5vw3s3","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual o seu nome?"}]}]},"groupId":"nog2woqmvhssnnjlcpwd41k5"},{"id":"o8ijci5gdfsp6fpv07kwh8br","type":"text input","groupId":"nog2woqmvhssnnjlcpwd41k5","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o seu nome"},"variableId":"vo40px5r6wg9vhs9fixd45kzn"},"outgoingEdgeId":"vwx6ofz1ur8maxcbw8fk66x9"}],"graphCoordinates":{"x":771.26,"y":213}},{"id":"j5co2kcotxafuxhzlj7u0qnn","title":"Qual seu email?","blocks":[{"id":"he1367t9ssao735kidd86mna","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, agora me informe seu endereço de email?"}]}]},"groupId":"j5co2kcotxafuxhzlj7u0qnn"},{"id":"qb8nwfs52g168tmnvp257b44","type":"email input","groupId":"j5co2kcotxafuxhzlj7u0qnn","options":{"labels":{"button":"Enviar","placeholder":"Digite o seu email"},"variableId":"vr75l1drc5uoxvisje0hio5ph","retryMessageContent":"Email incorreto!"},"outgoingEdgeId":"v53mvhejcapb4a1zq98swq5b"}],"graphCoordinates":{"x":1236.92,"y":204.84}},{"id":"wtd0o382phaji7i7u2n8pody","title":"Pergunta 1","blocks":[{"id":"zr69lw3bcmmkgahqq8og7shw","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, qual é o seu nível de satisfação geral com os serviços que nossa empresa fornece?"}]}]},"groupId":"wtd0o382phaji7i7u2n8pody"},{"id":"ku0zpu43cbbnd7y0ai71ptde","type":"rating input","groupId":"wtd0o382phaji7i7u2n8pody","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vbfl3sqze2wzicn9l1n9ckjs4"},"outgoingEdgeId":"ed1x8zan90zvrpo9xk9moroe"}],"graphCoordinates":{"x":1692.4,"y":194.19}},{"id":"ylerbfc1l2o62j68g8ghegxt","title":"Pergunta 2","blocks":[{"id":"l19jgtpln9al473dudr0gbzn","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, em que medida nossa empresa atendeu às suas expectativas em termos de qualidade do serviço prestado?"}]}]},"groupId":"ylerbfc1l2o62j68g8ghegxt"},{"id":"kfxuc6p58cdzy1xcyp4i4ra7","type":"rating input","groupId":"ylerbfc1l2o62j68g8ghegxt","options":{"labels":{"button":"Send"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vkgl2bfdbyms1dyc1s6efx678"},"outgoingEdgeId":"iy61ajcfl6ubbj7zghxeu6f7"}],"graphCoordinates":{"x":2156.14,"y":190.76}},{"id":"lbieknd0qp42pogsby5l82ww","title":"Pergunta 3","blocks":[{"id":"y43s12dnoxh772c9o3pmnhxf","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você teve alguma dificuldade em se comunicar com nossa equipe de suporte ao cliente?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"lbieknd0qp42pogsby5l82ww"},{"id":"fb6ckchqp8vx9ypig07we6q4","type":"text input","groupId":"lbieknd0qp42pogsby5l82ww","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"b538q1mt18l6oddo397nh1m4","type":"Condition","items":[{"id":"dwhc3ptqvktlgfvl17xg79s5","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"w6ao5pi6wt0966tobkned56m"},{"id":"cod3tkt16ry8ixm5u7rwxzm9","type":1,"blockId":"b538q1mt18l6oddo397nh1m4","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vzhsu0uc4suqoz38kv3q891ma","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"wlfmh2g3j5avj75sa9q6rsab"}],"groupId":"lbieknd0qp42pogsby5l82ww","outgoingEdgeId":"ehcwqdrkc4025pui2y1s9390"}],"graphCoordinates":{"x":2605.34,"y":189.93}},{"id":"qzhp25b9f2lvt4yeniqvjkav","title":"Pergunta 4","blocks":[{"id":"pos7njae2r35r29kcbyxtz2j","type":"text","content":{"richText":[{"type":"p","children":[{"text":"{{name}}, por favor, descreva o problema para que possamos melhorar."}]}]},"groupId":"qzhp25b9f2lvt4yeniqvjkav"},{"id":"ce2eodve0e4f2rubk4wv5jf1","type":"text input","groupId":"qzhp25b9f2lvt4yeniqvjkav","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Descreva o problema"},"variableId":"vd6fm2i9shcdjz8bhhwbsdh6t"},"outgoingEdgeId":"i11xudmpsb1tbsss7qoge6cm"}],"graphCoordinates":{"x":3041.23,"y":187.11}},{"id":"c8kh8eee1m3wyy372v4n6m1i","title":"Pergunta 5","blocks":[{"id":"txqi87lwinpa0p5of0xmqxu6","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Em uma escala de 0 a 10, como você avalia a capacidade da nossa empresa de cumprir os prazos acordados?"}]}]},"groupId":"c8kh8eee1m3wyy372v4n6m1i"},{"id":"mg2tmcmwnx3tap0hs4b7e0la","type":"rating input","groupId":"c8kh8eee1m3wyy372v4n6m1i","options":{"labels":{"button":"Enviar"},"length":10,"buttonType":"Numbers","customIcon":{"isEnabled":false},"variableId":"vz6lvahwo15dosvckdtkxduly"},"outgoingEdgeId":"c9nrzzcxt8w4dgk2sfez53n5"}],"graphCoordinates":{"x":3501.8,"y":179.58}},{"id":"tn8bcyughy9dsxhmjngrosvj","title":"Pergunta 6","blocks":[{"id":"aema350m33n9dljopcsxn8q5","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Você recomendaria nossos serviços para outras pessoas ou empresas?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"tn8bcyughy9dsxhmjngrosvj"},{"id":"wk4bkxbxcfu9skrzn8p8077u","type":"text input","groupId":"tn8bcyughy9dsxhmjngrosvj","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"n3j2dxaalkljl020o0o61ef9","type":"Condition","items":[{"id":"ifhm8cj8lsulhrarnfda2oal","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"yu9762ttf5jn3bmhd6uzrsv8"},{"id":"gxp6j3ouga4r0t8364tn8axs","type":1,"blockId":"n3j2dxaalkljl020o0o61ef9","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vndjnalmnb3ez9beeon5tzrgq","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"ji1y2o1hldhemto0ymwou09c"}],"groupId":"tn8bcyughy9dsxhmjngrosvj","outgoingEdgeId":"d3u83fikqplfy9ntva3sm7eg"}],"graphCoordinates":{"x":3926.41,"y":186.15}},{"id":"nzkhdw3hdv550aepsxvk2a0u","title":"Pergunta 7","blocks":[{"id":"io90onrpfrokejgkps94r3dj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Que pena {{name}}, por gentileza, nos conte o motivo?"}]}]},"groupId":"nzkhdw3hdv550aepsxvk2a0u"},{"id":"dj7dbgyjqk0a5u3jn6kzykb2","type":"text input","groupId":"nzkhdw3hdv550aepsxvk2a0u","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Digite o motivo"},"variableId":"vept0w6tr0w7eyyi52hgq1r3c"},"outgoingEdgeId":"k7vrrf5cfxopvmhsbf35bt3m"}],"graphCoordinates":{"x":4352.64,"y":194.04}},{"id":"jdz9w8vrz09vefk4wqrf0vwl","title":"Pergunta 8","blocks":[{"id":"hndzyb58fqxudykajr22skla","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Existe alguma sugestão que você gostaria de nos dar para melhorar nossos serviços?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},{"id":"ol9l8fdb3q65auykrn383q6d","type":"text input","groupId":"jdz9w8vrz09vefk4wqrf0vwl","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Responda com uma das opções"},"variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"zderh9hqjkpuz58p79szfa1i","type":"Condition","items":[{"id":"lur26nqa8dv7m4jmmljpyyf1","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"x2fzu1uuukp9cgmdzecp7mgk"},{"id":"aoj7e49zimwxng4o7bd6u00s","type":1,"blockId":"zderh9hqjkpuz58p79szfa1i","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vy5it60mewmth7mayzhlgmzf0","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"mb1fg83gijikrafud2ml6zbn"}],"groupId":"jdz9w8vrz09vefk4wqrf0vwl","outgoingEdgeId":"amyrx4i2rm3cjksym5zvwd50"}],"graphCoordinates":{"x":4768.69,"y":201.49}},{"id":"c4k1ftb4rbynkb01ulwuh4qh","title":"Pergunta 9","blocks":[{"id":"jqn5de3i29ygjyf6usbj117t","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Qual seria a sua sugestão?"}]}]},"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},{"id":"wfucksh3yaeq21l7mnlnsx75","type":"text input","groupId":"c4k1ftb4rbynkb01ulwuh4qh","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua sugestão"},"variableId":"vhygxyvhu5l6r2uws1cbthmxm"},"outgoingEdgeId":"u8c55of7l95fnz25gf7swt1m"}],"graphCoordinates":{"x":5233.77,"y":205.27}},{"id":"vvyooiddvdbon0t21bvzdr7q","title":"Finalização","blocks":[{"id":"efk089lhks1ev4khy38caner","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Então {{name}}, agradecemos muito por dedicar um tempo para nos fornecer seu feedback."}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"pvu3g8vpqdi3aecu2u0in2d0","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Sua opinião é muito importante para nós, e trabalharemos arduamente para melhorar ainda mais nossos serviços!"}]}]},"groupId":"vvyooiddvdbon0t21bvzdr7q"},{"id":"wqe9r1ivjf0ikubqichufzsg","type":"Webhook","groupId":"vvyooiddvdbon0t21bvzdr7q","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[]},"webhookId":"i3g1959ev6fl9s61ir8hn1we"}],"graphCoordinates":{"x":7067.06,"y":231.55}},{"id":"ffm0s2y4head3auw808hwfnx","title":"Retorna Pergunta 3","blocks":[{"id":"ox70407atqtf1kwrszis4cix","type":"Set variable","groupId":"ffm0s2y4head3auw808hwfnx","options":{"type":"Empty","variableId":"vzhsu0uc4suqoz38kv3q891ma"}},{"id":"bcwkrcxtsc8drzwynb2igu0g","type":"Jump","groupId":"ffm0s2y4head3auw808hwfnx","options":{"groupId":"lbieknd0qp42pogsby5l82ww"}}],"graphCoordinates":{"x":3040.8,"y":772.28}},{"id":"cf8r0wx0sgw6c9v79ebja1tj","title":"Retorna Pergunta 6","blocks":[{"id":"e02yfpbpj298m1q9y4tb905i","type":"Set variable","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"type":"Empty","variableId":"vndjnalmnb3ez9beeon5tzrgq"}},{"id":"wjfe41oxiik0jgwcye7sczeu","type":"Jump","groupId":"cf8r0wx0sgw6c9v79ebja1tj","options":{"groupId":"tn8bcyughy9dsxhmjngrosvj"}}],"graphCoordinates":{"x":4360.16,"y":732.74}},{"id":"b7zfnwcxvu28s98ii03isdae","title":"Retorna Pergunta 8","blocks":[{"id":"j1xmpy60ggf162ej9a0rti4f","type":"Set variable","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"type":"Empty","variableId":"vy5it60mewmth7mayzhlgmzf0"}},{"id":"lk06yb9dvrctn2u9tx35n12c","type":"Jump","groupId":"b7zfnwcxvu28s98ii03isdae","options":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"}}],"graphCoordinates":{"x":5213.21,"y":778}},{"id":"z0idhsnqisrd695z0j1tnqvw","title":"Retorna Pergunta 10","blocks":[{"id":"gs96ig682082mj4igcjjuh76","type":"Set variable","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"type":"Empty","variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"tihlp1xm8mvpdm3d0dqkwwx6","type":"Jump","groupId":"z0idhsnqisrd695z0j1tnqvw","options":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"}}],"graphCoordinates":{"x":6100.86,"y":819.65}},{"id":"qsrkmfsr04kayulair47gmn0","title":"Gera QRCODE pix","blocks":[{"id":"qs1uxqm8jqla9uui43ofms65","type":"Webhook","groupId":"qsrkmfsr04kayulair47gmn0","options":{"isCustomBody":true,"isAdvancedConfig":true,"variablesForTest":[],"responseVariableMapping":[{"id":"gcia6kdba4yydt14klsg8h6x","bodyPath":"data.qrcode_base64","variableId":"vamn8ortov9nk1y04vczo375h"}]},"webhookId":"ajx8mv7trd50mbv2uj6fr3x5"},{"id":"sz447ty7t4vreto9bf07h52i","type":"Set variable","groupId":"qsrkmfsr04kayulair47gmn0","options":{"type":"Custom","variableId":"vamn8ortov9nk1y04vczo375h","expressionToEvaluate":"if({{remoteJid}}){\n return {{qrcode}}.replace('data:image/png;base64,', ''); \n}else{\n return {{qrcode}}\n}\n"}},{"id":"c3wp5ic2wx9emj6kkii42xpj","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Aqui está qrcode para sua contribuição de R$ {{question11}}, caso tenha dificuldade na leitura utilize a nossa chave:"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"Telefone: 7499879409"}]},{"type":"p","children":[{"text":"Em nome de: Davidson Oliveira Gomes"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"jncggap4fivalzgntw3bfaom","type":"image","content":{"url":"{{qrcode}}"},"groupId":"qsrkmfsr04kayulair47gmn0"},{"id":"chiz9utw18jvui4c2r0vsiqp","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito obrigado pela sua contribuição!"}]}]},"groupId":"qsrkmfsr04kayulair47gmn0","outgoingEdgeId":"cwlt91vwhr7gvgx0qx2mnxtr"}],"graphCoordinates":{"x":6607.75,"y":229.53}},{"id":"cs5kjnrcsh4bjiuvwf99agho","title":"Pergunta 10","blocks":[{"id":"axpk3aoauusbiy8av70fc2fo","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Gostaria de fazer uma contribuição?"}]},{"type":"p","children":[{"text":""}]},{"type":"p","children":[{"text":"1 - Sim"}]},{"type":"p","children":[{"text":"2 - Não"}]}]},"groupId":"cs5kjnrcsh4bjiuvwf99agho"},{"id":"q136n37ja1g5dyhdeisur4rg","type":"text input","groupId":"cs5kjnrcsh4bjiuvwf99agho","options":{"isLong":false,"labels":{"button":"Enviar","placeholder":"Deixe sua resposta"},"variableId":"vx6p4ivk4mnssvbhl30c5zng9"}},{"id":"xza6e0p4hgkfz1wvwcjss48s","type":"Condition","items":[{"id":"m5mvt5ecw81eevl428n56aji","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"rln6ido55pzqyr9ihqp3r0oe","value":"^([Ss][IiÍí][Mm]|1)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"fe1wk4fc1xzt7mefasb2qzqz"},{"id":"bpcidulg0g7v8pwh3w9my880","type":1,"blockId":"xza6e0p4hgkfz1wvwcjss48s","content":{"comparisons":[{"id":"n0dm7n4vyowa9bftkmu0ypud","value":"^([Nn][AaÃã][Oo]|2)$","variableId":"vx6p4ivk4mnssvbhl30c5zng9","comparisonOperator":"Matches regex"}],"logicalOperator":"OR"},"outgoingEdgeId":"xg1zkpvob8ilx2r8p0kv604d"}],"groupId":"cs5kjnrcsh4bjiuvwf99agho","outgoingEdgeId":"o746eh96sq2j7juionfql73t"}],"graphCoordinates":{"x":5708.94,"y":210.9}},{"id":"tq60r6azxrmn17b4y7mjovf5","title":"Pergunta 11","blocks":[{"id":"o5fspfge731wt6m781nzjsll","type":"text","content":{"richText":[{"type":"p","children":[{"text":"Muito bem {{name}}, quanto você deseja contribuir?"}]}]},"groupId":"tq60r6azxrmn17b4y7mjovf5"},{"id":"khncvmg5fcjsmu8tlmf8in6m","type":"number input","groupId":"tq60r6azxrmn17b4y7mjovf5","options":{"max":5000,"min":1,"step":1,"labels":{"button":"Enviar","placeholder":"Digite um numero"},"variableId":"vhoqah2c0blbx92bfmd4gjnyx"},"outgoingEdgeId":"ns2kch8n15uklzwf8kn4m0lb"}],"graphCoordinates":{"x":6158.94,"y":224.91}},{"id":"h0svx6gyzgjsclr9hbpo04v6","title":"Configurações Iniciais","blocks":[{"id":"na4zglpatkg8ejqcap8lcv69","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vp1ask55v2r58ukom5lek5hej","expressionToEvaluate":"https://d715-45-39-187-135.ngrok-free.app"}},{"id":"t2bdxy8x8fsn29yijk02ti43","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vtsldvs2u8ui93tktazy77djw","expressionToEvaluate":"0f1c6e17-5a6a-4989-8c12-a7e7350870fe"}},{"id":"rt5h0lk6jaoh5hzag0s5hidd","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vkg1qlinovziltaloqhso2cw7","expressionToEvaluate":"https://pix.dgcode.com.br"}},{"id":"mh758b8y8288t56s6wz73mht","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vpjyy2e2ha6mu5x10q0nowuz3","expressionToEvaluate":"Davidson Oliveira Gomes"}},{"id":"ri9kv80djsej7r51m8xfjhuk","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vicsm3nkvhssvfhgss2xce2ad","expressionToEvaluate":"Telefone"}},{"id":"ye4teva02mnxph0rvfszdnsn","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vlmflx32cjlz457h0uzdi706g","expressionToEvaluate":"74999879409"}},{"id":"hfz4hqzfe6wgje96ezb5kann","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"veesfw943copg17w2qzdln9be","expressionToEvaluate":"Irece"}},{"id":"nd3yk369k7j73kws6exos0jw","type":"Set variable","groupId":"h0svx6gyzgjsclr9hbpo04v6","options":{"variableId":"vavwvk4wgst506zdioplg4u8p","expressionToEvaluate":"TypeBot"},"outgoingEdgeId":"mb90csrzzep8qz2opcxmw736"}],"graphCoordinates":{"x":312.08,"y":218.28}}],"variables":[{"id":"vo40px5r6wg9vhs9fixd45kzn","name":"name"},{"id":"vr75l1drc5uoxvisje0hio5ph","name":"email"},{"id":"vzhsu0uc4suqoz38kv3q891ma","name":"question3"},{"id":"vbfl3sqze2wzicn9l1n9ckjs4","name":"question1"},{"id":"vkgl2bfdbyms1dyc1s6efx678","name":"question2"},{"id":"vd6fm2i9shcdjz8bhhwbsdh6t","name":"question4"},{"id":"vz6lvahwo15dosvckdtkxduly","name":"question5"},{"id":"vndjnalmnb3ez9beeon5tzrgq","name":"question6"},{"id":"vept0w6tr0w7eyyi52hgq1r3c","name":"question7"},{"id":"vy5it60mewmth7mayzhlgmzf0","name":"question8"},{"id":"vhygxyvhu5l6r2uws1cbthmxm","name":"question9"},{"id":"vrdwfo2lpoei2fzlzazh4pp61","name":"pushName"},{"id":"vz1uq7t77aivpi5crwy6ifact","name":"remoteJid"},{"id":"vsu5or5sxes9lyuhsgcl3cuyd","name":"ID"},{"id":"vamn8ortov9nk1y04vczo375h","name":"qrcode"},{"id":"vx6p4ivk4mnssvbhl30c5zng9","name":"question10"},{"id":"vhoqah2c0blbx92bfmd4gjnyx","name":"question11"},{"id":"vpjyy2e2ha6mu5x10q0nowuz3","name":"me"},{"id":"vicsm3nkvhssvfhgss2xce2ad","name":"typePIX"},{"id":"vavwvk4wgst506zdioplg4u8p","name":"reference"},{"id":"vlmflx32cjlz457h0uzdi706g","name":"keyPIX"},{"id":"vkg1qlinovziltaloqhso2cw7","name":"apiURL"},{"id":"veesfw943copg17w2qzdln9be","name":"city"},{"id":"vp1ask55v2r58ukom5lek5hej","name":"evolutionURL"},{"id":"vtsldvs2u8ui93tktazy77djw","name":"evolutionToken"},{"id":"vpoyfwgfw4tbt4l4iy4homfoq","name":"instanceName"}],"edges":[{"id":"w6ao5pi6wt0966tobkned56m","to":{"groupId":"qzhp25b9f2lvt4yeniqvjkav"},"from":{"itemId":"dwhc3ptqvktlgfvl17xg79s5","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"wlfmh2g3j5avj75sa9q6rsab","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"itemId":"cod3tkt16ry8ixm5u7rwxzm9","blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"yu9762ttf5jn3bmhd6uzrsv8","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"itemId":"ifhm8cj8lsulhrarnfda2oal","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ji1y2o1hldhemto0ymwou09c","to":{"groupId":"nzkhdw3hdv550aepsxvk2a0u"},"from":{"itemId":"gxp6j3ouga4r0t8364tn8axs","blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"x2fzu1uuukp9cgmdzecp7mgk","to":{"groupId":"c4k1ftb4rbynkb01ulwuh4qh"},"from":{"itemId":"lur26nqa8dv7m4jmmljpyyf1","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"d3u83fikqplfy9ntva3sm7eg","to":{"groupId":"cf8r0wx0sgw6c9v79ebja1tj"},"from":{"blockId":"n3j2dxaalkljl020o0o61ef9","groupId":"tn8bcyughy9dsxhmjngrosvj"}},{"id":"ehcwqdrkc4025pui2y1s9390","to":{"groupId":"ffm0s2y4head3auw808hwfnx"},"from":{"blockId":"b538q1mt18l6oddo397nh1m4","groupId":"lbieknd0qp42pogsby5l82ww"}},{"id":"mb1fg83gijikrafud2ml6zbn","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"itemId":"aoj7e49zimwxng4o7bd6u00s","blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"amyrx4i2rm3cjksym5zvwd50","to":{"groupId":"b7zfnwcxvu28s98ii03isdae"},"from":{"blockId":"zderh9hqjkpuz58p79szfa1i","groupId":"jdz9w8vrz09vefk4wqrf0vwl"}},{"id":"o746eh96sq2j7juionfql73t","to":{"groupId":"z0idhsnqisrd695z0j1tnqvw"},"from":{"blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"fe1wk4fc1xzt7mefasb2qzqz","to":{"groupId":"tq60r6azxrmn17b4y7mjovf5"},"from":{"itemId":"m5mvt5ecw81eevl428n56aji","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"xg1zkpvob8ilx2r8p0kv604d","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"itemId":"bpcidulg0g7v8pwh3w9my880","blockId":"xza6e0p4hgkfz1wvwcjss48s","groupId":"cs5kjnrcsh4bjiuvwf99agho"}},{"id":"cwlt91vwhr7gvgx0qx2mnxtr","to":{"groupId":"vvyooiddvdbon0t21bvzdr7q"},"from":{"blockId":"chiz9utw18jvui4c2r0vsiqp","groupId":"qsrkmfsr04kayulair47gmn0"}},{"id":"aovnigvk665gzhyzg7bxhvn0","to":{"groupId":"h0svx6gyzgjsclr9hbpo04v6"},"from":{"blockId":"qn40kjwtw1he3l1bujt3bnje","groupId":"c76ucoughhenpernmadu7ibg"}},{"id":"mb90csrzzep8qz2opcxmw736","to":{"groupId":"nog2woqmvhssnnjlcpwd41k5"},"from":{"blockId":"nd3yk369k7j73kws6exos0jw","groupId":"h0svx6gyzgjsclr9hbpo04v6"}},{"id":"vwx6ofz1ur8maxcbw8fk66x9","to":{"groupId":"j5co2kcotxafuxhzlj7u0qnn"},"from":{"blockId":"o8ijci5gdfsp6fpv07kwh8br","groupId":"nog2woqmvhssnnjlcpwd41k5"}},{"id":"v53mvhejcapb4a1zq98swq5b","to":{"groupId":"wtd0o382phaji7i7u2n8pody"},"from":{"blockId":"qb8nwfs52g168tmnvp257b44","groupId":"j5co2kcotxafuxhzlj7u0qnn"}},{"id":"ed1x8zan90zvrpo9xk9moroe","to":{"groupId":"ylerbfc1l2o62j68g8ghegxt"},"from":{"blockId":"ku0zpu43cbbnd7y0ai71ptde","groupId":"wtd0o382phaji7i7u2n8pody"}},{"id":"iy61ajcfl6ubbj7zghxeu6f7","to":{"groupId":"lbieknd0qp42pogsby5l82ww"},"from":{"blockId":"kfxuc6p58cdzy1xcyp4i4ra7","groupId":"ylerbfc1l2o62j68g8ghegxt"}},{"id":"i11xudmpsb1tbsss7qoge6cm","to":{"groupId":"c8kh8eee1m3wyy372v4n6m1i"},"from":{"blockId":"ce2eodve0e4f2rubk4wv5jf1","groupId":"qzhp25b9f2lvt4yeniqvjkav"}},{"id":"c9nrzzcxt8w4dgk2sfez53n5","to":{"groupId":"tn8bcyughy9dsxhmjngrosvj"},"from":{"blockId":"mg2tmcmwnx3tap0hs4b7e0la","groupId":"c8kh8eee1m3wyy372v4n6m1i"}},{"id":"k7vrrf5cfxopvmhsbf35bt3m","to":{"groupId":"jdz9w8vrz09vefk4wqrf0vwl"},"from":{"blockId":"dj7dbgyjqk0a5u3jn6kzykb2","groupId":"nzkhdw3hdv550aepsxvk2a0u"}},{"id":"u8c55of7l95fnz25gf7swt1m","to":{"groupId":"cs5kjnrcsh4bjiuvwf99agho"},"from":{"blockId":"wfucksh3yaeq21l7mnlnsx75","groupId":"c4k1ftb4rbynkb01ulwuh4qh"}},{"id":"ns2kch8n15uklzwf8kn4m0lb","to":{"groupId":"qsrkmfsr04kayulair47gmn0"},"from":{"blockId":"khncvmg5fcjsmu8tlmf8in6m","groupId":"tq60r6azxrmn17b4y7mjovf5"}}],"theme":{"chat":{"inputs":{"color":"#ffffff","backgroundColor":"#1e293b","placeholderColor":"#9095A0"},"buttons":{"color":"#ffffff","backgroundColor":"#1a5fff"},"roundness":"large","hostAvatar":{"isEnabled":true},"guestAvatar":{"isEnabled":false},"hostBubbles":{"color":"#ffffff","backgroundColor":"#1e293b"},"guestBubbles":{"color":"#FFFFFF","backgroundColor":"#FF8E21"}},"general":{"font":"Open Sans","background":{"type":"Color","content":"#171923"}}},"selectedThemeTemplateId":"typebot-dark","settings":{"general":{"isBrandingEnabled":false},"metadata":{"imageUrl":"https://i.imgur.com/48TjKBb.jpg","description":"Sua opinião é fundamental para nos ajudar a melhorar!"},"typingEmulation":{"speed":300,"enabled":true,"maxDelay":1.5}},"publicId":"dgcode-pesquisa-satisfacao-whatsapp-7m64d9o","customDomain":null,"workspaceId":"clktt8c1y0001qa66zyg5tt23","resultsTablePreferences":null,"isArchived":false,"isClosed":false} \ No newline at end of file diff --git a/package.json b/package.json index 6f92aaf3..c7fbc0ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.5.0", + "version": "1.5.1", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 4f28dbd5..f68c4108 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -166,17 +166,17 @@ export class ConfigService { return { SERVER: { TYPE: process.env.SERVER_TYPE as 'http' | 'https', - PORT: Number.parseInt(process.env.SERVER_PORT), + PORT: Number.parseInt(process.env.SERVER_PORT) || 8080, URL: process.env.SERVER_URL, }, CORS: { - ORIGIN: process.env.CORS_ORIGIN.split(','), - METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[], + ORIGIN: process.env.CORS_ORIGIN.split(',') || ['*'], + METHODS: (process.env.CORS_METHODS.split(',') as HttpMethods[]) || ['POST', 'GET', 'PUT', 'DELETE'], CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true', }, SSL_CONF: { - PRIVKEY: process.env?.SSL_CONF_PRIVKEY, - FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN, + PRIVKEY: process.env?.SSL_CONF_PRIVKEY || '', + FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN || '', }, STORE: { MESSAGES: process.env?.STORE_MESSAGES === 'true', @@ -195,8 +195,8 @@ export class ConfigService { }, DATABASE: { CONNECTION: { - URI: process.env.DATABASE_CONNECTION_URI, - DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME, + URI: process.env.DATABASE_CONNECTION_URI || '', + DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution', }, ENABLED: process.env?.DATABASE_ENABLED === 'true', SAVE_DATA: { @@ -209,18 +209,27 @@ export class ConfigService { }, REDIS: { ENABLED: process.env?.REDIS_ENABLED === 'true', - URI: process.env.REDIS_URI, - PREFIX_KEY: process.env.REDIS_PREFIX_KEY, + URI: process.env.REDIS_URI || '', + PREFIX_KEY: process.env.REDIS_PREFIX_KEY || 'evolution', }, RABBITMQ: { ENABLED: process.env?.RABBITMQ_ENABLED === 'true', - URI: process.env.RABBITMQ_URI, + URI: process.env.RABBITMQ_URI || '', }, WEBSOCKET: { ENABLED: process.env?.WEBSOCKET_ENABLED === 'true', }, LOG: { - LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], + LEVEL: (process.env?.LOG_LEVEL.split(',') as LogLevel[]) || [ + 'ERROR', + 'WARN', + 'DEBUG', + 'INFO', + 'LOG', + 'VERBOSE', + 'DARK', + 'WEBHOOKS', + ], COLOR: process.env?.LOG_COLOR === 'true', BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', }, @@ -229,7 +238,7 @@ export class ConfigService { : Number.parseInt(process.env.DEL_INSTANCE) || false, WEBHOOK: { GLOBAL: { - URL: process.env?.WEBHOOK_GLOBAL_URL, + URL: process.env?.WEBHOOK_GLOBAL_URL || '', ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true', WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true', }, @@ -266,16 +275,16 @@ export class ConfigService { COLOR: process.env.QRCODE_COLOR || '#198754', }, AUTHENTICATION: { - TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', + TYPE: process.env.AUTHENTICATION_TYPE as 'apikey', API_KEY: { - KEY: process.env.AUTHENTICATION_API_KEY, + KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ', }, EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', JWT: { EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) : 3600, - SECRET: process.env.AUTHENTICATION_JWT_SECRET, + SECRET: process.env.AUTHENTICATION_JWT_SECRET || 'L=0YWt]b2w[WF>#>:&E`', }, }, }; diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index ebfed66a..2875cf2b 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -985,9 +985,10 @@ export const typebotSchema: JSONSchema7 = { expire: { type: 'integer' }, delay_message: { type: 'integer' }, unknown_message: { type: 'string' }, + listening_from_me: { type: 'boolean', enum: [true, false] }, }, - required: ['enabled', 'url', 'typebot', 'expire'], - ...isNotEmpty('enabled', 'url', 'typebot', 'expire'), + required: ['enabled', 'url', 'typebot', 'expire', 'delay_message', 'unknown_message', 'listening_from_me'], + ...isNotEmpty('enabled', 'url', 'typebot', 'expire', 'delay_message', 'unknown_message', 'listening_from_me'), }; export const typebotStatusSchema: JSONSchema7 = { diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 2a904761..1bcc868d 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -67,6 +67,7 @@ export class InstanceController { typebot_keyword_finish, typebot_delay_message, typebot_unknown_message, + typebot_listening_from_me, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -247,6 +248,7 @@ export class InstanceController { keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, + listening_from_me: typebot_listening_from_me, }); } catch (error) { this.logger.log(error); @@ -304,6 +306,7 @@ export class InstanceController { keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, + listening_from_me: typebot_listening_from_me, }, settings, qrcode: getQrcode, @@ -396,6 +399,7 @@ export class InstanceController { keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, + listening_from_me: typebot_listening_from_me, }, settings, chatwoot: { diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index cffe0303..7807d1a5 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -28,6 +28,7 @@ export class InstanceDto { typebot_keyword_finish?: string; typebot_delay_message?: number; typebot_unknown_message?: string; + typebot_listening_from_me?: boolean; proxy_enabled?: boolean; proxy_proxy?: string; } diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts index cda5ae58..6e9c6111 100644 --- a/src/whatsapp/dto/typebot.dto.ts +++ b/src/whatsapp/dto/typebot.dto.ts @@ -14,5 +14,6 @@ export class TypebotDto { keyword_finish?: string; delay_message?: number; unknown_message?: string; + listening_from_me?: boolean; sessions?: Session[]; } diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts index 5b005294..28135ebd 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -19,6 +19,7 @@ export class TypebotRaw { keyword_finish?: string; delay_message?: number; unknown_message?: string; + listening_from_me?: boolean; sessions?: Session[]; } @@ -31,6 +32,7 @@ const typebotSchema = new Schema({ keyword_finish: { type: String, required: true }, delay_message: { type: Number, required: true }, unknown_message: { type: String, required: true }, + listening_from_me: { type: Boolean, required: true }, sessions: [ { remoteJid: { type: String, required: true }, diff --git a/src/whatsapp/services/chamaai.service.ts b/src/whatsapp/services/chamaai.service.ts index ffa2d5a6..adfea803 100644 --- a/src/whatsapp/services/chamaai.service.ts +++ b/src/whatsapp/services/chamaai.service.ts @@ -151,8 +151,6 @@ export class ChamaaiService { }, }); - console.log(request.data); - const answer = request.data?.answer; const type = request.data?.type; diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 4dc9215c..abe48150 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1444,16 +1444,16 @@ export class ChatwootService { await this.createBotMessage(instance, msgStatus, 'incoming'); } - if (event === 'connection.update') { - this.logger.verbose('event connection.update'); + // if (event === 'connection.update') { + // this.logger.verbose('event connection.update'); - if (body.status === 'open') { - const msgConnection = `🚀 Connection successfully established!`; + // if (body.status === 'open') { + // const msgConnection = `🚀 Connection successfully established!`; - this.logger.verbose('send message to chatwoot'); - await this.createBotMessage(instance, msgConnection, 'incoming'); - } - } + // this.logger.verbose('send message to chatwoot'); + // await this.createBotMessage(instance, msgConnection, 'incoming'); + // } + // } if (event === 'qrcode.updated') { this.logger.verbose('event qrcode.updated'); diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 039a5f29..4c386180 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -220,6 +220,11 @@ export class WAMonitoringService { execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'chamaai', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`); + execSync(`rm -rf ${join(STORE_DIR, 'websocket', instanceName + '*')}`); execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); return; diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 1128bb0d..6ebcf8b1 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -53,6 +53,7 @@ export class TypebotService { keyword_finish: findData.keyword_finish, delay_message: findData.delay_message, unknown_message: findData.unknown_message, + listening_from_me: findData.listening_from_me, sessions: findData.sessions, }; @@ -76,6 +77,7 @@ export class TypebotService { keyword_finish: findData.keyword_finish, delay_message: findData.delay_message, unknown_message: findData.unknown_message, + listening_from_me: findData.listening_from_me, sessions: findData.sessions, }; @@ -195,6 +197,7 @@ export class TypebotService { keyword_finish: data.keyword_finish, delay_message: data.delay_message, unknown_message: data.unknown_message, + listening_from_me: data.listening_from_me, sessions: data.sessions, }; @@ -354,13 +357,15 @@ export class TypebotService { } public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: MessageRaw) { - const url = (await this.find(instance)).url; - const typebot = (await this.find(instance)).typebot; - const sessions = ((await this.find(instance)).sessions as Session[]) ?? []; - const expire = (await this.find(instance)).expire; - const keyword_finish = (await this.find(instance)).keyword_finish; - const delay_message = (await this.find(instance)).delay_message; - const unknown_message = (await this.find(instance)).unknown_message; + const findTypebot = await this.find(instance); + const url = findTypebot.url; + const typebot = findTypebot.typebot; + const sessions = (findTypebot.sessions as Session[]) ?? []; + const expire = findTypebot.expire; + const keyword_finish = findTypebot.keyword_finish; + const delay_message = findTypebot.delay_message; + const unknown_message = findTypebot.unknown_message; + const listening_from_me = findTypebot.listening_from_me; const session = sessions.find((session) => session.remoteJid === remoteJid); @@ -381,6 +386,7 @@ export class TypebotService { keyword_finish: keyword_finish, delay_message: delay_message, unknown_message: unknown_message, + listening_from_me: listening_from_me, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -404,6 +410,7 @@ export class TypebotService { keyword_finish: keyword_finish, delay_message: delay_message, unknown_message: unknown_message, + listening_from_me: listening_from_me, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -428,6 +435,7 @@ export class TypebotService { keyword_finish: keyword_finish, delay_message: delay_message, unknown_message: unknown_message, + listening_from_me: listening_from_me, sessions, }; @@ -462,6 +470,7 @@ export class TypebotService { keyword_finish: keyword_finish, delay_message: delay_message, unknown_message: unknown_message, + listening_from_me: listening_from_me, sessions, }; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 445069a5..432d8075 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -519,6 +519,9 @@ export class WAStartupService { this.localTypebot.unknown_message = data?.unknown_message; this.logger.verbose(`Typebot unknown_message: ${this.localTypebot.unknown_message}`); + this.localTypebot.listening_from_me = data?.listening_from_me; + this.logger.verbose(`Typebot listening_from_me: ${this.localTypebot.listening_from_me}`); + this.localTypebot.sessions = data?.sessions; this.logger.verbose('Typebot loaded'); @@ -532,6 +535,7 @@ export class WAStartupService { this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`); this.logger.verbose(`Typebot delay_message: ${data.delay_message}`); this.logger.verbose(`Typebot unknown_message: ${data.unknown_message}`); + this.logger.verbose(`Typebot listening_from_me: ${data.listening_from_me}`); Object.assign(this.localTypebot, data); this.logger.verbose('Typebot set'); } @@ -1434,12 +1438,14 @@ export class WAStartupService { ); } - if (this.localTypebot.enabled && messageRaw.key.fromMe === false) { - await this.typebotService.sendTypebot( - { instanceName: this.instance.name }, - messageRaw.key.remoteJid, - messageRaw, - ); + if (this.localTypebot.enabled) { + if (!(this.localTypebot.listening_from_me === false && messageRaw.key.fromMe === true)) { + await this.typebotService.sendTypebot( + { instanceName: this.instance.name }, + messageRaw.key.remoteJid, + messageRaw, + ); + } } if (this.localChamaai.enabled && messageRaw.key.fromMe === false) { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 72718b65..b4020649 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -94,6 +94,7 @@ export declare namespace wa { keyword_finish?: string; delay_message?: number; unknown_message?: string; + listening_from_me?: boolean; sessions?: Session[]; }; From 10c7e81e0271c0acd87816389a015410227bc215 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 23 Aug 2023 07:54:46 -0300 Subject: [PATCH 153/177] Added webhooks for typebot events --- CHANGELOG.md | 2 ++ Docker/.env.example | 5 +++ Dockerfile | 5 +++ src/config/env.config.ts | 6 ++++ src/dev-env.yml | 11 ++++-- src/validate/validate.schema.ts | 12 +++++++ .../controllers/instance.controller.ts | 9 +++++ .../controllers/rabbitmq.controller.ts | 3 ++ .../controllers/webhook.controller.ts | 3 ++ .../controllers/websocket.controller.ts | 3 ++ src/whatsapp/services/typebot.service.ts | 34 +++++++++++++++---- src/whatsapp/types/wa.types.ts | 3 ++ 12 files changed, 87 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23129582..7b3b343e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### Feature * Added listening_from_me option in Set Typebot +* Added variables options in Start Typebot +* Added webhooks for typebot events ### Fixed diff --git a/Docker/.env.example b/Docker/.env.example index bf21a71c..69ceaf23 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -81,6 +81,11 @@ WEBHOOK_EVENTS_CONNECTION_UPDATE=true WEBHOOK_EVENTS_CALL=true # This event fires every time a new token is requested via the refresh route WEBHOOK_EVENTS_NEW_JWT_TOKEN=false +# This events is used with Typebot +WEBHOOK_EVENTS_TYPEBOT_START=false +WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false +# This event is used with Chama AI +WEBHOOK_EVENTS_CHAMA_AI_ACTION=false # Name that will be displayed on smartphone connection CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI diff --git a/Dockerfile b/Dockerfile index 3777091f..d4defe07 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,6 +84,11 @@ ENV WEBHOOK_EVENTS_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false +ENV WEBHOOK_EVENTS_TYPEBOT_START=false +ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false + +ENV WEBHOOK_EVENTS_CHAMA_AI_ACTION=false + ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI ENV CONFIG_SESSION_PHONE_NAME=chrome diff --git a/src/config/env.config.ts b/src/config/env.config.ts index f68c4108..a2255b32 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -92,6 +92,9 @@ export type EventsWebhook = { GROUP_PARTICIPANTS_UPDATE: boolean; CALL: boolean; NEW_JWT_TOKEN: boolean; + TYPEBOT_START: boolean; + TYPEBOT_CHANGE_STATUS: boolean; + CHAMA_AI_ACTION: boolean; }; export type ApiKey = { KEY: string }; @@ -264,6 +267,9 @@ export class ConfigService { GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', + TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true', + TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true', + CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true', }, }, CONFIG_SESSION_PHONE: { diff --git a/src/dev-env.yml b/src/dev-env.yml index 235ec1b7..bd9ad277 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -83,7 +83,7 @@ RABBITMQ: ENABLED: false URI: "amqp://guest:guest@localhost:5672" -WEBSOCKET: +WEBSOCKET: ENABLED: false # Global Webhook Settings @@ -120,6 +120,11 @@ WEBHOOK: CALL: true # This event fires every time a new token is requested via the refresh route NEW_JWT_TOKEN: false + # This events is used with Typebot + TYPEBOT_START: false + TYPEBOT_CHANGE_STATUS: false + # This event is used with Chama AI + CHAMA_AI_ACTION: false CONFIG_SESSION_PHONE: # Name that will be displayed on smartphone connection @@ -129,7 +134,7 @@ CONFIG_SESSION_PHONE: # Set qrcode display limit QRCODE: LIMIT: 30 - COLOR: '#198754' + COLOR: "#198754" # Defines an authentication type for the api # We recommend using the apikey because it will allow you to use a custom token, @@ -145,4 +150,4 @@ AUTHENTICATION: # Set the secret key to encrypt and decrypt your token and its expiration time. JWT: EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires - SECRET: L=0YWt]b2w[WF>#>:&E` \ No newline at end of file + SECRET: L=0YWt]b2w[WF>#>:&E` diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 2875cf2b..b8a4c0ad 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -55,6 +55,9 @@ export const instanceNameSchema: JSONSchema7 = { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ], }, }, @@ -856,6 +859,9 @@ export const webhookSchema: JSONSchema7 = { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ], }, }, @@ -927,6 +933,9 @@ export const websocketSchema: JSONSchema7 = { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ], }, }, @@ -967,6 +976,9 @@ export const rabbitmqSchema: JSONSchema7 = { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ], }, }, diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 1bcc868d..818fabf1 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -127,6 +127,9 @@ export class InstanceController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } else { newEvents = events; @@ -173,6 +176,9 @@ export class InstanceController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } else { newEvents = events; @@ -217,6 +223,9 @@ export class InstanceController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } else { newEvents = events; diff --git a/src/whatsapp/controllers/rabbitmq.controller.ts b/src/whatsapp/controllers/rabbitmq.controller.ts index 4efd1c3f..8d33ce84 100644 --- a/src/whatsapp/controllers/rabbitmq.controller.ts +++ b/src/whatsapp/controllers/rabbitmq.controller.ts @@ -40,6 +40,9 @@ export class RabbitmqController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index 5515b8cc..8201f1b5 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -48,6 +48,9 @@ export class WebhookController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } diff --git a/src/whatsapp/controllers/websocket.controller.ts b/src/whatsapp/controllers/websocket.controller.ts index fb6bea0f..5771027a 100644 --- a/src/whatsapp/controllers/websocket.controller.ts +++ b/src/whatsapp/controllers/websocket.controller.ts @@ -40,6 +40,9 @@ export class WebsocketController { 'CONNECTION_UPDATE', 'CALL', 'NEW_JWT_TOKEN', + 'TYPEBOT_START', + 'TYPEBOT_CHANGE_STATUS', + 'CHAMA_AI_ACTION', ]; } diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 6ebcf8b1..ff595c6b 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -4,6 +4,7 @@ import { Logger } from '../../config/logger.config'; import { InstanceDto } from '../dto/instance.dto'; import { Session, TypebotDto } from '../dto/typebot.dto'; import { MessageRaw } from '../models'; +import { Events } from '../types/wa.types'; import { WAMonitoringService } from './monitor.service'; export class TypebotService { @@ -83,6 +84,14 @@ export class TypebotService { this.create(instance, typebotData); + this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, { + remoteJid: remoteJid, + status: status, + url: findData.url, + typebot: findData.typebot, + session, + }); + return { typebot: { ...instance, typebot: typebotData } }; } @@ -90,6 +99,15 @@ export class TypebotService { const remoteJid = data.remoteJid; const url = data.url; const typebot = data.typebot; + const variables = data.variables; + + const prefilledVariables = { + remoteJid: remoteJid, + }; + + variables.forEach((variable) => { + prefilledVariables[variable.name] = variable.value; + }); const id = Math.floor(Math.random() * 10000000000).toString(); @@ -97,14 +115,9 @@ export class TypebotService { sessionId: id, startParams: { typebot: data.typebot, - prefilledVariables: { - remoteJid: data.remoteJid, - pushName: data.pushName, - instanceName: instance.instanceName, - }, + prefilledVariables: prefilledVariables, }, }; - console.log(reqData); const request = await axios.post(data.url + '/api/v1/sendMessage', reqData); @@ -116,6 +129,14 @@ export class TypebotService { request.data.clientSideActions, ); + this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_START, { + remoteJid: remoteJid, + url: url, + typebot: typebot, + variables: variables, + sessionId: id, + }); + return { typebot: { ...instance, @@ -123,6 +144,7 @@ export class TypebotService { url: url, remoteJid: remoteJid, typebot: typebot, + variables: variables, }, }, }; diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index b4020649..2025e7f7 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -23,6 +23,9 @@ export enum Events { GROUPS_UPDATE = 'groups.update', GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', CALL = 'call', + TYPEBOT_START = 'typebot.start', + TYPEBOT_CHANGE_STATUS = 'typebot.change-status', + CHAMA_AI_ACTION = 'chama-ai.action', } export declare namespace wa { From 706cc6f49c5547279eb1245e229a4e7fc994b4e2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 23 Aug 2023 08:15:53 -0300 Subject: [PATCH 154/177] Added webhooks for typebot events --- src/whatsapp/services/chamaai.service.ts | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/whatsapp/services/chamaai.service.ts b/src/whatsapp/services/chamaai.service.ts index adfea803..ad2a42ad 100644 --- a/src/whatsapp/services/chamaai.service.ts +++ b/src/whatsapp/services/chamaai.service.ts @@ -7,6 +7,7 @@ import { Logger } from '../../config/logger.config'; import { ChamaaiDto } from '../dto/chamaai.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ChamaaiRaw } from '../models'; +import { Events } from '../types/wa.types'; import { WAMonitoringService } from './monitor.service'; export class ChamaaiService { @@ -88,6 +89,32 @@ export class ChamaaiService { return speakingTimeInSeconds; } + private getRegexPatterns() { + const patternsToCheck = [ + '.*atend.*humano.*', + '.*falar.*com.*um.*humano.*', + '.*fala.*humano.*', + '.*atend.*humano.*', + '.*fala.*atend.*', + '.*preciso.*ajuda.*', + '.*quero.*suporte.*', + '.*preciso.*assiste.*', + '.*ajuda.*atend.*', + '.*chama.*atendente.*', + '.*suporte.*urgente.*', + '.*atend.*por.*favor.*', + '.*quero.*falar.*com.*alguém.*', + '.*falar.*com.*um.*humano.*', + '.*transfer.*humano.*', + '.*transfer.*atend.*', + '.*equipe.*humano.*', + '.*suporte.*humano.*', + ]; + + const regexPatterns = patternsToCheck.map((pattern) => new RegExp(pattern, 'iu')); + return regexPatterns; + } + public async sendChamaai(instance: InstanceDto, remoteJid: string, msg: any) { const content = this.getConversationMessage(msg.message); const msgType = msg.messageType; @@ -189,6 +216,15 @@ export class ChamaaiService { }, }); } + + if (this.getRegexPatterns().some((pattern) => pattern.test(answer))) { + this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.CHAMA_AI_ACTION, { + remoteJid: remoteJid, + message: msg, + answer: answer, + action: 'transfer', + }); + } } } } From c03919be2d2f78555affc8ef03a3d208156021ca Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 23 Aug 2023 08:58:49 -0300 Subject: [PATCH 155/177] Added ChamaAI integration --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b3b343e..5701dfb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added listening_from_me option in Set Typebot * Added variables options in Start Typebot * Added webhooks for typebot events +* Added ChamaAI integration ### Fixed From 9b72b3e332de2b74082078b0f585e93266030c45 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 25 Aug 2023 09:01:48 -0300 Subject: [PATCH 156/177] Added webhook to send errors --- CHANGELOG.md | 1 + Docker/.env.example | 2 ++ Dockerfile | 2 ++ src/config/env.config.ts | 2 ++ src/dev-env.yml | 2 ++ src/main.ts | 31 ++++++++++++++++++- src/whatsapp/guards/instance.guard.ts | 43 ++++++++++++++++----------- 7 files changed, 65 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5701dfb4..427a412b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Added variables options in Start Typebot * Added webhooks for typebot events * Added ChamaAI integration +* Added webhook to send errors ### Fixed diff --git a/Docker/.env.example b/Docker/.env.example index 69ceaf23..ef70e704 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -86,6 +86,8 @@ WEBHOOK_EVENTS_TYPEBOT_START=false WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false # This event is used with Chama AI WEBHOOK_EVENTS_CHAMA_AI_ACTION=false +# This event is used to send errors +WEBHOOK_EVENTS_ERRORS=false # Name that will be displayed on smartphone connection CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI diff --git a/Dockerfile b/Dockerfile index d4defe07..76699acb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -89,6 +89,8 @@ ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false ENV WEBHOOK_EVENTS_CHAMA_AI_ACTION=false +ENV WEBHOOK_EVENTS_ERRORS=false + ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI ENV CONFIG_SESSION_PHONE_NAME=chrome diff --git a/src/config/env.config.ts b/src/config/env.config.ts index a2255b32..fb566eaf 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -95,6 +95,7 @@ export type EventsWebhook = { TYPEBOT_START: boolean; TYPEBOT_CHANGE_STATUS: boolean; CHAMA_AI_ACTION: boolean; + ERRORS: boolean; }; export type ApiKey = { KEY: string }; @@ -270,6 +271,7 @@ export class ConfigService { TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true', TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true', CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true', + ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true', }, }, CONFIG_SESSION_PHONE: { diff --git a/src/dev-env.yml b/src/dev-env.yml index bd9ad277..624137e7 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -125,6 +125,8 @@ WEBHOOK: TYPEBOT_CHANGE_STATUS: false # This event is used with Chama AI CHAMA_AI_ACTION: false + # This event is used to send errors to the webhook + ERRORS: false CONFIG_SESSION_PHONE: # Name that will be displayed on smartphone connection diff --git a/src/main.ts b/src/main.ts index 2095bd4c..5727575c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,12 @@ import 'express-async-errors'; +import axios from 'axios'; import compression from 'compression'; import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; -import { configService, Cors, HttpServer, Rabbitmq } from './config/env.config'; +import { configService, Cors, HttpServer, Rabbitmq, Webhook } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; @@ -54,6 +55,34 @@ function bootstrap() { app.use( (err: Error, req: Request, res: Response, next: NextFunction) => { if (err) { + const webhook = configService.get('WEBHOOK'); + + if (webhook.GLOBAL.ENABLED && webhook.EVENTS.ERRORS) { + const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds + const localISOTime = new Date(Date.now() - tzoffset).toISOString(); + const now = localISOTime; + + const errorData = { + event: 'error', + data: { + error: err['error'] || 'Internal Server Error', + message: err['message'] || 'Internal Server Error', + status: err['status'] || 500, + response: { + message: err['message'] || 'Internal Server Error', + }, + }, + date_time: now, + }; + + logger.error(errorData); + + const baseURL = configService.get('WEBHOOK').GLOBAL.URL; + const httpService = axios.create({ baseURL }); + + httpService.post('', errorData); + } + return res.status(err['status'] || 500).json({ status: err['status'] || 500, error: err['error'] || 'Internal Server Error', diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 144f4d40..e5b7ebe0 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -4,31 +4,40 @@ import { join } from 'path'; import { configService, Database, Redis } from '../../config/env.config'; import { INSTANCE_DIR } from '../../config/path.config'; -import { BadRequestException, ForbiddenException, NotFoundException } from '../../exceptions'; +import { + BadRequestException, + ForbiddenException, + InternalServerErrorException, + NotFoundException, +} from '../../exceptions'; import { dbserver } from '../../libs/db.connect'; import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; async function getInstance(instanceName: string) { - const db = configService.get('DATABASE'); - const redisConf = configService.get('REDIS'); + try { + const db = configService.get('DATABASE'); + const redisConf = configService.get('REDIS'); - const exists = !!waMonitor.waInstances[instanceName]; + const exists = !!waMonitor.waInstances[instanceName]; - if (redisConf.ENABLED) { - const keyExists = await cache.keyExists(); - return exists || keyExists; + if (redisConf.ENABLED) { + const keyExists = await cache.keyExists(); + return exists || keyExists; + } + + if (db.ENABLED) { + const collection = dbserver + .getClient() + .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') + .collection(instanceName); + return exists || (await collection.find({}).toArray()).length > 0; + } + + return exists || existsSync(join(INSTANCE_DIR, instanceName)); + } catch (error) { + throw new InternalServerErrorException(error?.toString()); } - - if (db.ENABLED) { - const collection = dbserver - .getClient() - .db(db.CONNECTION.DB_PREFIX_NAME + '-instances') - .collection(instanceName); - return exists || (await collection.find({}).toArray()).length > 0; - } - - return exists || existsSync(join(INSTANCE_DIR, instanceName)); } export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) { From 54cfa67d529647b482e21da0a516523b2b8a37bd Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 25 Aug 2023 09:31:13 -0300 Subject: [PATCH 157/177] Added webhook to send errors --- Docker/.env.example | 1 + Dockerfile | 1 + src/config/env.config.ts | 2 ++ src/dev-env.yml | 1 + src/main.ts | 4 ++-- 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index ef70e704..847f6ef1 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -88,6 +88,7 @@ WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false WEBHOOK_EVENTS_CHAMA_AI_ACTION=false # This event is used to send errors WEBHOOK_EVENTS_ERRORS=false +WEBHOOK_EVENTS_ERRORS_WEBHOOK= # Name that will be displayed on smartphone connection CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI diff --git a/Dockerfile b/Dockerfile index 76699acb..6959ea30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -90,6 +90,7 @@ ENV WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false ENV WEBHOOK_EVENTS_CHAMA_AI_ACTION=false ENV WEBHOOK_EVENTS_ERRORS=false +ENV WEBHOOK_EVENTS_ERRORS_WEBHOOK= ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI ENV CONFIG_SESSION_PHONE_NAME=chrome diff --git a/src/config/env.config.ts b/src/config/env.config.ts index fb566eaf..94f67a7f 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -96,6 +96,7 @@ export type EventsWebhook = { TYPEBOT_CHANGE_STATUS: boolean; CHAMA_AI_ACTION: boolean; ERRORS: boolean; + ERRORS_WEBHOOK: string; }; export type ApiKey = { KEY: string }; @@ -272,6 +273,7 @@ export class ConfigService { TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true', CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true', ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true', + ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '', }, }, CONFIG_SESSION_PHONE: { diff --git a/src/dev-env.yml b/src/dev-env.yml index 624137e7..7f686cb1 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -127,6 +127,7 @@ WEBHOOK: CHAMA_AI_ACTION: false # This event is used to send errors to the webhook ERRORS: false + ERRORS_WEBHOOK: CONFIG_SESSION_PHONE: # Name that will be displayed on smartphone connection diff --git a/src/main.ts b/src/main.ts index 5727575c..167909b1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -57,7 +57,7 @@ function bootstrap() { if (err) { const webhook = configService.get('WEBHOOK'); - if (webhook.GLOBAL.ENABLED && webhook.EVENTS.ERRORS) { + if (webhook.EVENTS.ERRORS_WEBHOOK && webhook.EVENTS.ERRORS_WEBHOOK != '' && webhook.EVENTS.ERRORS) { const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds const localISOTime = new Date(Date.now() - tzoffset).toISOString(); const now = localISOTime; @@ -77,7 +77,7 @@ function bootstrap() { logger.error(errorData); - const baseURL = configService.get('WEBHOOK').GLOBAL.URL; + const baseURL = webhook.EVENTS.ERRORS_WEBHOOK; const httpService = axios.create({ baseURL }); httpService.post('', errorData); From bbc2b8a3960e89e65d506f2f59429481779b9dfc Mon Sep 17 00:00:00 2001 From: AdsonCicilioti Date: Sat, 26 Aug 2023 00:29:58 -0300 Subject: [PATCH 158/177] clean: declarative bridge network instead shellscript check --- docker-compose.yaml.example | 4 ++-- docker-compose.yaml.example.complete | 4 ++-- docker-compose.yaml.example.dockerhub | 4 ++-- docker.sh | 9 +-------- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/docker-compose.yaml.example b/docker-compose.yaml.example index 93e04cc0..b3981999 100644 --- a/docker-compose.yaml.example +++ b/docker-compose.yaml.example @@ -24,5 +24,5 @@ volumes: networks: evolution-net: - external: true - \ No newline at end of file + name: evolution-net + driver: bridge diff --git a/docker-compose.yaml.example.complete b/docker-compose.yaml.example.complete index 4e453b51..790c6289 100644 --- a/docker-compose.yaml.example.complete +++ b/docker-compose.yaml.example.complete @@ -75,5 +75,5 @@ volumes: networks: evolution-net: - external: true - \ No newline at end of file + name: evolution-net + driver: bridge diff --git a/docker-compose.yaml.example.dockerhub b/docker-compose.yaml.example.dockerhub index 6136997d..562d1b07 100644 --- a/docker-compose.yaml.example.dockerhub +++ b/docker-compose.yaml.example.dockerhub @@ -24,5 +24,5 @@ volumes: networks: evolution-net: - external: true - \ No newline at end of file + name: evolution-net + driver: bridge diff --git a/docker.sh b/docker.sh index d72e56dd..579312b3 100755 --- a/docker.sh +++ b/docker.sh @@ -1,13 +1,6 @@ #!/bin/bash - -NET='evolution-net' IMAGE='evolution/api:local' -if !(docker network ls | grep ${NET} > /dev/null) -then - docker network create -d bridge ${NET} -fi - docker build -t ${IMAGE} . -docker compose up -d \ No newline at end of file +docker compose up -d From c9721d7bc9c623dc943a15e6e924330d5b3d7b9a Mon Sep 17 00:00:00 2001 From: AdsonCicilioti Date: Sat, 26 Aug 2023 02:36:45 -0300 Subject: [PATCH 159/177] clean: `docker build` will be remove in future releases / build into compose file --- docker-compose.yaml.example | 1 + docker-compose.yaml.example.complete | 1 + docker.sh | 6 ------ 3 files changed, 2 insertions(+), 6 deletions(-) delete mode 100755 docker.sh diff --git a/docker-compose.yaml.example b/docker-compose.yaml.example index b3981999..d0a75a5d 100644 --- a/docker-compose.yaml.example +++ b/docker-compose.yaml.example @@ -4,6 +4,7 @@ services: api: container_name: evolution_api image: evolution/api:local + build: . restart: always ports: - 8080:8080 diff --git a/docker-compose.yaml.example.complete b/docker-compose.yaml.example.complete index 790c6289..de13de57 100644 --- a/docker-compose.yaml.example.complete +++ b/docker-compose.yaml.example.complete @@ -4,6 +4,7 @@ services: api: container_name: evolution_api image: evolution/api:local + build: . restart: always ports: - 8080:8080 diff --git a/docker.sh b/docker.sh deleted file mode 100755 index 579312b3..00000000 --- a/docker.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -IMAGE='evolution/api:local' - -docker build -t ${IMAGE} . - -docker compose up -d From adb43ec5b3b041e835c764f3e2ae53778c54416c Mon Sep 17 00:00:00 2001 From: AdsonCicilioti Date: Sat, 26 Aug 2023 02:53:02 -0300 Subject: [PATCH 160/177] clean: correct docker network declaration --- Docker/mongodb/docker-compose.yaml | 5 +++-- Docker/redis/docker-compose.yaml | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index 698ca50c..01220c54 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -35,7 +35,8 @@ volumes: evolution_mongodb_data: evolution_mongodb_configdb: + networks: evolution-net: - external: true - \ No newline at end of file + name: evolution-net + driver: bridge diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index b0bb5985..297b11db 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -5,17 +5,17 @@ services: image: redis:latest container_name: redis command: > - redis-server - --port 6379 - --appendonly yes + redis-server --port 6379 --appendonly yes volumes: - evolution_redis:/data ports: - 6379:6379 - + volumes: evolution_redis: + networks: evolution-net: - external: true + name: evolution-net + driver: bridge From 91c7b4f2cd5eb08925e37ce6b1be3f16ecb4b34c Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 28 Aug 2023 09:59:04 -0300 Subject: [PATCH 161/177] =?UTF-8?q?Corre=C3=A7=C3=A3o=20DEL=5FINSTANCE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/env.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 4f28dbd5..db425c17 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -225,7 +225,7 @@ export class ConfigService { BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', }, DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 'true' + ? process.env.DEL_INSTANCE === 5 : Number.parseInt(process.env.DEL_INSTANCE) || false, WEBHOOK: { GLOBAL: { From 821a422ab526c56b2bdd2e9554dfb905cb49e2a5 Mon Sep 17 00:00:00 2001 From: Wender Teixeira Date: Mon, 28 Aug 2023 23:26:40 -0300 Subject: [PATCH 162/177] Fix set event rabbitmq/websocket --- src/whatsapp/controllers/instance.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 818fabf1..7d3691b5 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -181,7 +181,7 @@ export class InstanceController { 'CHAMA_AI_ACTION', ]; } else { - newEvents = events; + newEvents = websocket_events; } this.websocketService.create(instance, { enabled: true, @@ -232,7 +232,7 @@ export class InstanceController { } this.rabbitmqService.create(instance, { enabled: true, - events: newEvents, + events: rabbitmq_events, }); rabbitmqEvents = (await this.rabbitmqService.find(instance)).events; From 92632b2b96f16a25090c30ac2bfe9344422ab4c8 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Tue, 29 Aug 2023 14:29:50 -0300 Subject: [PATCH 163/177] wip --- Docker/.env.example | 4 ++-- Dockerfile | 2 +- src/config/env.config.ts | 2 +- src/dev-env.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index bf21a71c..739d24c0 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -84,8 +84,8 @@ WEBHOOK_EVENTS_NEW_JWT_TOKEN=false # Name that will be displayed on smartphone connection CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI -# Browser Name = chrome | firefox | edge | opera | safari -CONFIG_SESSION_PHONE_NAME=chrome +# Browser Name = Chrome | Firefox | Edge | Opera | Safari +CONFIG_SESSION_PHONE_NAME=Chrome # Set qrcode display limit QRCODE_LIMIT=30 diff --git a/Dockerfile b/Dockerfile index c9975782..2a241a1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -85,7 +85,7 @@ ENV WEBHOOK_EVENTS_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI -ENV CONFIG_SESSION_PHONE_NAME=chrome +ENV CONFIG_SESSION_PHONE_NAME=Chrome ENV QRCODE_LIMIT=30 ENV QRCODE_COLOR=#198754 diff --git a/src/config/env.config.ts b/src/config/env.config.ts index db425c17..85e5ee70 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -259,7 +259,7 @@ export class ConfigService { }, CONFIG_SESSION_PHONE: { CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', - NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'Chrome', }, QRCODE: { LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, diff --git a/src/dev-env.yml b/src/dev-env.yml index 235ec1b7..66a65ef4 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -124,7 +124,7 @@ WEBHOOK: CONFIG_SESSION_PHONE: # Name that will be displayed on smartphone connection CLIENT: "Evolution API" - NAME: chrome # chrome | firefox | edge | opera | safari + NAME: Chrome # Chrome | Firefox | Edge | Opera | Safari # Set qrcode display limit QRCODE: From 878ba5a8692c0658bbc8450b9f28ef9b5fd9eff1 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Tue, 29 Aug 2023 18:57:31 -0300 Subject: [PATCH 164/177] =?UTF-8?q?Corre=C3=A7=C3=A3o=20de=20Erro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```This comparison appears to be unintentional because the types 'string' and 'number' have no overlap.``` --- src/config/env.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index db425c17..9c63b893 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -224,8 +224,8 @@ export class ConfigService { COLOR: process.env?.LOG_COLOR === 'true', BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', }, - DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 5 + DEL_INSTANCE: process.env?.DEL_INSTANCE === 'true' + ? 5 : Number.parseInt(process.env.DEL_INSTANCE) || false, WEBHOOK: { GLOBAL: { From e61fe4d092d0019921e9b4206043ad5c718c4786 Mon Sep 17 00:00:00 2001 From: Wender Teixeira Date: Wed, 30 Aug 2023 12:38:53 -0300 Subject: [PATCH 165/177] Update error.config.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit encerramento controlado para lidar com erros não capturados no aplicativo. --- src/config/error.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/config/error.config.ts b/src/config/error.config.ts index 6449d52e..7a6717da 100644 --- a/src/config/error.config.ts +++ b/src/config/error.config.ts @@ -8,6 +8,7 @@ export function onUnexpectedError() { stderr: process.stderr.fd, error, }); + process.exit(1); }); process.on('unhandledRejection', (error, origin) => { @@ -17,5 +18,6 @@ export function onUnexpectedError() { stderr: process.stderr.fd, error, }); + process.exit(1); }); } From 16a18c4f2285986209f4138e7d9942a3db992273 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 30 Aug 2023 13:27:47 -0300 Subject: [PATCH 166/177] fix: update error.config.ts --- src/config/env.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 070e7279..e4995aab 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -239,7 +239,7 @@ export class ConfigService { BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error', }, DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) - ? process.env.DEL_INSTANCE === 5 + ? process.env.DEL_INSTANCE === 'true' : Number.parseInt(process.env.DEL_INSTANCE) || false, WEBHOOK: { GLOBAL: { From d00e1df29c202378eaa6076904f66505d9c06f3e Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Wed, 30 Aug 2023 15:09:03 -0300 Subject: [PATCH 167/177] [Melhoria] Group Create Verifica todos os participantes e pega apenas os que existe no WhatsApp --- src/whatsapp/services/whatsapp.service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d11946ee..12b145aa 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2969,7 +2969,9 @@ export class WAStartupService { public async createGroup(create: CreateGroupDto) { this.logger.verbose('Creating group: ' + create.subject); try { - const participants = create.participants.map((p) => this.createJid(p)); + const participants = (await this.whatsappNumber({ numbers: create.participants })) + .filter((participant) => participant.exists) + .map((participant) => participant.jid); const { id } = await this.client.groupCreate(create.subject, participants); this.logger.verbose('Group created: ' + id); @@ -2979,7 +2981,7 @@ export class WAStartupService { } if (create?.promoteParticipants) { - this.logger.verbose('Prometing group participants: ' + create.description); + this.logger.verbose('Prometing group participants: ' + participants); await this.updateGParticipant({ groupJid: id, action: 'promote', @@ -2987,8 +2989,8 @@ export class WAStartupService { }); } - const group = await this.client.groupMetadata(id); this.logger.verbose('Getting group metadata'); + const group = await this.client.groupMetadata(id); return group; } catch (error) { From 3ea3abe81a375e89c4826f3fcc8efb74cca2e3a6 Mon Sep 17 00:00:00 2001 From: Francis Breit Date: Thu, 31 Aug 2023 07:55:53 -0300 Subject: [PATCH 168/177] Update manager.json - Added the following settings for instances: Set Typebot and Typebot Change Session Status. - Fixed bug in Webhook settings --- Extras/appsmith/manager.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extras/appsmith/manager.json b/Extras/appsmith/manager.json index 0c26ec23..391f1a03 100644 --- a/Extras/appsmith/manager.json +++ b/Extras/appsmith/manager.json @@ -1 +1 @@ -{"clientSchemaVersion":1.0,"serverSchemaVersion":6.0,"exportedApplication":{"name":"EvolutionAPI Public","isPublic":true,"pages":[{"id":"Home","isDefault":true}],"publishedPages":[{"id":"Home","isDefault":true}],"viewMode":false,"appIsExample":false,"unreadCommentThreads":0.0,"color":"#F5D1D1","icon":"smartphone","slug":"evolutionapi-public","unpublishedAppLayout":{"type":"DESKTOP"},"publishedAppLayout":{"type":"DESKTOP"},"unpublishedCustomJSLibs":[],"publishedCustomJSLibs":[],"evaluationVersion":2.0,"applicationVersion":2.0,"collapseInvisibleWidgets":true,"isManualUpdate":false,"deleted":false},"datasourceList":[],"customJSLibList":[],"pageList":[{"unpublishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":82.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":41.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":27.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Number Input","sourceData":1.0,"isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"publishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":420.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":82.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run();\nshowModal('ModalChatwoot');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"image"},{"key":"borderRadius"}],"defaultImage":"https://evolution-api.com/files/evolution-api-favicon.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":147.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":36.0,"bottomRow":42.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":36.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":41.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":36.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":38.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":476.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":27.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Number Input","sourceData":1.0,"isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c534835ebbd221b60b4c56"}],"actionList":[{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_fetch_Instances","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c53560efcfc27db90a9788"},{"pluginType":"JS","pluginId":"js-plugin","unpublishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Scripts.verifyConfig","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Connect","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5374a2d8f7a159ce65333"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"publishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"id":"Home_Restart","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2717ea84639bf879f3b"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"publishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"id":"Home_Logout","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2a87ea84639bf879f3d"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"publishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"id":"Home_Delete","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d2c87ea84639bf879f3f"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"publishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"id":"Home_Create_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c5d7617ea84639bf879f46"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"publishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"id":"Home_Find_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be2a81f77b07d4a599f1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"publishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"id":"Home_Find_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6be9d81f77b07d4a599f3"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"publishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"id":"Home_Find_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6becd81f77b07d4a599f6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"publishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"id":"Home_Set_Webhook","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c3ab81f77b07d4a599fe"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"publishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"id":"Home_Set_Settings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c46581f77b07d4a59a04"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"publishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending,\n\t}\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"id":"Home_Set_Chatwoot","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c6c4c581f77b07d4a59a06"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"publishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"id":"Home_Fetch_Instance","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a62881f77b07d4a59a58"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"publishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"id":"Home_Update_ProfileName","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a79581f77b07d4a59a5a"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"publishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"id":"Home_Update_ProfileStatus","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a81c81f77b07d4a59a5c"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"publishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"id":"Home_Update_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a85481f77b07d4a59a5e"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"publishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"id":"Home_Remove_ProfilePicture","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8a881f77b07d4a59a60"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"publishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"id":"Home_Fetch_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8c881f77b07d4a59a62"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"publishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"id":"Home_Update_PrivacySettings","deleted":false,"gitSyncId":"64c53a7a7ea84639bf879f21_64c7a8f781f77b07d4a59a64"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"publishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"id":"Home_Find_Websocket","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafad875b7a111cf894430"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"publishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"id":"Home_Find_Rabbitmq","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafaf475b7a111cf894432"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"publishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"id":"Home_Set_Websocket","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafb0275b7a111cf894434"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"publishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"id":"Home_Set_Rabbitmq","deleted":false,"gitSyncId":"64ca60783615e270291978b0_64cafb2175b7a111cf894436"}],"actionCollectionList":[{"unpublishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"publishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"id":"Home_Scripts","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e"}],"updatedResources":{"customJSLibList":[],"actionList":["Delete##ENTITY_SEPARATOR##Home","Find_Websocket##ENTITY_SEPARATOR##Home","Scripts.verifyConfig##ENTITY_SEPARATOR##Home","Find_Chatwoot##ENTITY_SEPARATOR##Home","Logout##ENTITY_SEPARATOR##Home","Connect##ENTITY_SEPARATOR##Home","Fetch_Instance##ENTITY_SEPARATOR##Home","Set_Chatwoot##ENTITY_SEPARATOR##Home","Update_ProfileName##ENTITY_SEPARATOR##Home","Set_Websocket##ENTITY_SEPARATOR##Home","Remove_ProfilePicture##ENTITY_SEPARATOR##Home","Create_Instance##ENTITY_SEPARATOR##Home","Fetch_PrivacySettings##ENTITY_SEPARATOR##Home","Restart##ENTITY_SEPARATOR##Home","Update_ProfileStatus##ENTITY_SEPARATOR##Home","Find_Webhook##ENTITY_SEPARATOR##Home","Update_ProfilePicture##ENTITY_SEPARATOR##Home","Find_Settings##ENTITY_SEPARATOR##Home","Set_Rabbitmq##ENTITY_SEPARATOR##Home","fetch_Instances##ENTITY_SEPARATOR##Home","Set_Settings##ENTITY_SEPARATOR##Home","Find_Rabbitmq##ENTITY_SEPARATOR##Home","Set_Webhook##ENTITY_SEPARATOR##Home","Update_PrivacySettings##ENTITY_SEPARATOR##Home"],"pageList":["Home"],"actionCollectionList":["Scripts##ENTITY_SEPARATOR##Home"]},"editModeTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false},"publishedTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false}} \ No newline at end of file +{"clientSchemaVersion":1.0,"serverSchemaVersion":6.0,"exportedApplication":{"name":"manager2","isPublic":true,"pages":[{"id":"Home","isDefault":true}],"publishedPages":[{"id":"Home","isDefault":true}],"viewMode":false,"appIsExample":false,"unreadCommentThreads":0.0,"clonedFromApplicationId":"64da025f98d1c41c0da60e90","color":"#F5D1D1","icon":"email","slug":"manager2","unpublishedAppLayout":{"type":"FLUID"},"publishedAppLayout":{"type":"FLUID"},"unpublishedCustomJSLibs":[],"publishedCustomJSLibs":[],"evaluationVersion":2.0,"applicationVersion":2.0,"collapseInvisibleWidgets":true,"isManualUpdate":false,"deleted":false},"datasourceList":[],"customJSLibList":[],"pageList":[{"unpublishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":480.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":83.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem16ysonwzrq.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItembtatfbml4y.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run()\nshowModal('ModalChatwoot');}}"},"menuItem16ysonwzrq":{"id":"menuItem16ysonwzrq","index":5.0,"label":"Set Typebot","widgetId":"fi9nb2bace","isDisabled":false,"isVisible":true,"onClick":"{{Find_Typebot.run()\nshowModal('ModalTypebot');}}"},"menuItembtatfbml4y":{"id":"menuItembtatfbml4y","index":6.0,"label":"TypeBot Set Session Status","widgetId":"7f6mg653ra","isDisabled":false,"isVisible":true,"onClick":"{{showModal('ModalTypebotChangeSessionStatu');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"image"}],"defaultImage":"https://manualnegocioonline.com.br/downloads/evolution-api-favicon2.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":183.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":40.0,"bottomRow":48.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":40.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":48.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":40.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":40.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"1","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalTypebot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":45.0,"bottomRow":665.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":620.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":620.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Typebot.run().then(() => {\n showAlert('Typebot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Typebot', 'error');\n});\ncloseModal('ModalTypebot');}}","topRow":1.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.typebot.defaultValue"},{"key":"schema.__root_schema__.children.typebot.accentColor"},{"key":"schema.__root_schema__.children.typebot.borderRadius"},{"key":"schema.__root_schema__.children.expire.defaultValue"},{"key":"schema.__root_schema__.children.expire.accentColor"},{"key":"schema.__root_schema__.children.expire.borderRadius"},{"key":"schema.__root_schema__.children.keyword_finish.defaultValue"},{"key":"schema.__root_schema__.children.keyword_finish.accentColor"},{"key":"schema.__root_schema__.children.keyword_finish.borderRadius"},{"key":"schema.__root_schema__.children.delay_message.defaultValue"},{"key":"schema.__root_schema__.children.delay_message.accentColor"},{"key":"schema.__root_schema__.children.delay_message.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":68.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chat2.manualnegocioonline.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"typebot":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.typebot))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","isCustomField":false,"accessor":"typebot","identifier":"typebot","position":2.0,"originalIdentifier":"typebot","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Typebot"},"expire":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.expire))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Number Input","sourceData":20.0,"isCustomField":false,"accessor":"expire","identifier":"expire","position":3.0,"originalIdentifier":"expire","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Expire"},"keyword_finish":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.keyword_finish))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"#SAIR","isCustomField":false,"accessor":"keyword_finish","identifier":"keyword_finish","position":4.0,"originalIdentifier":"keyword_finish","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Keyword Finish"},"delay_message":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.delay_message))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Number Input","sourceData":3000.0,"isCustomField":false,"accessor":"delay_message","identifier":"delay_message","position":5.0,"originalIdentifier":"delay_message","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Delay Message"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Object","sourceData":{"enabled":true,"url":"https://chat2.manualnegocioonline.com.br","typebot":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","expire":20.0,"keyword_finish":"#SAIR","delay_message":3000.0,"unknown_message":"Mensagem não reconhecida2"},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormTypebot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":60.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Set Typebot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Typebot.data.enabled || false}},\n \"url\": {{Find_Typebot.data.url}},\n \"typebot\": {{Find_Typebot.data.typebot}},\n \"expire\": {{Find_Typebot.data.expire}},\n \"keyword_finish\": {{Find_Typebot.data.keyword_finish}},\n \"delay_message\": {{Find_Typebot.data.delay_message}}\n \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"fyu0oxvlx7","minWidth":450.0,"parentId":"bvxewkusbf","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":1.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bvxewkusbf","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"4n3m0wo9tx","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":620.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"4n3m0wo9tx","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalTypebotChangeSessionStatu","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":45.0,"bottomRow":415.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":370.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopyCopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":370.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_TypebotChangeSessionStatus.run().then(() => {\n showAlert('Typebot Change Session updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Session Typebot', 'error');\n});\ncloseModal('ModalTypebotChangeSessionStatu');}}","topRow":1.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.remoteJid.defaultValue"},{"key":"schema.__root_schema__.children.remoteJid.accentColor"},{"key":"schema.__root_schema__.children.remoteJid.borderRadius"},{"key":"schema.__root_schema__.children.status.defaultValue"},{"key":"schema.__root_schema__.children.status.accentColor"},{"key":"schema.__root_schema__.children.status.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":60.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"remoteJid":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.remoteJid))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"remoteJid","identifier":"remoteJid","position":0.0,"originalIdentifier":"remoteJid","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":true,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Remote Jid (WhatsApp. Ex: 5511968162699@s.whatsapp.net)"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.status))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"status","identifier":"status","position":1.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Status (opened, paused or closed)"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Object","sourceData":{"enabled":true,"url":"https://chat2.manualnegocioonline.com.br","typebot":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","expire":20.0,"keyword_finish":"#SAIR","delay_message":3000.0,"unknown_message":"Mensagem não reconhecida2"},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormTypebotChangeSessionStatus","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":35.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Typebot Change Session Status","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"remoteJid\": \"@s.whatsapp.net\",\n \"status\": \"\"\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"28lli5jdvr","minWidth":450.0,"parentId":"8m0yhclt7g","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":1.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"8m0yhclt7g","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"84rj87eew6","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":370.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"84rj87eew6","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":[],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"publishedPage":{"name":"Home","slug":"home","customSlug":"","layouts":[{"viewMode":false,"dsl":{"widgetName":"MainContainer","backgroundColor":"none","rightColumn":4896.0,"snapColumns":64.0,"detachFromLayout":true,"widgetId":"0","topRow":0.0,"bottomRow":480.0,"containerStyle":"none","snapRows":124.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"version":83.0,"minHeight":1292.0,"dynamicTriggerPathList":[],"parentColumnSpace":1.0,"dynamicBindingPathList":[],"leftColumn":0.0,"children":[{"boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","borderColor":"#E0DEDE","isVisibleDownload":true,"iconSVG":"https://appcdn.appsmith.com/static/media/icon.24905525921dd6f5ff46d0dd843b9e12.svg","topRow":6.0,"isSortable":true,"type":"TABLE_WIDGET_V2","inlineEditingSaveOption":"ROW_LEVEL","animateLoading":true,"dynamicBindingPathList":[{"key":"tableData"},{"key":"primaryColumns.customColumn9.boxShadow"},{"key":"primaryColumns.customColumn9.borderRadius"},{"key":"primaryColumns.customColumn9.menuColor"},{"key":"primaryColumns.customColumn8.computedValue"},{"key":"primaryColumns.customColumn7.computedValue"},{"key":"primaryColumns.customColumn6.computedValue"},{"key":"primaryColumns.customColumn5.computedValue"},{"key":"primaryColumns.customColumn2.computedValue"},{"key":"primaryColumns.customColumn1.textColor"},{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"primaryColumns.customColumn1.computedValue"},{"key":"primaryColumns.instance.computedValue"},{"key":"isVisible"},{"key":"accentColor"},{"key":"borderRadius"},{"key":"boxShadow"}],"needsHeightForContent":true,"leftColumn":14.0,"delimiter":",","defaultSelectedRowIndex":0.0,"showInlineEditingOptionDropdown":true,"accentColor":"{{appsmith.theme.colors.primaryColor}}","isVisibleFilters":true,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","enableClientSideSearch":true,"version":2.0,"totalRecordsCount":0.0,"isLoading":false,"childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","columnUpdatedAt":1.690746223636E12,"defaultSelectedRowIndices":[0.0],"mobileBottomRow":32.0,"widgetName":"TableInstances","defaultPageSize":0.0,"columnOrder":["instance","customColumn5","customColumn1","customColumn2","customColumn6","customColumn7","customColumn8","customColumn9"],"dynamicPropertyPathList":[{"key":"primaryColumns.customColumn1.cellBackground"},{"key":"isVisible"}],"displayName":"Table","bottomRow":42.0,"columnWidthMap":{"customColumn3":92.0,"customColumn2":340.0,"customColumn5":254.0,"customColumn9":60.0},"parentRowSpace":10.0,"hideCard":false,"mobileRightColumn":36.0,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[{"key":"primaryColumns.customColumn9.menuItems.menuItemjfzsd8g6yr.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem4sqork5nmt.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemig6ua4ixjx.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemx9oyhys8cj.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItemxk5jvvwwef.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItem16ysonwzrq.onClick"},{"key":"primaryColumns.customColumn9.menuItems.menuItembtatfbml4y.onClick"}],"borderWidth":"1","primaryColumns":{"instance":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":0.0,"width":150.0,"originalId":"instance","id":"instance","alias":"instance","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":false,"label":"Instance","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.instanceName))}}","sticky":"","validation":{}},"customColumn1":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":1.0,"width":150.0,"originalId":"customColumn1","id":"customColumn1","alias":"Status","horizontalAlignment":"CENTER","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Status","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","cellBackground":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.status === \"open\" ? \"#499B51\" : currentRow.instance.status === \"close\" ? \"#DD524C\" : \"#2770FC\"))}}","textColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.backgroundColor)))}}"},"customColumn2":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":2.0,"width":150.0,"originalId":"customColumn2","id":"customColumn2","alias":"Apikey","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Apikey","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.apikey))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn5":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":5.0,"width":150.0,"originalId":"customColumn5","id":"customColumn5","alias":"Owner","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"Owner","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.owner))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn6":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":6.0,"width":150.0,"originalId":"customColumn6","id":"customColumn6","alias":"profilePictureUrl","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profilePictureUrl","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profilePictureUrl))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn7":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":7.0,"width":150.0,"originalId":"customColumn7","id":"customColumn7","alias":"profileName","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileName","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileName))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn8":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":8.0,"width":150.0,"originalId":"customColumn8","id":"customColumn8","alias":"profileStatus","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"text","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":false,"isDerived":true,"label":"profileStatus","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( currentRow.instance.profileStatus))}}","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF"},"customColumn9":{"allowCellWrapping":false,"allowSameOptionsInNewRow":true,"index":9.0,"width":150.0,"originalId":"customColumn9","id":"customColumn9","alias":"#","horizontalAlignment":"LEFT","verticalAlignment":"CENTER","columnType":"menuButton","textSize":"0.875rem","enableFilter":true,"enableSort":true,"isVisible":true,"isDisabled":false,"isCellEditable":false,"isEditable":false,"isCellVisible":true,"isDerived":true,"label":"#","isSaveVisible":true,"isDiscardVisible":true,"computedValue":"","sticky":"","validation":{},"buttonStyle":"rgb(3, 179, 101)","labelColor":"#FFFFFF","menuColor":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.colors.primaryColor)))}}","borderRadius":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( (appsmith.theme.borderRadius.appBorderRadius)))}}","boxShadow":"{{TableInstances.processedTableData.map((currentRow, currentIndex) => ( \"none\"))}}","customAlias":"","menuItemsSource":"STATIC","menuButtonLabel":" ","menuButtoniconName":"chevron-down","menuItems":{"menuItemjfzsd8g6yr":{"id":"menuItemjfzsd8g6yr","index":0.0,"label":"Webhook","widgetId":"vygcejtdun","isDisabled":false,"isVisible":true,"onClick":"{{Find_Webhook.run({\n //\"key\": \"value\",\n});\nshowModal('ModalWebhook');}}"},"menuItem4sqork5nmt":{"id":"menuItem4sqork5nmt","index":1.0,"label":"Settings","widgetId":"0hw8oqpwcj","isDisabled":false,"isVisible":true,"onClick":"{{Find_Settings.run();\nshowModal('ModalSettings');}}"},"menuItemx9oyhys8cj":{"id":"menuItemx9oyhys8cj","index":2.0,"label":"Websocket","widgetId":"j75a4k6ecq","isDisabled":false,"isVisible":true,"onClick":"{{Find_Websocket.run();\nshowModal('ModalWebsocket');}}"},"menuItemxk5jvvwwef":{"id":"menuItemxk5jvvwwef","index":3.0,"label":"Rabbitmq","widgetId":"3u94ov6qst","isDisabled":false,"isVisible":true,"onClick":"{{Find_Rabbitmq.run();\nshowModal('ModalRabbitmq');}}"},"menuItemig6ua4ixjx":{"id":"menuItemig6ua4ixjx","index":4.0,"label":"Chatwoot","widgetId":"fuq5dtgbqc","isDisabled":false,"isVisible":true,"onClick":"{{Find_Chatwoot.run()\nshowModal('ModalChatwoot');}}"},"menuItem16ysonwzrq":{"id":"menuItem16ysonwzrq","index":5.0,"label":"Set Typebot","widgetId":"fi9nb2bace","isDisabled":false,"isVisible":true,"onClick":"{{Find_Typebot.run()\nshowModal('ModalTypebot');}}"},"menuItembtatfbml4y":{"id":"menuItembtatfbml4y","index":6.0,"label":"TypeBot Set Session Status","widgetId":"7f6mg653ra","isDisabled":false,"isVisible":true,"onClick":"{{showModal('ModalTypebotChangeSessionStatu');}}"}}}},"key":"e3yxhhyeel","canFreezeColumn":true,"isDeprecated":false,"rightColumn":63.0,"textSize":"0.875rem","widgetId":"uupm7enu8u","minWidth":450.0,"tableData":"{{fetch_Instances.data}}","label":"Data","searchKey":"","parentId":"0","renderMode":"CANVAS","mobileTopRow":4.0,"horizontalAlignment":"LEFT","isVisibleSearch":true,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"isVisiblePagination":true,"verticalAlignment":"CENTER"},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnNewInstance","onClick":"{{showModal('ModalInstance');}}","buttonColor":"rgb(3, 179, 101)","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":8.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":7.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"New Instance","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":19.0,"isDefaultClickDisabled":true,"iconName":"add","widgetId":"84ei9q1ugm","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":74.0,"widgetName":"ModalQrcode","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":500.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":45.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":21.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas1","displayName":"Canvas","topRow":0.0,"bottomRow":450.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":52.0,"widgetName":"ImageQrcode","displayName":"Image","iconSVG":"https://appcdn.appsmith.com/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":55.0,"animateLoading":true,"parentColumnSpace":20.078125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":2.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"image"}],"defaultImage":"https://manualnegocioonline.com.br/downloads/evolution-api-favicon2.png","key":"4chlj9l432","image":"{{Connect.data.base64}}","isDeprecated":false,"rightColumn":61.0,"objectFit":"contain","widgetId":"27dpgapd7q","isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":40.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":43.0,"enableRotation":false},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton1","onClick":"{{closeModal('ModalQrcode');\nfetch_Instances.run()}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":58.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"i1dw369dch","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"mobileBottomRow":5.0,"widgetName":"Text1","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":41.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Qrcode","key":"9s8f10sepn","isDeprecated":false,"rightColumn":41.0,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"mg2cqsi9fn","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"we6j3r2byy","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"we6j3r2byy","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ljwryrjhy7","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":450.0,"isDeprecated":false,"rightColumn":45.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ljwryrjhy7","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":50.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":21.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"BtnConfig","onClick":"{{showModal('ModalConfig');}}","buttonColor":"#2563eb","dynamicPropertyPathList":[],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":30.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"text":"Access","isDisabled":false,"key":"crzwqv3pdr","isDeprecated":false,"rightColumn":7.0,"isDefaultClickDisabled":true,"iconName":"user","widgetId":"uegjpy37i6","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":14.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":73.0,"widgetName":"ModalConfig","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":49.0,"bottomRow":30.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"minHeight":300.0,"animateLoading":true,"parentColumnSpace":11.75,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas2","displayName":"Canvas","topRow":0.0,"bottomRow":300.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":300.0,"mobileRightColumn":282.0,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":84.0,"borderColor":"#E0DEDE","widgetName":"FormConfig","isCanvas":true,"displayName":"Form","iconSVG":"/static/media/icon.5d6d2ac5cb1aa68bcd9b14f11c56b44a.svg","searchTags":["group"],"topRow":0.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"FORM_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":25.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":400.0,"widgetName":"Canvas2Copy","displayName":"Canvas","topRow":0.0,"bottomRow":280.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":false,"hideCard":true,"minHeight":400.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"mobileBottomRow":5.0,"widgetName":"Text2","displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":1.0,"bottomRow":5.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":25.5,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","dynamicTriggerPathList":[],"leftColumn":1.5,"dynamicBindingPathList":[{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"Access Credentials","key":"9s8f10sepn","isDeprecated":false,"rightColumn":25.5,"textAlign":"LEFT","dynamicHeight":"AUTO_HEIGHT","widgetId":"tps5rw2lk9","minWidth":450.0,"isVisible":true,"fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.5,"maxDynamicHeight":9000.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1","onClick":"{{storeValue('api_url', FormConfig.data.InputApiUrl);\nstoreValue('api_key', FormConfig.data.InputGlobalApiKey);\nfetch_Instances.run().then(() => {\n showAlert('successful login', 'success');\n}).catch(() => {\n showAlert('Could not load instances', 'error');\n});\ncloseModal('ModalConfig').then(() => {});}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":22.0,"bottomRow":26.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":51.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"text":"Login","isDisabled":"","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":63.0,"isDefaultClickDisabled":true,"iconName":"log-in","widgetId":"gzxvnsxk0y","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"resetFormOnClick":true,"boxShadow":"none","mobileBottomRow":37.0,"widgetName":"Button1Copy","onClick":"{{removeValue('api_url');\nremoveValue('api_key').then(() => {\n showAlert('successful logout', 'success');\n});}}","buttonColor":"#dc2626","dynamicPropertyPathList":[{"key":"isDisabled"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":21.0,"bottomRow":25.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":62.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":2.0,"dynamicBindingPathList":[{"key":"isDisabled"},{"key":"borderRadius"}],"text":"Logout","isDisabled":"{{!appsmith.store.api_key && !appsmith.store.api_url ? true : false}}","key":"crzwqv3pdr","isDeprecated":false,"rightColumn":14.0,"isDefaultClickDisabled":true,"iconName":"log-out","widgetId":"f2i8tsbgx1","minWidth":120.0,"isVisible":true,"recaptchaType":"V3","version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":33.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":46.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":6.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"TEXT","placeholderText":"","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputApiUrl","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":13.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"spgryrb5ao","minWidth":450.0,"label":"API URL","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"isSpellCheck":false,"iconAlign":"left","defaultText":"{{appsmith.store.api_url || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","iconSVG":"/static/media/icon.d0ce957b6c4640f8a7418ce846ee200e.svg","topRow":14.0,"labelWidth":5.0,"type":"INPUT_WIDGET_V2","animateLoading":true,"resetOnSubmit":true,"leftColumn":2.0,"dynamicBindingPathList":[{"key":"defaultText"},{"key":"accentColor"},{"key":"borderRadius"}],"labelStyle":"","inputType":"PASSWORD","isDisabled":false,"isRequired":true,"dynamicHeight":"FIXED","accentColor":"{{appsmith.theme.colors.primaryColor}}","showStepArrows":false,"isVisible":true,"version":2.0,"isLoading":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileBottomRow":13.0,"widgetName":"InputGlobalApiKey","displayName":"Input","searchTags":["form","text input","number","textarea"],"bottomRow":21.0,"parentRowSpace":10.0,"autoFocus":false,"hideCard":false,"mobileRightColumn":22.0,"parentColumnSpace":5.047119140625,"dynamicTriggerPathList":[],"labelPosition":"Top","key":"r1hfat3ouf","labelTextSize":"0.875rem","isDeprecated":false,"rightColumn":63.0,"widgetId":"v2vedr13py","minWidth":450.0,"label":"GLOBAL API KEY","parentId":"lrtvcpswru","labelAlignment":"left","renderMode":"CANVAS","mobileTopRow":6.0,"responsiveBehavior":"fill","mobileLeftColumn":2.0,"maxDynamicHeight":9000.0,"shouldAllowAutofill":true,"iconAlign":"left","defaultText":"{{appsmith.store.api_key || ''}}","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton2","onClick":"{{closeModal('ModalConfig');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"parentRowSpace":10.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"parentColumnSpace":9.072265625,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":60.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"isDisabled":false,"key":"pezy0hb491","isDeprecated":false,"rightColumn":64.0,"iconName":"cross","widgetId":"oaouelmhi1","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"lrtvcpswru","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":60.0,"buttonVariant":"TERTIARY"}],"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"lrtvcpswru","containerStyle":"none","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"h97rbttd5c","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"borderWidth":"0","positioning":"fixed","key":"dtzd07zsya","backgroundColor":"#FFFFFF","isDeprecated":false,"rightColumn":63.0,"dynamicHeight":"AUTO_HEIGHT","widgetId":"h97rbttd5c","minWidth":450.0,"isVisible":true,"parentId":"es5gsctogb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":44.0,"responsiveBehavior":"fill","originalTopRow":0.0,"borderRadius":"0.375rem","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"originalBottomRow":28.0,"minDynamicHeight":10.0}],"isDisabled":false,"key":"e8r23nd8j4","isDeprecated":false,"rightColumn":282.0,"detachFromLayout":true,"widgetId":"es5gsctogb","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"gneh33z88k","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"g8xx6ocuvi","height":300.0,"isDeprecated":false,"rightColumn":25.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"gneh33z88k","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":49.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":1.0,"maxDynamicHeight":9000.0,"width":632.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":66.0,"widgetName":"ModalInstance","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":1892.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":37.0,"minHeight":1850.0,"animateLoading":true,"parentColumnSpace":11.828125,"leftColumn":13.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas3","displayName":"Canvas","topRow":0.0,"bottomRow":1850.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":1140.0,"mobileRightColumn":283.875,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","mobileBottomRow":4.0,"widgetName":"IconButton3Copy","onClick":"{{closeModal('ModalInstance');}}","buttonColor":"{{appsmith.theme.colors.primaryColor}}","displayName":"Icon button","iconSVG":"/static/media/icon.80fc7466c0d7181ec0271de7fda795ec.svg","searchTags":["click","submit"],"topRow":0.0,"bottomRow":4.0,"type":"ICON_BUTTON_WIDGET","hideCard":false,"mobileRightColumn":64.0,"animateLoading":true,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":57.0,"dynamicBindingPathList":[{"key":"buttonColor"},{"key":"borderRadius"}],"iconSize":24.0,"isDisabled":false,"key":"mr6bto7c8j","isDeprecated":false,"rightColumn":63.0,"iconName":"cross","widgetId":"xofakp4har","minWidth":50.0,"isVisible":true,"version":1.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"hug","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":58.0,"buttonVariant":"TERTIARY"},{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Create_Instance.run().then(() => {\n showAlert('Instance created successfully', 'success');\n}).catch(() => {\n showAlert('Error creating instance', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalInstance');}}","topRow":4.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.defaultValue"},{"key":"schema.__root_schema__.children.instance.borderRadius"},{"key":"schema.__root_schema__.children.instance.cellBorderRadius"},{"key":"schema.__root_schema__.children.instance.children.instanceName.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.instanceName.accentColor"},{"key":"schema.__root_schema__.children.instance.children.instanceName.borderRadius"},{"key":"schema.__root_schema__.children.instance.children.token.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.token.accentColor"},{"key":"schema.__root_schema__.children.instance.children.token.borderRadius"},{"key":"schema.__root_schema__.children.webhook.cellBorderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.webhook.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.events.accentColor"},{"key":"schema.__root_schema__.children.webhook.children.events.borderRadius"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.settings.defaultValue"},{"key":"schema.__root_schema__.children.settings.borderRadius"},{"key":"schema.__root_schema__.children.settings.cellBorderRadius"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.settings.children.msg_call.borderRadius"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.cellBorderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_account_id.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_token.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_url.borderRadius"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.accentColor"},{"key":"schema.__root_schema__.children.websocket.defaultValue"},{"key":"schema.__root_schema__.children.websocket.borderRadius"},{"key":"schema.__root_schema__.children.websocket.cellBorderRadius"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.accentColor"},{"key":"schema.__root_schema__.children.websocket.children.websocket_events.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.borderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.cellBorderRadius"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.accentColor"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_events.borderRadius"}],"showReset":true,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY","iconAlign":"left"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Create","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":183.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook":{"children":{"webhook":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"webhook","identifier":"webhook","position":0.0,"originalIdentifier":"webhook","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"},"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook.webhook_by_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":2.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"webhook","identifier":"webhook","position":1.0,"originalIdentifier":"webhook","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Webhook","labelStyle":"BOLD"},"instance":{"children":{"instanceName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.instanceName))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"instanceName","identifier":"instanceName","position":0.0,"originalIdentifier":"instanceName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Instance Name"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"token","identifier":"token","position":1.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token"},"qrcode":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance.qrcode))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"qrcode","identifier":"qrcode","position":2.0,"originalIdentifier":"qrcode","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Qrcode"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.instance))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"instance","identifier":"instance","position":0.0,"originalIdentifier":"instance","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Instance","labelStyle":"BOLD"},"settings":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.reject_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.msg_call))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.groups_ignore))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.always_online))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_messages))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings.read_status))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.settings))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"settings","identifier":"settings","position":2.0,"originalIdentifier":"settings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Settings","labelStyle":"BOLD"},"chatwoot":{"children":{"chatwoot_account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_account_id))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_account_id","identifier":"chatwoot_account_id","position":0.0,"originalIdentifier":"chatwoot_account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Account Id"},"chatwoot_token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_token))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Password Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_token","identifier":"chatwoot_token","position":1.0,"originalIdentifier":"chatwoot_token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Token","shouldAllowAutofill":true},"chatwoot_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_url))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"chatwoot_url","identifier":"chatwoot_url","position":2.0,"originalIdentifier":"chatwoot_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Url"},"chatwoot_sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_sign_msg))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_sign_msg","identifier":"chatwoot_sign_msg","position":3.0,"originalIdentifier":"chatwoot_sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Sign Msg"},"chatwoot_reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_reopen_conversation))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_reopen_conversation","identifier":"chatwoot_reopen_conversation","position":4.0,"originalIdentifier":"chatwoot_reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Reopen Conversation"},"chatwoot_conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot.chatwoot_conversation_pending))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"chatwoot_conversation_pending","identifier":"chatwoot_conversation_pending","position":5.0,"originalIdentifier":"chatwoot_conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Chatwoot Conversation Pending"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.chatwoot))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"chatwoot","identifier":"chatwoot","position":5.0,"originalIdentifier":"chatwoot","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Chatwoot","labelStyle":"BOLD"},"websocket":{"children":{"websocket_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"websocket_enabled","identifier":"websocket_enabled","position":0.0,"originalIdentifier":"websocket_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Websocket Enabled"},"websocket_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket.websocket_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"websocket_events","identifier":"websocket_events","position":1.0,"originalIdentifier":"websocket_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Websocket Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.websocket))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{},"isCustomField":false,"accessor":"websocket","identifier":"websocket","position":3.0,"originalIdentifier":"websocket","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Websocket","labelStyle":"BOLD"},"rabbitmq":{"children":{"rabbitmq_enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_enabled))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"rabbitmq_enabled","identifier":"rabbitmq_enabled","position":1.0,"originalIdentifier":"rabbitmq_enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Rabbitmq Enabled"},"rabbitmq_events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq.rabbitmq_events))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"isCustomField":false,"accessor":"rabbitmq_events","identifier":"rabbitmq_events","position":1.0,"originalIdentifier":"rabbitmq_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Rabbitmq Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":[{"label":"Blue","value":"BLUE"},{"label":"Green","value":"GREEN"},{"label":"Red","value":"RED"}]}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.rabbitmq))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"websocket_enabled":false,"websocket_events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"]},"isCustomField":false,"accessor":"rabbitmq","identifier":"rabbitmq","position":4.0,"originalIdentifier":"rabbitmq","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Rabbitmq","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","fieldType":"Object","sourceData":{"instanceName":"","token":"","webhook":"","webhook_by_events":false,"events":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL","NEW_JWT_TOKEN"],"reject_call":false,"msg_call":"","groups_ignore":false,"always_online":false,"read_messages":false,"read_status":false,"chatwoot_account_id":"","chatwoot_token":"","chatwoot_url":"","chatwoot_sign_msg":false,"chatwoot_reopen_conversation":false,"chatwoot_conversation_pending":false},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormInstance.sourceData, FormInstance.formData, FormInstance.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":85.0,"widgetName":"FormInstance","submitButtonStyles":{"buttonColor":"rgb(3, 179, 101)","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.settings.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.chatwoot.children.chatwoot_conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.instance.children.qrcode.defaultValue"},{"key":"schema.__root_schema__.children.websocket.children.websocket_enabled.defaultValue"},{"key":"schema.__root_schema__.children.rabbitmq.children.rabbitmq_enabled.defaultValue"}],"displayName":"JSON Form","bottomRow":183.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"New Instance","hideCard":false,"mobileRightColumn":22.0,"shouldScrollContents":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"instance\": {\n\t\t\t\"instanceName\": \"\",\n \t\"token\": \"\",\n\t\t\t\"qrcode\": true\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"webhook\": \"\",\n\t\t\t\"events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t],\n\t\t\t\"webhook_by_events\": false\n\t\t},\n \"settings\": {\n\t\t\t\"reject_call\": false,\n\t\t\t\"msg_call\": \"\",\n\t\t\t\"groups_ignore\": false,\n\t\t\t\"always_online\": false,\n\t\t\t\"read_messages\": false,\n\t\t\t\"read_status\": false\n\t\t},\n\t\t\"websocket\": {\n\t\t\t\"websocket_enabled\": false,\n\t\t\t\"websocket_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n\t\t\"rabbitmq\": {\n\t\t\t\"rabbitmq_enabled\": false,\n\t\t\t\"rabbitmq_events\": [\n\t\t\t\t\"APPLICATION_STARTUP\",\n\t\t\t\t\t\"QRCODE_UPDATED\",\n\t\t\t\t\t\"MESSAGES_SET\",\n\t\t\t\t\t\"MESSAGES_UPSERT\",\n\t\t\t\t\t\"MESSAGES_UPDATE\",\n\t\t\t\t\t\"MESSAGES_DELETE\",\n\t\t\t\t\t\"SEND_MESSAGE\",\n\t\t\t\t\t\"CONTACTS_SET\",\n\t\t\t\t\t\"CONTACTS_UPSERT\",\n\t\t\t\t\t\"CONTACTS_UPDATE\",\n\t\t\t\t\t\"PRESENCE_UPDATE\",\n\t\t\t\t\t\"CHATS_SET\",\n\t\t\t\t\t\"CHATS_UPSERT\",\n\t\t\t\t\t\"CHATS_UPDATE\",\n\t\t\t\t\t\"CHATS_DELETE\",\n\t\t\t\t\t\"GROUPS_UPSERT\",\n\t\t\t\t\t\"GROUP_UPDATE\",\n\t\t\t\t\t\"GROUP_PARTICIPANTS_UPDATE\",\n\t\t\t\t\t\"CONNECTION_UPDATE\",\n\t\t\t\t\t\"CALL\",\n\t\t\t\t\t\"NEW_JWT_TOKEN\"\n\t\t\t]\n\t\t},\n \"chatwoot\": {\n\t\t\t\"chatwoot_account_id\": \"\",\n\t\t\t\"chatwoot_token\": \"\",\n\t\t\t\"chatwoot_url\": \"\",\n\t\t\t\"chatwoot_sign_msg\": false,\n\t\t\t\"chatwoot_reopen_conversation\": false,\n\t\t\t\"chatwoot_conversation_pending\": false\n\t\t}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"o0v8ypwnya","minWidth":450.0,"parentId":"esgwuzqcwt","renderMode":"CANVAS","mobileTopRow":44.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":4.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"w17ra2a85u","isDeprecated":false,"rightColumn":283.875,"detachFromLayout":true,"widgetId":"esgwuzqcwt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"rnttu90jzr","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"bkvkzj4d20","height":1850.0,"isDeprecated":false,"rightColumn":37.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"rnttu90jzr","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":42.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":13.0,"maxDynamicHeight":9000.0,"width":628.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonRefreshData","onClick":"{{fetch_Instances.run()}}","buttonColor":"#60a5fa","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":35.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":19.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"text":"","isDisabled":false,"key":"k10nyfsas3","isDeprecated":false,"rightColumn":24.0,"isDefaultClickDisabled":true,"iconName":"refresh","widgetId":"dn1ehe3gvu","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"hug","disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":19.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":5.0,"widgetName":"ButtonGroup1","isCanvas":false,"dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button Group","iconSVG":"/static/media/icon.7c22979bacc83c8d84aedf56ea6c2022.svg","searchTags":["click","submit"],"topRow":1.0,"bottomRow":5.0,"parentRowSpace":10.0,"groupButtons":{"groupButton1":{"label":"Connect","iconName":"camera","id":"groupButton1","widgetId":"","buttonType":"SIMPLE","placement":"CENTER","isVisible":true,"isDisabled":false,"index":0.0,"menuItems":{},"buttonColor":"#16a34a","onClick":"{{Connect.run();\nfetch_Instances.run();\nshowModal('ModalQrcode');}}"},"groupButton2":{"label":"Restart","iconName":"reset","id":"groupButton2","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":1.0,"menuItems":{},"buttonColor":"#2563eb","onClick":"{{Restart.run().then(() => {\n showAlert('Instance restarted successfully', 'success');\n}).catch(() => {\n showAlert('Error restarting instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButton3":{"label":"Logout","iconName":"log-in","id":"groupButton3","buttonType":"SIMPLE","placement":"CENTER","widgetId":"","isVisible":true,"isDisabled":false,"index":2.0,"menuItems":{"menuItem1":{"label":"First Option","backgroundColor":"#FFFFFF","id":"menuItem1","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":0.0},"menuItem2":{"label":"Second Option","backgroundColor":"#FFFFFF","id":"menuItem2","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":1.0},"menuItem3":{"label":"Delete","iconName":"trash","iconColor":"#FFFFFF","iconAlign":"right","textColor":"#FFFFFF","backgroundColor":"#DD4B34","id":"menuItem3","widgetId":"","onClick":"","isVisible":true,"isDisabled":false,"index":2.0}},"buttonColor":"#a16207","onClick":"{{Logout.run().then(() => {\n showAlert('Instance logout successfully', 'success');\n}).catch(() => {\n showAlert('Error logout instance', 'error');\n});\nfetch_Instances.run();}}"},"groupButtonmghcs8rd4g":{"id":"groupButtonmghcs8rd4g","index":3.0,"label":"Delete","menuItems":{},"buttonType":"SIMPLE","placement":"CENTER","widgetId":"v0qkg2pjo2","isDisabled":false,"isVisible":true,"buttonColor":"#ef4444","iconName":"cross","onClick":"{{Delete.run().then(() => {\n showAlert('Instance deleted successfully', 'success');\n}).catch(() => {\n showAlert('Error deleting instance', 'error');\n});\nfetch_Instances.run();}}"}},"type":"BUTTON_GROUP_WIDGET","hideCard":false,"mobileRightColumn":51.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[{"key":"groupButtons.groupButton1.onClick"},{"key":"groupButtons.groupButton2.onClick"},{"key":"groupButtons.groupButton3.onClick"},{"key":"groupButtons.groupButtonmghcs8rd4g.onClick"}],"leftColumn":27.0,"dynamicBindingPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"isDisabled":false,"key":"za8m3k8x7w","orientation":"horizontal","isDeprecated":false,"rightColumn":63.0,"widgetId":"2s6fqi483g","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":1.0,"responsiveBehavior":"fill","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}},"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":27.0,"buttonVariant":"PRIMARY"},{"boxShadow":"none","mobileBottomRow":18.0,"widgetName":"ProfilePicture","dynamicPropertyPathList":[{"key":"isVisible"},{"key":"borderRadius"}],"displayName":"Image","iconSVG":"/static/media/icon.30c8cbd442cce232b01ba2d434c53a53.svg","topRow":6.0,"bottomRow":28.0,"parentRowSpace":10.0,"type":"IMAGE_WIDGET","hideCard":false,"mobileRightColumn":13.0,"animateLoading":true,"parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"imageShape":"RECTANGLE","leftColumn":1.0,"dynamicBindingPathList":[{"key":"image"},{"key":"isVisible"}],"defaultImage":"https://th.bing.com/th/id/OIP.ruat7whad9-kcI8_1KH_tQHaGI?pid=ImgDet&rs=1","key":"bl30j21wwb","image":"{{TableInstances.selectedRow.profilePictureUrl}}","isDeprecated":false,"rightColumn":13.0,"objectFit":"contain","widgetId":"1sjznr31jo","isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":6.0,"maxZoomLevel":1.0,"enableDownload":false,"borderRadius":"0.335rem","mobileLeftColumn":1.0,"enableRotation":false},{"mobileBottomRow":22.0,"widgetName":"Text4","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":40.0,"bottomRow":48.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":11.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.828125,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.profileName || ''}}\n\n{{TableInstances.selectedRow.profileStatus || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"0c356c66hp","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":18.0,"responsiveBehavior":"fill","originalTopRow":40.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":48.0,"fontSize":"0.875rem","minDynamicHeight":4.0},{"mobileBottomRow":41.0,"widgetName":"Text5","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Text","iconSVG":"/static/media/icon.c3b6033f570046f8c6288d911333a827.svg","searchTags":["typography","paragraph","label"],"topRow":32.0,"bottomRow":40.0,"parentRowSpace":10.0,"type":"TEXT_WIDGET","hideCard":false,"mobileRightColumn":9.0,"animateLoading":true,"overflow":"NONE","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","parentColumnSpace":11.75,"dynamicTriggerPathList":[],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"text"},{"key":"isVisible"},{"key":"fontFamily"}],"shouldTruncate":false,"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","text":"{{TableInstances.selectedRow.instance || ''}}","key":"gqt8t28m33","isDeprecated":false,"rightColumn":13.0,"textAlign":"CENTER","dynamicHeight":"AUTO_HEIGHT","widgetId":"5qg2iscn1l","minWidth":450.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? true : false}}","fontStyle":"BOLD","textColor":"#231F20","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":37.0,"responsiveBehavior":"fill","originalTopRow":32.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"originalBottomRow":40.0,"fontSize":"1.25rem","minDynamicHeight":4.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebhook","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":43.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":430.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4","displayName":"Canvas","topRow":0.0,"bottomRow":430.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Webhook.run().then(() => {\n showAlert('Webhook updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating webhook', 'error');\n});\ncloseModal('ModalWebhook');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.borderRadius"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.webhook_by_events.accentColor"},{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":41.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"webhook_by_events":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_by_events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"webhook_by_events","identifier":"webhook_by_events","position":3.0,"originalIdentifier":"webhook_by_events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook By Events"},"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Text Input","sourceData":"https://webhook.site/06c7b29f-543b-49bc-b598-51bf99d08f6c","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Multiselect","sourceData":["APPLICATION_STARTUP","QRCODE_UPDATED","MESSAGES_SET","MESSAGES_UPSERT","MESSAGES_UPDATE","MESSAGES_DELETE","SEND_MESSAGE","CONTACTS_SET","CONTACTS_UPSERT","CONTACTS_UPDATE","PRESENCE_UPDATE","CHATS_SET","CHATS_UPSERT","CHATS_UPDATE","CHATS_DELETE","GROUPS_UPSERT","GROUP_UPDATE","GROUP_PARTICIPANTS_UPDATE","CONNECTION_UPDATE","CALL"],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebhook","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.webhook_by_events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.url.defaultValue"}],"displayName":"JSON Form","bottomRow":41.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Webhook","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Webhook.data.enabled || false}},\n\t\"url\": {{Find_Webhook.data.url}},\n \"webhook_by_events\": {{Find_Webhook.data.webhook_by_events}},\n \"events\": {{Find_Webhook.data.events || false}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"tb1ekur7fx","minWidth":450.0,"parentId":"mv02ta6pzr","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"mv02ta6pzr","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"0g8ql5hukz","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":430.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"0g8ql5hukz","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalWebsocket","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":42.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":290.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Websocket.run().then(() => {\n showAlert('Websocket updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating websocket', 'error');\n});\ncloseModal('ModalWebsocket');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebsocket.sourceData, FormWebsocket.formData, FormWebsocket.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormWebsocket","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Websocket","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Websocket.data.enabled}},\n \"events\": {{Find_Websocket.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"masqwth5vo","minWidth":450.0,"parentId":"gzf4hjxdo8","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"gzf4hjxdo8","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9twyngcwej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9twyngcwej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalRabbitmq","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":31.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":320.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy1Copy","displayName":"Canvas","topRow":0.0,"bottomRow":320.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Rabbitmq.run().then(() => {\n showAlert('Rabbitmq updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating rabbitmq', 'error');\n});\ncloseModal('ModalRabbitmq');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"sourceData"},{"key":"schema.__root_schema__.children.events.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"schema.__root_schema__.children.events.accentColor"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.children.events.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":30.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"events":{"children":{},"dataType":"array","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.events))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","fieldType":"Multiselect","sourceData":[],"isCustomField":false,"accessor":"events","identifier":"events","position":2.0,"originalIdentifier":"events","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormRabbitmq.sourceData, FormRabbitmq.formData, FormRabbitmq.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Events","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n\n {\n \"label\": \"APPLICATION_STARTUP\",\n \"value\": \"APPLICATION_STARTUP\"\n },\n {\n \"label\": \"QRCODE_UPDATED\",\n \"value\": \"QRCODE_UPDATED\"\n },\n {\n \"label\": \"MESSAGES_SET\",\n \"value\": \"MESSAGES_SET\"\n },\n {\n \"label\": \"MESSAGES_UPSERT\",\n \"value\": \"MESSAGES_UPSERT\"\n },\n {\n \"label\": \"MESSAGES_UPDATE\",\n \"value\": \"MESSAGES_UPDATE\"\n },\n {\n \"label\": \"MESSAGES_DELETE\",\n \"value\": \"MESSAGES_DELETE\"\n },\n {\n \"label\": \"SEND_MESSAGE\",\n \"value\": \"SEND_MESSAGE\"\n },\n {\n \"label\": \"CONTACTS_SET\",\n \"value\": \"CONTACTS_SET\"\n },\n {\n \"label\": \"CONTACTS_UPSERT\",\n \"value\": \"CONTACTS_UPSERT\"\n },\n {\n \"label\": \"CONTACTS_UPDATE\",\n \"value\": \"CONTACTS_UPDATE\"\n },\n {\n \"label\": \"PRESENCE_UPDATE\",\n \"value\": \"PRESENCE_UPDATE\"\n },\n {\n \"label\": \"CHATS_SET\",\n \"value\": \"CHATS_SET\"\n },\n {\n \"label\": \"CHATS_UPSERT\",\n \"value\": \"CHATS_UPSERT\"\n },\n {\n \"label\": \"CHATS_UPDATE\",\n \"value\": \"CHATS_UPDATE\"\n },\n {\n \"label\": \"CHATS_DELETE\",\n \"value\": \"CHATS_DELETE\"\n },\n {\n \"label\": \"GROUPS_UPSERT\",\n \"value\": \"GROUPS_UPSERT\"\n },\n {\n \"label\": \"GROUP_UPDATE\",\n \"value\": \"GROUP_UPDATE\"\n },\n {\n \"label\": \"GROUP_PARTICIPANTS_UPDATE\",\n \"value\": \"GROUP_PARTICIPANTS_UPDATE\"\n },\n {\n \"label\": \"CONNECTION_UPDATE\",\n \"value\": \"CONNECTION_UPDATE\"\n },\n {\n \"label\": \"CALL\",\n \"value\": \"CALL\"\n },\n {\n \"label\": \"NEW_JWT_TOKEN\",\n \"value\": \"NEW_JWT_TOKEN\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormRabbitmq","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.events.defaultValue"}],"displayName":"JSON Form","bottomRow":30.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Rabbitmq","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Rabbitmq.data.enabled || false}},\n \"events\": {{Find_Rabbitmq.data.events || []}} \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"gdkpog7ep5","minWidth":450.0,"parentId":"rkuaegvcin","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"rkuaegvcin","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"76vl08dr1n","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":320.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"76vl08dr1n","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalSettings","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":46.0,"bottomRow":516.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":470.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4Copy","displayName":"Canvas","topRow":0.0,"bottomRow":470.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Settings.run().then(() => {\n showAlert('Settings updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Settings', 'error');\n});\ncloseModal('ModalSettings');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":1.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.read_status.accentColor"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.accentColor"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.always_online.accentColor"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.accentColor"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.accentColor"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"},{"key":"schema.__root_schema__.children.reject_call.accentColor"},{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.msg_call.borderRadius"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":45.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"reject_call":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reject_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reject_call","identifier":"reject_call","position":0.0,"originalIdentifier":"reject_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reject Call"},"msg_call":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.msg_call))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Text Input","sourceData":"Não aceitamos chamadas!","isCustomField":false,"accessor":"msg_call","identifier":"msg_call","position":1.0,"originalIdentifier":"msg_call","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Msg Call"},"groups_ignore":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.groups_ignore))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"groups_ignore","identifier":"groups_ignore","position":2.0,"originalIdentifier":"groups_ignore","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Groups Ignore"},"always_online":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.always_online))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"always_online","identifier":"always_online","position":3.0,"originalIdentifier":"always_online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Always Online"},"read_messages":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_messages))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"read_messages","identifier":"read_messages","position":4.0,"originalIdentifier":"read_messages","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Messages"},"read_status":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.read_status))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"read_status","identifier":"read_status","position":5.0,"originalIdentifier":"read_status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormSettings.sourceData, FormSettings.formData, FormSettings.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Read Status"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormSettings","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.reject_call.defaultValue"},{"key":"schema.__root_schema__.children.groups_ignore.defaultValue"},{"key":"schema.__root_schema__.children.always_online.defaultValue"},{"key":"schema.__root_schema__.children.read_messages.defaultValue"},{"key":"schema.__root_schema__.children.read_status.defaultValue"},{"key":"schema.__root_schema__.children.msg_call.defaultValue"}],"displayName":"JSON Form","bottomRow":45.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Settings","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"reject_call\": {{Find_Settings.data.reject_call || false}},\n \"msg_call\": {{Find_Settings.data.msg_call}},\n \"groups_ignore\": {{Find_Settings.data.groups_ignore || false}},\n \"always_online\": {{Find_Settings.data.always_online || false}},\n \"read_messages\": {{Find_Settings.data.read_messages || false}},\n \"read_status\": {{Find_Settings.data.read_status || false}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"3wajdobhry","minWidth":450.0,"parentId":"bj66ktxeor","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bj66ktxeor","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"9pvl5efylb","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":470.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"9pvl5efylb","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalChatwoot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":50.0,"bottomRow":780.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":730.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":730.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Chatwoot.run().then(() => {\n showAlert('Chatwoot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Chatwoot', 'error');\n});\ncloseModal('ModalChatwoot');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"schema.__root_schema__.children.conversation_pending.accentColor"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.accentColor"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.accentColor"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.token.borderRadius"},{"key":"schema.__root_schema__.children.token.accentColor"},{"key":"schema.__root_schema__.children.token.defaultValue"},{"key":"schema.__root_schema__.children.account_id.accentColor"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.account_id.borderRadius"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.accentColor"},{"key":"schema.__root_schema__.children.webhook_url.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.name_inbox.defaultValue"},{"key":"schema.__root_schema__.children.name_inbox.borderRadius"},{"key":"schema.__root_schema__.children.name_inbox.accentColor"},{"key":"submitButtonStyles.buttonColor"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":71.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"account_id":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.account_id))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"1","isCustomField":false,"accessor":"account_id","identifier":"account_id","position":1.0,"originalIdentifier":"account_id","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Account Id"},"token":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.token))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Password Input","sourceData":"uHquVJgCdkee8JPJm9YBkdH6","isCustomField":false,"accessor":"token","identifier":"token","position":2.0,"originalIdentifier":"token","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Token","shouldAllowAutofill":true},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chatwoot.evolution.dgcode.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":3.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"sign_msg":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.sign_msg))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"sign_msg","identifier":"sign_msg","position":4.0,"originalIdentifier":"sign_msg","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Sign Msg"},"reopen_conversation":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.reopen_conversation))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"reopen_conversation","identifier":"reopen_conversation","position":5.0,"originalIdentifier":"reopen_conversation","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Reopen Conversation"},"conversation_pending":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.conversation_pending))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Switch","sourceData":false,"isCustomField":false,"accessor":"conversation_pending","identifier":"conversation_pending","position":6.0,"originalIdentifier":"conversation_pending","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Conversation Pending"},"webhook_url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.webhook_url))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"https://api.evolution.dgcode.com.br/chatwoot/webhook/evolution-cwId-4","isCustomField":false,"accessor":"webhook_url","identifier":"webhook_url","position":8.0,"originalIdentifier":"webhook_url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Webhook Url"},"name_inbox":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.name_inbox))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","fieldType":"Text Input","sourceData":"evolution-cwId-4","isCustomField":false,"accessor":"name_inbox","identifier":"name_inbox","position":7.0,"originalIdentifier":"name_inbox","accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormChatwoot.sourceData, FormChatwoot.formData, FormChatwoot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":true,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Name Inbox"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormWebhook.sourceData, FormWebhook.formData, FormWebhook.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormChatwoot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":71.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Chatwoot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Chatwoot.data.enabled || false}},\n\t\"account_id\": {{Find_Chatwoot.data.account_id}},\n \"token\": {{Find_Chatwoot.data.token}},\n \"url\": {{Find_Chatwoot.data.url}},\n \"sign_msg\": {{Find_Chatwoot.data.sign_msg || false}},\n \"reopen_conversation\": {{Find_Chatwoot.data.reopen_conversation || false}},\n \"conversation_pending\": {{Find_Chatwoot.data.conversation_pending || false}},\n\t\t\"name_inbox\": {{Find_Chatwoot.data.name_inbox}},\n\t\t\"webhook_url\": {{Find_Chatwoot.data.webhook_url}}\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"c5v1lwuyrk","minWidth":450.0,"parentId":"wqoo05rt9h","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"wqoo05rt9h","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"kekx3o71p4","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":730.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"kekx3o71p4","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalTypebot","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":45.0,"bottomRow":665.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":620.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":620.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_Typebot.run().then(() => {\n showAlert('Typebot updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Typebot', 'error');\n});\ncloseModal('ModalTypebot');}}","topRow":1.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.enabled.accentColor"},{"key":"schema.__root_schema__.children.url.defaultValue"},{"key":"schema.__root_schema__.children.url.accentColor"},{"key":"schema.__root_schema__.children.url.borderRadius"},{"key":"schema.__root_schema__.children.typebot.defaultValue"},{"key":"schema.__root_schema__.children.typebot.accentColor"},{"key":"schema.__root_schema__.children.typebot.borderRadius"},{"key":"schema.__root_schema__.children.expire.defaultValue"},{"key":"schema.__root_schema__.children.expire.accentColor"},{"key":"schema.__root_schema__.children.expire.borderRadius"},{"key":"schema.__root_schema__.children.keyword_finish.defaultValue"},{"key":"schema.__root_schema__.children.keyword_finish.accentColor"},{"key":"schema.__root_schema__.children.keyword_finish.borderRadius"},{"key":"schema.__root_schema__.children.delay_message.defaultValue"},{"key":"schema.__root_schema__.children.delay_message.accentColor"},{"key":"schema.__root_schema__.children.delay_message.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":68.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"enabled":{"children":{},"dataType":"boolean","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.enabled))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Switch","sourceData":true,"isCustomField":false,"accessor":"enabled","identifier":"enabled","position":0.0,"originalIdentifier":"enabled","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","alignWidget":"LEFT","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Enabled"},"url":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.url))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"https://chat2.manualnegocioonline.com.br","isCustomField":false,"accessor":"url","identifier":"url","position":1.0,"originalIdentifier":"url","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Url"},"typebot":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.typebot))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","isCustomField":false,"accessor":"typebot","identifier":"typebot","position":2.0,"originalIdentifier":"typebot","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Typebot"},"expire":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.expire))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Number Input","sourceData":20.0,"isCustomField":false,"accessor":"expire","identifier":"expire","position":3.0,"originalIdentifier":"expire","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Expire"},"keyword_finish":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.keyword_finish))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Text Input","sourceData":"#SAIR","isCustomField":false,"accessor":"keyword_finish","identifier":"keyword_finish","position":4.0,"originalIdentifier":"keyword_finish","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Keyword Finish"},"delay_message":{"children":{},"dataType":"number","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.delay_message))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Number Input","sourceData":3000.0,"isCustomField":false,"accessor":"delay_message","identifier":"delay_message","position":5.0,"originalIdentifier":"delay_message","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Delay Message"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Object","sourceData":{"enabled":true,"url":"https://chat2.manualnegocioonline.com.br","typebot":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","expire":20.0,"keyword_finish":"#SAIR","delay_message":3000.0,"unknown_message":"Mensagem não reconhecida2"},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormTypebot","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.enabled.defaultValue"},{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":60.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Set Typebot","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"enabled\": {{Find_Typebot.data.enabled || false}},\n \"url\": {{Find_Typebot.data.url}},\n \"typebot\": {{Find_Typebot.data.typebot}},\n \"expire\": {{Find_Typebot.data.expire}},\n \"keyword_finish\": {{Find_Typebot.data.keyword_finish}},\n \"delay_message\": {{Find_Typebot.data.delay_message}}\n \n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"fyu0oxvlx7","minWidth":450.0,"parentId":"bvxewkusbf","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":1.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"bvxewkusbf","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"4n3m0wo9tx","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":620.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"4n3m0wo9tx","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"boxShadow":"none","mobileBottomRow":70.0,"widgetName":"ModalTypebotChangeSessionStatu","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":45.0,"bottomRow":415.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":370.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas4CopyCopyCopyCopy","displayName":"Canvas","topRow":0.0,"bottomRow":370.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":730.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Set_TypebotChangeSessionStatus.run().then(() => {\n showAlert('Typebot Change Session updated successfully', 'success');\n}).catch(() => {\n showAlert('Error updating Session Typebot', 'error');\n});\ncloseModal('ModalTypebotChangeSessionStatu');}}","topRow":1.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.remoteJid.defaultValue"},{"key":"schema.__root_schema__.children.remoteJid.accentColor"},{"key":"schema.__root_schema__.children.remoteJid.borderRadius"},{"key":"schema.__root_schema__.children.status.defaultValue"},{"key":"schema.__root_schema__.children.status.accentColor"},{"key":"schema.__root_schema__.children.status.borderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":60.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"remoteJid":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.remoteJid))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"remoteJid","identifier":"remoteJid","position":0.0,"originalIdentifier":"remoteJid","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":true,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Remote Jid (WhatsApp. Ex: 5511968162699@s.whatsapp.net)"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.status))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"status","identifier":"status","position":1.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebotChangeSessionStatus.sourceData, FormTypebotChangeSessionStatus.formData, FormTypebotChangeSessionStatus.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Status (opened, paused or closed)"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","fieldType":"Object","sourceData":{"enabled":true,"url":"https://chat2.manualnegocioonline.com.br","typebot":"francis-whatsapp-pesquisa-satisfacao-copy-copy-74fk24p","expire":20.0,"keyword_finish":"#SAIR","delay_message":3000.0,"unknown_message":"Mensagem não reconhecida2"},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormTypebot.sourceData, FormTypebot.formData, FormTypebot.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormTypebotChangeSessionStatus","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[{"key":"schema.__root_schema__.children.sign_msg.defaultValue"},{"key":"schema.__root_schema__.children.reopen_conversation.defaultValue"},{"key":"schema.__root_schema__.children.conversation_pending.defaultValue"},{"key":"schema.__root_schema__.children.account_id.defaultValue"},{"key":"schema.__root_schema__.children.webhook_url.defaultValue"}],"displayName":"JSON Form","bottomRow":35.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Typebot Change Session Status","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n \"remoteJid\": \"@s.whatsapp.net\",\n \"status\": \"\"\n}","resetButtonLabel":"Reset","key":"lgqqk5r1jk","backgroundColor":"#fff","isDeprecated":false,"rightColumn":63.0,"widgetId":"28lli5jdvr","minWidth":450.0,"parentId":"8m0yhclt7g","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":1.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"svq68rvpdn","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"8m0yhclt7g","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"84rj87eew6","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"6x3z5yow7u","height":370.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"84rj87eew6","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":692.0,"minDynamicHeight":24.0},{"resetFormOnClick":false,"boxShadow":"none","mobileBottomRow":50.0,"widgetName":"Button2","onClick":"{{Fetch_Instance.run();\nFetch_PrivacySettings.run();\nshowModal('ModalProfile');}}","buttonColor":"#2770fc","dynamicPropertyPathList":[{"key":"isVisible"}],"displayName":"Button","iconSVG":"/static/media/icon.7beb9123fb53027d9d6b778cdfe4caed.svg","searchTags":["click","submit"],"topRow":28.0,"bottomRow":32.0,"parentRowSpace":10.0,"type":"BUTTON_WIDGET","hideCard":false,"mobileRightColumn":21.0,"animateLoading":true,"parentColumnSpace":17.9375,"dynamicTriggerPathList":[{"key":"onClick"}],"leftColumn":1.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"isVisible"}],"text":"Edit Profile","isDisabled":false,"key":"zhd9fobc1z","isDeprecated":false,"rightColumn":13.0,"isDefaultClickDisabled":true,"iconName":"edit","widgetId":"uh6430ysqy","minWidth":120.0,"isVisible":"{{appsmith.store.api_key && appsmith.store.api_url ? TableInstances.selectedRow.instance ? TableInstances.selectedRow.Status === 'open' ? true : false : false : false}}","recaptchaType":"V3","version":1.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":46.0,"responsiveBehavior":"hug","originalTopRow":51.0,"disabledWhenInvalid":false,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":5.0,"originalBottomRow":55.0,"buttonVariant":"PRIMARY","iconAlign":"left","placement":"CENTER"},{"boxShadow":"none","mobileBottomRow":59.0,"widgetName":"ModalProfile","isCanvas":true,"displayName":"Modal","iconSVG":"/static/media/icon.d2ab7de0666eaef853cc2d330f86887b.svg","searchTags":["dialog","popup","notification"],"topRow":35.0,"bottomRow":975.0,"parentRowSpace":10.0,"type":"MODAL_WIDGET","hideCard":false,"shouldScrollContents":true,"mobileRightColumn":35.0,"minHeight":940.0,"animateLoading":true,"parentColumnSpace":17.9375,"leftColumn":11.0,"dynamicBindingPathList":[{"key":"borderRadius"}],"children":[{"mobileBottomRow":240.0,"widgetName":"Canvas5","displayName":"Canvas","topRow":0.0,"bottomRow":940.0,"parentRowSpace":1.0,"type":"CANVAS_WIDGET","canExtend":true,"hideCard":true,"shouldScrollContents":false,"minHeight":240.0,"mobileRightColumn":430.5,"parentColumnSpace":1.0,"leftColumn":0.0,"dynamicBindingPathList":[],"children":[{"boxShadow":"none","borderColor":"#E0DEDE","iconSVG":"/static/media/icon.efac588608711d232f1c6c8a2144d2dd.svg","onSubmit":"{{Update_ProfileName.run().then(() => {\n showAlert('ProfileName successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileName', 'error');\n});\nUpdate_ProfilePicture.run().then(() => {\n showAlert('ProfilePicture successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfilePicture', 'error');\n});\nUpdate_ProfileStatus.run().then(() => {\n showAlert('ProfileStatus successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating ProfileStatus', 'error');\n});\nUpdate_PrivacySettings.run().then(() => {\n showAlert('PrivacySttings successfully saved!', 'success');\n}).catch(() => {\n showAlert('Error updating PrivacySttings', 'error');\n});\nfetch_Instances.run();\ncloseModal('ModalProfile');}}","topRow":0.0,"type":"JSON_FORM_WIDGET","animateLoading":true,"leftColumn":0.0,"dynamicBindingPathList":[{"key":"borderRadius"},{"key":"submitButtonStyles.buttonColor"},{"key":"submitButtonStyles.borderRadius"},{"key":"resetButtonStyles.buttonColor"},{"key":"resetButtonStyles.borderRadius"},{"key":"schema.__root_schema__.defaultValue"},{"key":"schema.__root_schema__.borderRadius"},{"key":"schema.__root_schema__.cellBorderRadius"},{"key":"schema.__root_schema__.children.profileName.defaultValue"},{"key":"schema.__root_schema__.children.profileName.accentColor"},{"key":"schema.__root_schema__.children.profileName.borderRadius"},{"key":"schema.__root_schema__.children.profileStatus.defaultValue"},{"key":"schema.__root_schema__.children.profileStatus.accentColor"},{"key":"schema.__root_schema__.children.profileStatus.borderRadius"},{"key":"schema.__root_schema__.children.profilePictureUrl.defaultValue"},{"key":"schema.__root_schema__.children.profilePictureUrl.borderRadius"},{"key":"sourceData"},{"key":"schema.__root_schema__.children.profilePictureUrl.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.readreceipts.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.profile.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.status.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.status.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.status.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.online.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.online.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.online.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.last.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.last.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.last.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.accentColor"},{"key":"schema.__root_schema__.children.privacySettings.children.groupadd.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.defaultValue"},{"key":"schema.__root_schema__.children.privacySettings.borderRadius"},{"key":"schema.__root_schema__.children.privacySettings.cellBorderRadius"}],"showReset":false,"dynamicHeight":"AUTO_HEIGHT","autoGenerateForm":true,"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"SECONDARY"},"isVisible":true,"version":1.0,"isLoading":false,"submitButtonLabel":"Save","childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}},"disabledWhenInvalid":true,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","originalBottomRow":92.0,"useSourceData":false,"schema":{"__root_schema__":{"children":{"profileName":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileName))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileName","identifier":"profileName","position":1.0,"originalIdentifier":"profileName","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Name"},"profileStatus":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profileStatus))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"","isCustomField":false,"accessor":"profileStatus","identifier":"profileStatus","position":2.0,"originalIdentifier":"profileStatus","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Status"},"profilePictureUrl":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.profilePictureUrl))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Text Input","sourceData":"https://pps.whatsapp.net/v/t61.24694-24/359816109_329991892684302_7466658594467953893_n.jpg?ccb=11-4&oh=01_AdTpgc4O-xiZDr2v0OLu_jssxaw8dsws819srLMOzUwEnw&oe=64D3C41E","isCustomField":false,"accessor":"profilePictureUrl","identifier":"profilePictureUrl","position":0.0,"originalIdentifier":"profilePictureUrl","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","iconAlign":"left","isDisabled":false,"isRequired":false,"isSpellCheck":false,"isVisible":true,"labelTextSize":"0.875rem","label":"Profile Picture Url"},"privacySettings":{"children":{"readreceipts":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.readreceipts))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"readreceipts","identifier":"readreceipts","position":0.0,"originalIdentifier":"readreceipts","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Readreceipts","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"profile":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.profile))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"profile","identifier":"profile","position":1.0,"originalIdentifier":"profile","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Profile","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"status":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.status))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"status","identifier":"status","position":2.0,"originalIdentifier":"status","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Status","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"online":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.online))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"online","identifier":"online","position":3.0,"originalIdentifier":"online","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Online","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"match_last_seen\",\n \"value\": \"match_last_seen\"\n }\n]"},"last":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.last))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"contacts","isCustomField":false,"accessor":"last","identifier":"last","position":4.0,"originalIdentifier":"last","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Last","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"},"groupadd":{"children":{},"dataType":"string","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings.groupadd))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Select","sourceData":"all","isCustomField":false,"accessor":"groupadd","identifier":"groupadd","position":5.0,"originalIdentifier":"groupadd","accentColor":"{{((sourceData, formData, fieldState) => ((appsmith.theme.colors.primaryColor)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","isDisabled":false,"isFilterable":false,"isRequired":false,"isVisible":true,"label":"Groupadd","labelTextSize":"0.875rem","serverSideFiltering":false,"options":"[\n {\n \"label\": \"all\",\n \"value\": \"all\"\n },\n {\n \"label\": \"contacts\",\n \"value\": \"contacts\"\n },\n {\n \"label\": \"contact_blacklist\",\n \"value\": \"contact_blacklist\"\n },\n {\n \"label\": \"none\",\n \"value\": \"none\"\n }\n]"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData.privacySettings))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"readreceipts":"all","profile":"all","status":"contacts","online":"all","last":"contacts","groupadd":"all"},"isCustomField":false,"accessor":"privacySettings","identifier":"privacySettings","position":3.0,"originalIdentifier":"privacySettings","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"1rem","label":"Privacy Settings","labelStyle":"BOLD"}},"dataType":"object","defaultValue":"{{((sourceData, formData, fieldState) => (sourceData))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","fieldType":"Object","sourceData":{"name":"John","date_of_birth":"20/02/1990","employee_id":1001.0},"isCustomField":false,"accessor":"__root_schema__","identifier":"__root_schema__","position":-1.0,"originalIdentifier":"__root_schema__","borderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","boxShadow":"none","cellBorderRadius":"{{((sourceData, formData, fieldState) => ((appsmith.theme.borderRadius.appBorderRadius)))(FormProfile.sourceData, FormProfile.formData, FormProfile.fieldState)}}","cellBoxShadow":"none","isDisabled":false,"isRequired":false,"isVisible":true,"labelTextSize":"0.875rem","label":""}},"mobileBottomRow":41.0,"widgetName":"FormProfile","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","buttonVariant":"PRIMARY"},"dynamicPropertyPathList":[],"displayName":"JSON Form","bottomRow":92.0,"fieldLimitExceeded":false,"parentRowSpace":10.0,"title":"Edit Profile","hideCard":false,"mobileRightColumn":25.0,"parentColumnSpace":6.9375,"dynamicTriggerPathList":[{"key":"onSubmit"}],"borderWidth":"0","sourceData":"{\n\t\"profilePictureUrl\": \"{{Fetch_Instance.data.instance.profilePictureUrl}}\",\n\t\"profileName\": \"{{Fetch_Instance.data.instance.profileName}}\",\n\t\"profileStatus\": \"{{Fetch_Instance.data.instance.profileStatus}}\",\n\t\"privacySettings\": {\n \"readreceipts\": {{Fetch_PrivacySettings.data.readreceipts}},\n \"profile\": {{Fetch_PrivacySettings.data.profile}},\n \"status\": {{Fetch_PrivacySettings.data.status}},\n \"online\": {{Fetch_PrivacySettings.data.online}},\n \"last\": {{Fetch_PrivacySettings.data.last}},\n \"groupadd\": {{Fetch_PrivacySettings.data.groupadd}}\n\t\t}\n}","resetButtonLabel":"","key":"72nqor459k","backgroundColor":"#fff","isDeprecated":false,"rightColumn":64.0,"widgetId":"hguxefink2","minWidth":450.0,"parentId":"basosxf5qt","renderMode":"CANVAS","mobileTopRow":0.0,"scrollContents":true,"responsiveBehavior":"fill","fixedFooter":true,"originalTopRow":0.0,"mobileLeftColumn":0.0,"maxDynamicHeight":9000.0,"minDynamicHeight":4.0}],"isDisabled":false,"key":"mepf0qsn1e","isDeprecated":false,"rightColumn":430.5,"detachFromLayout":true,"widgetId":"basosxf5qt","minWidth":450.0,"isVisible":true,"version":1.0,"parentId":"ss96aihlej","renderMode":"CANVAS","isLoading":false,"mobileTopRow":0.0,"responsiveBehavior":"fill","mobileLeftColumn":0.0,"flexLayers":[]}],"key":"4ktj7iym0b","height":940.0,"isDeprecated":false,"rightColumn":35.0,"detachFromLayout":true,"dynamicHeight":"AUTO_HEIGHT","widgetId":"ss96aihlej","canOutsideClickClose":true,"canEscapeKeyClose":true,"version":2.0,"parentId":"0","renderMode":"CANVAS","isLoading":false,"mobileTopRow":35.0,"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","mobileLeftColumn":11.0,"maxDynamicHeight":9000.0,"width":456.0,"minDynamicHeight":24.0}]},"layoutOnLoadActions":[[{"id":"Home_Scripts.verifyConfig","name":"Scripts.verifyConfig","collectionId":"Home_Scripts","clientSideExecution":true,"confirmBeforeExecute":false,"pluginType":"JS","jsonPathKeys":[],"timeoutInMillisecond":10000.0}],[{"id":"Home_Find_Rabbitmq","name":"Find_Rabbitmq","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0},{"id":"Home_Find_Websocket","name":"Find_Websocket","confirmBeforeExecute":false,"pluginType":"API","jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"timeoutInMillisecond":10000.0}]],"layoutOnLoadActionErrors":[],"validOnPageLoadActions":true,"id":"Home","deleted":false,"policies":[],"userPermissions":[]}],"userPermissions":[],"policies":[],"isHidden":false},"deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b0"}],"actionList":[{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"publishedAction":{"name":"Restart","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/restart/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:01:05Z"},"id":"Home_Restart","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b4"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"publishedAction":{"name":"Create_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/create","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n}}","bodyFormData":[{"key":"instanceName","value":"{{FormInstance.data.InputNewInstanceName}}"},{"key":"token","value":"{{FormInstance.data.InputNewInstanceToken}}"}],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"bodyFormData[0].value"},{"key":"bodyFormData[1].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["\n\t{\n\t\t\"instanceName\": FormInstance.formData.instance.instanceName,\n\t\t\"token\": FormInstance.formData.instance.token,\n\t\t\"qrcode\": FormInstance.formData.instance.qrcode,\n\t\t\"webhook\": FormInstance.formData.webhook.webhook,\n\t\t\"webhook_by_events\": FormInstance.formData.webhook.webhook_by_events,\n\t\t\"websocket_enabled\": FormInstance.formData.websocket.websocket_enabled,\n\t\t\"websocket_events\": FormInstance.formData.websocket.websocket_events,\n\t\t\"rabbitmq_enabled\": FormInstance.formData.websocket.rabbitmq_enabled,\n\t\t\"rabbitmq_events\": FormInstance.formData.websocket.rabbitmq_events,\n\t\t\"events\": FormInstance.formData.webhook.events,\n\t\t\"reject_call\": FormInstance.formData.settings.reject_call,\n\t\t\"msg_call\": FormInstance.formData.settings.msg_call,\n\t\t\"groups_ignore\": FormInstance.formData.settings.groups_ignore,\n\t\t\"always_online\": FormInstance.formData.settings.always_online,\n\t\t\"read_messages\": FormInstance.formData.settings.read_messages,\n\t\t\"read_status\": FormInstance.formData.settings.read_status,\n\t\t\"chatwoot_account_id\": FormInstance.formData.chatwoot.chatwoot_account_id,\n\t\t\"chatwoot_token\": FormInstance.formData.chatwoot.chatwoot_token,\n\t\t\"chatwoot_url\": FormInstance.formData.chatwoot.chatwoot_url,\n\t\t\"chatwoot_sign_msg\": FormInstance.formData.chatwoot.chatwoot_sign_msg,\n\t\t\"chatwoot_reopen_conversation\": FormInstance.formData.chatwoot.chatwoot_reopen_conversation,\n\t\t\"chatwoot_conversation_pending\": FormInstance.formData.chatwoot.chatwoot_conversation_pending\n\t}\n","FormInstance.data.InputNewInstanceName","FormInstance.data.InputNewInstanceToken","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:22:09Z"},"id":"Home_Create_Instance","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b3"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"publishedAction":{"name":"Find_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:49:33Z"},"id":"Home_Find_Chatwoot","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b5"},{"pluginType":"JS","pluginId":"js-plugin","unpublishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":[],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"verifyConfig","fullyQualifiedName":"Scripts.verifyConfig","datasource":{"name":"UNUSED_DATASOURCE","pluginId":"js-plugin","invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","collectionId":"Home_Scripts","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","encodeParamsToggle":true,"body":"async function () {\n const api_url = await appsmith.store.api_url;\n const api_key = await appsmith.store.api_key;\n if (!api_url && !api_key) {\n showModal('ModalConfig');\n return false;\n }\n fetch_Instances.run();\n Find_Webhook.run();\n Find_Settings.run();\n Find_Chatwoot.run();\n return true;\n}","selfReferencingDataPaths":[],"jsArguments":[],"isAsync":true},"executeOnLoad":true,"clientSideExecution":true,"dynamicBindingPathList":[{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":[],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Scripts.verifyConfig","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b2"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"publishedAction":{"name":"Find_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:48:45Z"},"id":"Home_Find_Settings","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b9"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"fetch_Instances","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_fetch_Instances","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"publishedAction":{"name":"Connect","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/connect/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-29T16:12:42Z"},"id":"Home_Connect","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7ba"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"publishedAction":{"name":"Delete","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/delete/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:32Z"},"id":"Home_Delete","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b7"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"publishedAction":{"name":"Logout","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/logout/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","appsmith.store.api_key"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T03:02:00Z"},"id":"Home_Logout","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7b8"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"publishedAction":{"name":"Find_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T19:46:50Z"},"id":"Home_Find_Webhook","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7c5"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"publishedAction":{"name":"Find_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:16Z"},"id":"Home_Find_Rabbitmq","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7c1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"publishedAction":{"name":"Set_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebsocket.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebsocket.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:55:30Z"},"id":"Home_Set_Websocket","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7bd"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"publishedAction":{"name":"Update_ProfileName","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileName/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"name\": FormProfile.formData.profileName\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:22:45Z"},"id":"Home_Update_ProfileName","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7bb"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"publishedAction":{"name":"Update_ProfileStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfileStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"body"},{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"status\": FormProfile.formData.profileStatus\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:00Z"},"id":"Home_Update_ProfileStatus","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b37fa2945b083c5bc7c6"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"publishedAction":{"name":"Set_Settings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/settings/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormSettings.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"application/json"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url","\n\tFormSettings.formData\n"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:13:25Z"},"id":"Home_Set_Settings","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7ce"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"publishedAction":{"name":"Set_Chatwoot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chatwoot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"enabled\": FormChatwoot.formData.enabled,\n\t\t\"account_id\": String(FormChatwoot.formData.account_id),\n\t\t\"token\": FormChatwoot.formData.token,\n\t\t\"url\": FormChatwoot.formData.url,\n\t\t\"sign_msg\": FormChatwoot.formData.sign_msg,\n\t\t\"reopen_conversation\": FormChatwoot.formData.reopen_conversation,\n\t\t\"conversation_pending\": FormChatwoot.formData.conversation_pending\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:15:01Z"},"id":"Home_Set_Chatwoot","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d0"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"publishedAction":{"name":"Fetch_Instance","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/instance/fetchInstances","headers":[{"key":"apikey","value":"{{appsmith.store.api_key}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[{"key":"instanceName","value":"{{TableInstances.selectedRow.instance}}"}],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"queryParameters[0].value"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["appsmith.store.api_url","appsmith.store.api_key","TableInstances.selectedRow.instance"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:16:40Z"},"id":"Home_Fetch_Instance","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7cf"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"publishedAction":{"name":"Remove_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/removeProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"","bodyFormData":[],"httpMethod":"DELETE","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:20Z"},"id":"Home_Remove_ProfilePicture","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d4"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"publishedAction":{"name":"Set_Webhook","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/webhook/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormWebhook.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormWebhook.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-30T20:10:19Z"},"id":"Home_Set_Webhook","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d5"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"publishedAction":{"name":"Update_ProfilePicture","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updateProfilePicture/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n\t\t\"picture\": FormProfile.formData.profilePictureUrl\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:25:56Z"},"id":"Home_Update_ProfilePicture","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d1"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_TypebotChangeSessionStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/changeStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n{\n \"remoteJid\": FormTypebotChangeSessionStatus.formData.remoteJid,\n \"status\": FormTypebotChangeSessionStatus.formData.status\n}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"path"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","\n{\n \"remoteJid\": FormTypebotChangeSessionStatus.formData.remoteJid,\n \"status\": FormTypebotChangeSessionStatus.formData.status\n}\n","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T11:28:01Z"},"publishedAction":{"name":"Set_TypebotChangeSessionStatus","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/changeStatus/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n{\n \"remoteJid\": FormTypebotChangeSessionStatus.formData.remoteJid,\n \"status\": FormTypebotChangeSessionStatus.formData.status\n}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"path"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","\n{\n \"remoteJid\": FormTypebotChangeSessionStatus.formData.remoteJid,\n \"status\": FormTypebotChangeSessionStatus.formData.status\n}\n","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T11:28:01Z"},"id":"Home_Set_TypebotChangeSessionStatus","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d2"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Typebot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormTypebot.formData.enabled,\n\t\t\"url\": (FormTypebot.formData.url),\n\t\t\"typebot\": FormTypebot.formData.typebot,\n\t\t\"expire\": FormTypebot.formData.expire,\n\t\t\"keyword_finish\": FormTypebot.formData.keyword_finish,\n\t\t\"delay_message\": FormTypebot.formData.delay_message,\n\t\t\"unknown_messageg\": FormTypebot.formData.cunknown_messageg\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"path"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","\n\t{\n\t\t\"enabled\": FormTypebot.formData.enabled,\n\t\t\"url\": (FormTypebot.formData.url),\n\t\t\"typebot\": FormTypebot.formData.typebot,\n\t\t\"expire\": FormTypebot.formData.expire,\n\t\t\"keyword_finish\": FormTypebot.formData.keyword_finish,\n\t\t\"delay_message\": FormTypebot.formData.delay_message,\n\t\t\"unknown_messageg\": FormTypebot.formData.cunknown_messageg\n\t}\n","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T05:00:46Z"},"publishedAction":{"name":"Set_Typebot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n\t\t\"enabled\": FormTypebot.formData.enabled,\n\t\t\"url\": (FormTypebot.formData.url),\n\t\t\"typebot\": FormTypebot.formData.typebot,\n\t\t\"expire\": FormTypebot.formData.expire,\n\t\t\"keyword_finish\": FormTypebot.formData.keyword_finish,\n\t\t\"delay_message\": FormTypebot.formData.delay_message,\n\t\t\"unknown_messageg\": FormTypebot.formData.cunknown_messageg\n\t}\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"path"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","\n\t{\n\t\t\"enabled\": FormTypebot.formData.enabled,\n\t\t\"url\": (FormTypebot.formData.url),\n\t\t\"typebot\": FormTypebot.formData.typebot,\n\t\t\"expire\": FormTypebot.formData.expire,\n\t\t\"keyword_finish\": FormTypebot.formData.keyword_finish,\n\t\t\"delay_message\": FormTypebot.formData.delay_message,\n\t\t\"unknown_messageg\": FormTypebot.formData.cunknown_messageg\n\t}\n","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T05:00:46Z"},"id":"Home_Set_Typebot","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d9"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"publishedAction":{"name":"Find_Websocket","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/websocket/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":true,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:54:48Z"},"id":"Home_Find_Websocket","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7d8"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"publishedAction":{"name":"Fetch_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/fetchPrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:27:52Z"},"id":"Home_Fetch_PrivacySettings","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7dd"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"publishedAction":{"name":"Set_Rabbitmq","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/rabbitmq/set/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\tFormRabbitmq.formData\n}}","bodyFormData":[],"httpMethod":"POST","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"},{"key":"body"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\tFormRabbitmq.formData\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-03T00:56:01Z"},"id":"Home_Set_Rabbitmq","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7de"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"publishedAction":{"name":"Update_PrivacySettings","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/chat/updatePrivacySettings/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[{"key":"content-type","value":"application/json"}],"encodeParamsToggle":true,"queryParameters":[],"body":"{{\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n}}","bodyFormData":[],"httpMethod":"PUT","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"headers[0].value"},{"key":"body"},{"key":"path"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","\n\t{\n \"privacySettings\": {\n \"readreceipts\": FormProfile.formData.privacySettings.readreceipts,\n \"profile\": FormProfile.formData.privacySettings.profile,\n \"status\": FormProfile.formData.privacySettings.status,\n \"online\": FormProfile.formData.privacySettings.online,\n \"last\": FormProfile.formData.privacySettings.last,\n \"groupadd\": FormProfile.formData.privacySettings.groupadd\n\t\t}\n\t}\n","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":false,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-07-31T12:28:39Z"},"id":"Home_Update_PrivacySettings","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7db"},{"pluginType":"API","pluginId":"restapi-plugin","unpublishedAction":{"name":"Find_Typebot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T03:57:40Z"},"publishedAction":{"name":"Find_Typebot","datasource":{"name":"DEFAULT_REST_DATASOURCE","pluginId":"restapi-plugin","datasourceConfiguration":{"url":""},"invalids":[],"messages":[],"isAutoGenerated":false,"deleted":false,"policies":[],"userPermissions":[]},"pageId":"Home","actionConfiguration":{"timeoutInMillisecond":10000.0,"paginationType":"NONE","path":"{{appsmith.store.api_url}}/typebot/find/{{encodeURIComponent(TableInstances.selectedRow.instance)}}","headers":[{"key":"apikey","value":"{{TableInstances.selectedRow.Apikey}}"}],"autoGeneratedHeaders":[],"encodeParamsToggle":true,"queryParameters":[],"bodyFormData":[],"httpMethod":"GET","selfReferencingDataPaths":[],"pluginSpecifiedTemplates":[{"value":true}],"formData":{"apiContentType":"none"}},"executeOnLoad":false,"dynamicBindingPathList":[{"key":"path"},{"key":"headers[0].value"}],"isValid":true,"invalids":[],"messages":[],"jsonPathKeys":["TableInstances.selectedRow.Apikey","encodeURIComponent(TableInstances.selectedRow.instance)","appsmith.store.api_url"],"userSetOnLoad":true,"confirmBeforeExecute":false,"policies":[],"userPermissions":[],"createdAt":"2023-08-19T03:57:40Z"},"id":"Home_Find_Typebot","deleted":false,"gitSyncId":"64e0b37fa2945b083c5bc7ac_64e0b380a2945b083c5bc7e3"}],"actionCollectionList":[{"unpublishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"publishedCollection":{"name":"Scripts","pageId":"Home","pluginId":"js-plugin","pluginType":"JS","actions":[],"archivedActions":[],"body":"export default {\n\tmyVar1: [],\n\tmyVar2: {},\n\tasync verifyConfig () {\n\t\tconst api_url = await appsmith.store.api_url;\n\t\tconst api_key = await appsmith.store.api_key;\n\t\tif(!api_url && !api_key){\n\t\t\tshowModal('ModalConfig');\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tfetch_Instances.run();\n\t\tFind_Webhook.run();\n\t\tFind_Settings.run();\n\t\tFind_Chatwoot.run();\n\t\treturn true;\n\t}\n}","variables":[{"name":"myVar1","value":"[]"},{"name":"myVar2","value":"{}"}],"userPermissions":[]},"id":"Home_Scripts","deleted":false,"gitSyncId":"64c534835ebbd221b60b4c54_64c5372a5dd3482b9ab5e11e"}],"updatedResources":{"customJSLibList":[],"actionList":["Scripts.verifyConfig##ENTITY_SEPARATOR##Home","Logout##ENTITY_SEPARATOR##Home","Fetch_Instance##ENTITY_SEPARATOR##Home","Set_Websocket##ENTITY_SEPARATOR##Home","Update_ProfileName##ENTITY_SEPARATOR##Home","Set_Chatwoot##ENTITY_SEPARATOR##Home","Create_Instance##ENTITY_SEPARATOR##Home","Update_ProfileStatus##ENTITY_SEPARATOR##Home","Find_Webhook##ENTITY_SEPARATOR##Home","Update_ProfilePicture##ENTITY_SEPARATOR##Home","Find_Settings##ENTITY_SEPARATOR##Home","Set_Settings##ENTITY_SEPARATOR##Home","Set_Typebot##ENTITY_SEPARATOR##Home","Update_PrivacySettings##ENTITY_SEPARATOR##Home","Find_Typebot##ENTITY_SEPARATOR##Home","Delete##ENTITY_SEPARATOR##Home","Find_Websocket##ENTITY_SEPARATOR##Home","Find_Chatwoot##ENTITY_SEPARATOR##Home","Connect##ENTITY_SEPARATOR##Home","Remove_ProfilePicture##ENTITY_SEPARATOR##Home","Fetch_PrivacySettings##ENTITY_SEPARATOR##Home","Restart##ENTITY_SEPARATOR##Home","Set_Rabbitmq##ENTITY_SEPARATOR##Home","fetch_Instances##ENTITY_SEPARATOR##Home","Find_Rabbitmq##ENTITY_SEPARATOR##Home","Set_Webhook##ENTITY_SEPARATOR##Home","Set_TypebotChangeSessionStatus##ENTITY_SEPARATOR##Home"],"pageList":["Home"],"actionCollectionList":["Scripts##ENTITY_SEPARATOR##Home"]},"editModeTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false},"publishedTheme":{"name":"Default","displayName":"Modern","config":{"colors":{"primaryColor":"#553DE9","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":{"none":"0px","M":"0.375rem","L":"1.5rem"}},"boxShadow":{"appBoxShadow":{"none":"none","S":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)","M":"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)","L":"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},"fontFamily":{"appFont":["System Default","Nunito Sans","Poppins","Inter","Montserrat","Noto Sans","Open Sans","Roboto","Rubik","Ubuntu"]}},"properties":{"colors":{"primaryColor":"#16a34a","backgroundColor":"#F8FAFC"},"borderRadius":{"appBorderRadius":"0.375rem"},"boxShadow":{"appBoxShadow":"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"},"fontFamily":{"appFont":"Nunito Sans"}},"stylesheet":{"AUDIO_RECORDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"BUTTON_GROUP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}"}}},"CAMERA_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","accentColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"CHECKBOX_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CHECKBOX_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CONTAINER_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"CIRCULAR_PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATE_PICKER_WIDGET2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FILE_PICKER_WIDGET_V2":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"FORM_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"ICON_BUTTON_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"IFRAME_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"IMAGE_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"INPUT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"JSON_FORM_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","submitButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"resetButtonStyles":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"childStylesheet":{"ARRAY":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"OBJECT":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none","cellBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","cellBoxShadow":"none"},"CHECKBOX":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CURRENCY_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DATEPICKER":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"EMAIL_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTISELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTILINE_TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PASSWORD_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PHONE_NUMBER_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RADIO_GROUP":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SELECT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"SWITCH":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"TEXT_INPUT":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"LIST_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"MAP_CHART_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}"},"MENU_BUTTON_WIDGET":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MODAL_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"MULTI_SELECT_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"DROP_DOWN_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"PROGRESSBAR_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"PROGRESS_WIDGET":{"fillColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"CODE_SCANNER_WIDGET":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"RATE_WIDGET":{"activeColor":"{{appsmith.theme.colors.primaryColor}}"},"RADIO_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"RICH_TEXT_EDITOR_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"STATBOX_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SWITCH_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","boxShadow":"none"},"SWITCH_GROUP_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"SELECT_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"TABLE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"}}},"TABLE_WIDGET_V2":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}","childStylesheet":{"button":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"menuButton":{"menuColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"iconButton":{"buttonColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"editActions":{"saveButtonColor":"{{appsmith.theme.colors.primaryColor}}","saveBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","discardButtonColor":"{{appsmith.theme.colors.primaryColor}}","discardBorderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"}}},"TABS_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"TEXT_WIDGET":{"truncateButtonColor":"{{appsmith.theme.colors.primaryColor}}","fontFamily":"{{appsmith.theme.fontFamily.appFont}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}"},"VIDEO_WIDGET":{"borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"{{appsmith.theme.boxShadow.appBoxShadow}}"},"SINGLE_SELECT_TREE_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}","borderRadius":"{{appsmith.theme.borderRadius.appBorderRadius}}","boxShadow":"none"},"CATEGORY_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"NUMBER_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"},"RANGE_SLIDER_WIDGET":{"accentColor":"{{appsmith.theme.colors.primaryColor}}"}},"isSystemTheme":false,"deleted":false}} From 9123d7014de8f0c62524f73ca6e1f0fabfb440b7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 31 Aug 2023 16:49:50 -0300 Subject: [PATCH 169/177] fix: create rabbitmq queues on set config --- src/libs/amqp.server.ts | 28 +++++++++++++++++++ .../controllers/instance.controller.ts | 5 +++- src/whatsapp/services/rabbitmq.service.ts | 2 ++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index cc0f13b5..272577d9 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -41,3 +41,31 @@ export const initAMQP = () => { export const getAMQP = (): amqp.Channel | null => { return amqpChannel; }; + +export const initQueues = (instanceName: string, events: string[]) => { + const queues = events.map((event) => { + return `${event.replace(/_/g, '.').toLowerCase()}`; + }); + + queues.forEach((event) => { + const amqp = getAMQP(); + const exchangeName = instanceName ?? 'evolution_exchange'; + + amqp.assertExchange(exchangeName, 'topic', { + durable: true, + autoDelete: false, + }); + + const queueName = `${instanceName}.${event}`; + + amqp.assertQueue(queueName, { + durable: true, + autoDelete: false, + arguments: { + 'x-queue-type': 'quorum', + }, + }); + + amqp.bindQueue(queueName, exchangeName, event); + }); +}; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 3030a060..ed466284 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -5,6 +5,7 @@ import EventEmitter2 from 'eventemitter2'; import { ConfigService, HttpServer } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; +import { initQueues } from '../../libs/amqp.server'; import { RedisCache } from '../../libs/redis.client'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; @@ -232,10 +233,12 @@ export class InstanceController { } this.rabbitmqService.create(instance, { enabled: true, - events: rabbitmq_events, + events: newEvents, }); rabbitmqEvents = (await this.rabbitmqService.find(instance)).events; + + initQueues(instance.instanceName, rabbitmqEvents); } catch (error) { this.logger.log(error); } diff --git a/src/whatsapp/services/rabbitmq.service.ts b/src/whatsapp/services/rabbitmq.service.ts index 383ad07a..a377595b 100644 --- a/src/whatsapp/services/rabbitmq.service.ts +++ b/src/whatsapp/services/rabbitmq.service.ts @@ -1,4 +1,5 @@ import { Logger } from '../../config/logger.config'; +import { initQueues } from '../../libs/amqp.server'; import { InstanceDto } from '../dto/instance.dto'; import { RabbitmqDto } from '../dto/rabbitmq.dto'; import { RabbitmqRaw } from '../models'; @@ -13,6 +14,7 @@ export class RabbitmqService { this.logger.verbose('create rabbitmq: ' + instance.instanceName); this.waMonitor.waInstances[instance.instanceName].setRabbitmq(data); + initQueues(instance.instanceName, data.events); return { rabbitmq: { ...instance, rabbitmq: data } }; } From 3ea454c7ed03bffcf89ad27dfe5e38117481c3d4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 31 Aug 2023 17:01:09 -0300 Subject: [PATCH 170/177] fix: create rabbitmq queues on set config --- src/libs/amqp.server.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 272577d9..21357257 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -43,6 +43,9 @@ export const getAMQP = (): amqp.Channel | null => { }; export const initQueues = (instanceName: string, events: string[]) => { + console.log('initQueues', instanceName, events); + if (!events.length) return; + const queues = events.map((event) => { return `${event.replace(/_/g, '.').toLowerCase()}`; }); From 6eda5562421f53b31fe566cc131acfc5af3a32b0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 31 Aug 2023 17:10:19 -0300 Subject: [PATCH 171/177] fix: create rabbitmq queues on set config --- src/libs/amqp.server.ts | 2 +- src/whatsapp/controllers/instance.controller.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 21357257..172d76a7 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -44,7 +44,7 @@ export const getAMQP = (): amqp.Channel | null => { export const initQueues = (instanceName: string, events: string[]) => { console.log('initQueues', instanceName, events); - if (!events.length) return; + if (!events || !events.length) return; const queues = events.map((event) => { return `${event.replace(/_/g, '.').toLowerCase()}`; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index ed466284..257d5f05 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -229,7 +229,7 @@ export class InstanceController { 'CHAMA_AI_ACTION', ]; } else { - newEvents = events; + newEvents = rabbitmq_events; } this.rabbitmqService.create(instance, { enabled: true, @@ -237,8 +237,6 @@ export class InstanceController { }); rabbitmqEvents = (await this.rabbitmqService.find(instance)).events; - - initQueues(instance.instanceName, rabbitmqEvents); } catch (error) { this.logger.log(error); } From 7e4dbfdd7e108d9a4d8437f4857997def278823a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 31 Aug 2023 18:24:30 -0300 Subject: [PATCH 172/177] fix: Added log when send event to rabbitMQ and Websocket --- src/libs/amqp.server.ts | 1 - .../controllers/instance.controller.ts | 1 - src/whatsapp/services/whatsapp.service.ts | 38 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/libs/amqp.server.ts b/src/libs/amqp.server.ts index 172d76a7..18b82c52 100644 --- a/src/libs/amqp.server.ts +++ b/src/libs/amqp.server.ts @@ -43,7 +43,6 @@ export const getAMQP = (): amqp.Channel | null => { }; export const initQueues = (instanceName: string, events: string[]) => { - console.log('initQueues', instanceName, events); if (!events || !events.length) return; const queues = events.map((event) => { diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 257d5f05..8d0e21ca 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -5,7 +5,6 @@ import EventEmitter2 from 'eventemitter2'; import { ConfigService, HttpServer } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; -import { initQueues } from '../../libs/amqp.server'; import { RedisCache } from '../../libs/redis.client'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index f5e2c619..2e5e79f6 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -688,6 +688,25 @@ export class WAStartupService { } amqp.publish(exchangeName, event, Buffer.from(JSON.stringify(message))); + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendData-RabbitMQ', + event, + instance: this.instance.name, + data, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + date_time: now, + sender: this.wuid, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } } } } @@ -713,6 +732,25 @@ export class WAStartupService { this.logger.verbose('Sending data to socket.io in channel: ' + this.instance.name); io.of(`/${this.instance.name}`).emit(event, message); + + if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { + const logData = { + local: WAStartupService.name + '.sendData-Websocket', + event, + instance: this.instance.name, + data, + server_url: serverUrl, + apikey: (expose && instanceApikey) || null, + date_time: now, + sender: this.wuid, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); + } } } From f83d8de476fc206a792395df4773e44e7a5c38f6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 4 Sep 2023 13:00:16 -0300 Subject: [PATCH 173/177] test: process exit when errors --- package.json | 2 +- src/main.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 275e2b41..783731d7 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@figuro/chatwoot-sdk": "^1.1.14", "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", - "@whiskeysockets/baileys": "github:EvolutionAPI/Baileys", + "@whiskeysockets/baileys": "^6.4.1", "amqplib": "^0.10.3", "axios": "^1.3.5", "class-validator": "^0.13.2", diff --git a/src/main.ts b/src/main.ts index 167909b1..8581fda7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -83,6 +83,11 @@ function bootstrap() { httpService.post('', errorData); } + if (err['message'].includes('No sessions') || err['message'].includes('Connection Closed')) { + console.log(err['message']); + process.exit(1); + } + return res.status(err['status'] || 500).json({ status: err['status'] || 500, error: err['error'] || 'Internal Server Error', From 41bea8931f6dfca19b09ec19b8f48310be448d46 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 4 Sep 2023 13:08:16 -0300 Subject: [PATCH 174/177] test: process exit when errors --- src/whatsapp/services/whatsapp.service.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index bc719392..74a0a01c 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1432,7 +1432,12 @@ export class WAStartupService { this.logger.verbose('Event received: messages.upsert'); const received = messages[0]; - if (type !== 'notify' || received.message?.protocolMessage || received.message?.pollUpdateMessage) { + if ( + type !== 'notify' || + !received.message || + received.message?.protocolMessage || + received.message?.pollUpdateMessage + ) { this.logger.verbose('message rejected'); return; } From 2791f88b4c36038cf24ff90e679c289b6c0aa7bb Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 4 Sep 2023 16:13:43 -0300 Subject: [PATCH 175/177] fix: added delay in chatwoot receive webhook --- src/whatsapp/services/chatwoot.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index abe48150..9c386bce 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -945,6 +945,9 @@ export class ChatwootService { public async receiveWebhook(instance: InstanceDto, body: any) { try { + // espera 500ms para evitar duplicidade de mensagens + await new Promise((resolve) => setTimeout(resolve, 500)); + this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); const client = await this.clientCw(instance); From 384e311c7af5565cd351888ed19223c2f42c2c04 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 4 Sep 2023 16:48:04 -0300 Subject: [PATCH 176/177] fix: added delay in chatwoot receive webhook --- src/whatsapp/services/chatwoot.service.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 9c386bce..485e408d 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -460,7 +460,9 @@ export class ChatwootService { let contact: any; if (body.key.fromMe) { if (findContact) { - contact = findContact; + contact = await this.updateContact(instance, findContact.id, { + avatar_url: picture_url.profilePictureUrl || null, + }); } else { const jid = isGroup ? null : body.key.remoteJid; contact = await this.createContact( @@ -481,7 +483,9 @@ export class ChatwootService { avatar_url: picture_url.profilePictureUrl || null, }); } else { - contact = findContact; + contact = await this.updateContact(instance, findContact.id, { + avatar_url: picture_url.profilePictureUrl || null, + }); } } else { const jid = isGroup ? null : body.key.remoteJid; From 23534da27dd64badecc053ec1ccd5d36714b04b0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 5 Sep 2023 08:39:51 -0300 Subject: [PATCH 177/177] fix: added delay in chatwoot receive webhook --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 8581fda7..9f93ac71 100644 --- a/src/main.ts +++ b/src/main.ts @@ -83,7 +83,7 @@ function bootstrap() { httpService.post('', errorData); } - if (err['message'].includes('No sessions') || err['message'].includes('Connection Closed')) { + if (err['message'].includes('No sessions')) { console.log(err['message']); process.exit(1); }