diff --git a/backend/app.js b/backend/app.js index 11219ab..0899999 100644 --- a/backend/app.js +++ b/backend/app.js @@ -43,6 +43,7 @@ const cors = require('cors') // routers const crmRouter = require('./routes/crmRoute') +const integrationRouter = require("./routes/integrationRoutes") const notFoundMiddlware = require('./middleware/not-found') const errorHandlerMiddleware = require('./middleware/error-handler') @@ -78,6 +79,7 @@ app.get('/', (req, res) => { app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerDocument)) app.use('/api/v1/crm', crmRouter) +app.use('/api/v1/integration', integrationRouter) Sentry.setupExpressErrorHandler(app) app.use(notFoundMiddlware) diff --git a/backend/controllers/crmController.js b/backend/controllers/crmController.js index 17d53c2..70c48b1 100644 --- a/backend/controllers/crmController.js +++ b/backend/controllers/crmController.js @@ -1,7 +1,7 @@ const path = require('path') -const Sentry = require('@sentry/node') -const omnihitV2Integration = require('../data/omihitV2IntegrationCRM.json') +const getIntegrationsConfig = require('../utils/getIntegrationsConfig') + const { StatusCodes } = require("http-status-codes") const { createCRMContact, sendMessageSocket, @@ -88,49 +88,60 @@ const callJournaling = async (req, res) => { // Remove 0 from the beginning of the number. Ex: 011996067641 to 11996067641 crmPhone = removeZeroInicial(crmPhone) + + + // test remove + // return res.status(StatusCodes.OK).send() + // Refactor this in the future. crmPhone = '55' + crmPhone console.log('========> CRMPHONE: ', crmPhone) console.log('========> COMPANY ID before: ', companyId) + if (companyId == "1") companyId = '99' + console.log('========> COMPANY ID after: ', companyId) + if (!crmAgent) crmAgent = "0000" // + mustContainProperties(req, ['companyId', 'operation', 'crmPhone', /*'crmAgent'*/,]) + // if (operation == 'inboundAnsweredCall' && !crmCallDuration) // throw new CustomError.BadRequestError(`The crmCallDuration property must be provided when operation is inboundAnsweredCall`) // if (operation == 'outboundAsweredCall' && !crmCallDuration) // throw new CustomError.BadRequestError(`The crmCallDuration property must be provided when operation is outboundAsweredCall`) + + if (!crmCallDuration || crmCallDuration.trim() == "" || crmCallDuration == "0") crmCallDuration = "10" + + if (operationStatus == "hangup") await journaling(companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName) + else if (operationStatus == "update-answer") { console.log('update-answer') - // Referente a cliente a gabriel, pois os tickets estao sendo abertos diretamente em um botao do hitphone - if (companyId != "12928") { - console.log(`################## CRIAÇÃO AUTOMATICA DE TICKET COMPANY ID ${companyId} ##################`) - await ticketCRM(companyId, crmPhone, crmAgent, crmFirstName) - } - + await ticketCRM(companyId, crmPhone, crmAgent, crmFirstName) const resp = await redirectContactLinkCRM(companyId, crmPhone, crmAgent, crmFirstName) return res.status(StatusCodes.OK).json({ contact: resp }) } + res.status(StatusCodes.OK).send() } catch (error) { // console.log(`[ERROR - ${new Date()}] Erro no Call Journaling`, error?.response?.data) @@ -143,9 +154,11 @@ const callJournaling = async (req, res) => { data: error.response.data, }) } + } else if (error.request) { console.error('==================> callJournaling Nenhuma resposta recebida da API:', error.request) } + } else { console.error('==================> callJournaling Erro ao configurar a request:', error.message) } @@ -215,6 +228,7 @@ const oauthCallBack = async (req, res) => { console.log('xxxxxxxxxx passed') + let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId }) let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId }) crmOauth = crmOauth.toObject() @@ -510,13 +524,14 @@ const webhook_crm = async (req, res) => { const { phone } = contact - const obj = omnihitV2Integration.find(o => o.companyId == companyId) + // const obj = omnihitV2Integration.find(o => o.companyId == companyId) - if (obj) { + const config = await getIntegrationsConfig(companyId, 'omnihit') - const { companyId, - omnihit: { accountId, api: { url, token } = {}, - createConversation: { inbox_id, status, team_id } = {} } = {} } = obj + if (config) { + + const { accountId, api: { url, token } = {}, + createConversation: { inbox_id, status, team_id } = {} = {} } = config const contactIdChatwoot = await getContactIdChatwoot(url, token, phone) @@ -541,6 +556,15 @@ const webhook_crm = async (req, res) => { return res.set('Content-Type', 'text/xml').status(StatusCodes.OK).send(responseXml) } +const integration = async (req, res) => { + const { companyId } = req.query + const { integration } = req.body + + console.log("====> companyId: ", companyId, " | integration: ", integration) + + res.send() +} + module.exports = { contactCreate, uploadCrmConfig, diff --git a/backend/controllers/integrationController.js b/backend/controllers/integrationController.js new file mode 100644 index 0000000..dea6525 --- /dev/null +++ b/backend/controllers/integrationController.js @@ -0,0 +1,39 @@ +const { StatusCodes } = require("http-status-codes") +const { mustContainProperties } = require("../utils") +const Company = require("../models/Company") +const getIntegrationsConfig = require("../utils/getIntegrationsConfig") + +const integration = async (req, res) => { + const { companyId } = req.params + const { config, name } = req.body + + mustContainProperties(req, ['name', 'config']) + + const company = await Company.findOne({ companyId }) + + if (!company) { + return res.status(StatusCodes.NOT_FOUND).send({ msg: "companyId not found!" }) + } + + const existingIntegrationIndex = company.integrations.findIndex(i => i.name === name) + + if (existingIntegrationIndex !== -1) { + company.integrations[existingIntegrationIndex].config = config + } else { + company.integrations.push({ name, config }) + } + + await company.save() + + res.status(StatusCodes.OK).send({ + msg: 'Integração atualizada com sucesso', + integrations: company.integrations + }) +} + +module.exports = { + integration +} + + + diff --git a/backend/controllers/test.js b/backend/controllers/test.js deleted file mode 100644 index 8402885..0000000 --- a/backend/controllers/test.js +++ /dev/null @@ -1,11 +0,0 @@ -const omnihitV2Integration = require('../data/omihitV2IntegrationCRM.json') - -const obj = omnihitV2Integration.find(o => o.companyId === "99") - -if (obj) { - console.log(obj) - - const { companyId, omnihit: { accountId, api: { url, token } = {}, createConversation: { inbox_id, status, team_id } = {} } = {} } = obj - - console.log('companyId: ', companyId, ' accountId: ', accountId, ' url: ', url, ' token: ', token, ' inbox_id: ', inbox_id, ' status: ', status, ' team_id: ', team_id) -} diff --git a/backend/models/Company.js b/backend/models/Company.js index cf3ddea..61cfad6 100644 --- a/backend/models/Company.js +++ b/backend/models/Company.js @@ -10,7 +10,16 @@ const crmCompany = new Schema({ }, name: { type: String - } + }, + integrations: [ + { + name: { type: String, required: true }, + config: { + type: Schema.Types.Mixed, + default: {} + } + } + ] }, { timestamps: true, @@ -26,7 +35,7 @@ crmCompany.virtual('crms', { // match: { rating: 4 } }) -crmCompany.pre('deleteOne', { document: true, query: false }, async function () { +crmCompany.pre('deleteOne', { document: true, query: false }, async function () { const crms = await this.model('CRM').find({ company: this._id }) for (const crm of crms) { await crm.deleteOne() // Delete each CRM diff --git a/backend/routes/integrationRoutes.js b/backend/routes/integrationRoutes.js new file mode 100644 index 0000000..6278ecd --- /dev/null +++ b/backend/routes/integrationRoutes.js @@ -0,0 +1,8 @@ +const express = require('express') +const router = express.Router() +const { authorization, } = require('../middleware/authentication') +const { integration } = require('../controllers/integrationController') + +router.route('/:companyId').patch(authorization, integration) + +module.exports = router diff --git a/backend/utils/getIntegrationsConfig.js b/backend/utils/getIntegrationsConfig.js new file mode 100644 index 0000000..f9e4fa6 --- /dev/null +++ b/backend/utils/getIntegrationsConfig.js @@ -0,0 +1,13 @@ +const Company = require("../models/Company") + +async function getIntegrationsConfig(companyId, name) { + const company = await Company.findOne({ companyId }) + + if (company){ + let obj = company.integrations.find(i => i.name === name) + return obj?.config + } + +} + +module.exports = getIntegrationsConfig \ No newline at end of file diff --git a/backend/utils/whatsappJournalingCRM.js b/backend/utils/whatsappJournalingCRM.js index 8adad82..949a440 100644 --- a/backend/utils/whatsappJournalingCRM.js +++ b/backend/utils/whatsappJournalingCRM.js @@ -10,15 +10,14 @@ const createTicket = require('./createTicket') const lookupCRMTicket = require('./lookupCRMTicket') const sendEventTicketCreatedToSocket = require('./sendEventTicketCreatedToSocket') const journalingRequest = require('./journalingRequest') + +const getIntegrationsConfig = require('../utils/getIntegrationsConfig') -const omnihitV2Integration = require('../data/omihitV2IntegrationCRM.json') - - -async function whatsappJournalingCRM(companyId, crmPhone, crmAgent, crmFirstName = 'Username', ticketId=null) { +async function whatsappJournalingCRM(companyId, crmPhone, crmAgent, crmFirstName = 'Username', ticketId = null) { const crmFiles = await loadCRM(companyId) - const crmContactIds = [] + const crmContactIds = [] for (const crmConfig of crmFiles) { @@ -32,25 +31,19 @@ async function whatsappJournalingCRM(companyId, crmPhone, crmAgent, crmFirstName if (chatJournaling) { - let contact = await _lookupContact(rest, authentication, crmPhone, companyId, crmFirstName) - - const { contactId, created } = contact + let contact = await _lookupContact(rest, authentication, crmPhone, companyId, crmFirstName) let { request, chats, response } = chatJournaling let body = findProperty(chats, 'chatDone') + let config = await getIntegrationsConfig(companyId, 'omnihit') + if (ticketId && config) { - const obj = omnihitV2Integration.find(o => o.companyId == companyId) - - if (ticketId && obj) { - - const { companyId, - omnihit: { accountId, api: { url, urlHttps, token } = {}, - createConversation: { inbox_id, status, team_id } = {} } = {} } = obj - + const { accountId, api: { url, urlHttps, token } = {}, + createConversation: { inbox_id, status, team_id } = {} = {} } = config console.log('===============> body1: ', body) body = JSON.stringify(body)