From 6497728899846b509459607ec5455f48a41c6bff Mon Sep 17 00:00:00 2001 From: adriano Date: Thu, 10 Apr 2025 15:28:38 -0300 Subject: [PATCH] fix(integration): The companyId was missing when testing the integration between the Salesforce JSON template and the API. This change ensures it's properly passed to the function. --- .../TEMPLATES-DEFAULT/hubspot_hit_test.json | 235 ++++++++++++++++++ .../salesforce_hit_test.json | 181 ++++++++++++++ backend/controllers/crmController.js | 3 +- backend/utils/createContact.js | 29 ++- backend/utils/lookupCRMContactByPhone.js | 2 +- backend/utils/oauth2.js | 1 + backend/utils/requestConfigHeader.js | 2 +- backend/utils/templateValidator.js | 7 +- 8 files changed, 452 insertions(+), 8 deletions(-) create mode 100644 backend/Templates-test/TEMPLATES-DEFAULT/hubspot_hit_test.json create mode 100644 backend/Templates-test/TEMPLATES-DEFAULT/salesforce_hit_test.json diff --git a/backend/Templates-test/TEMPLATES-DEFAULT/hubspot_hit_test.json b/backend/Templates-test/TEMPLATES-DEFAULT/hubspot_hit_test.json new file mode 100644 index 0000000..7f80ed4 --- /dev/null +++ b/backend/Templates-test/TEMPLATES-DEFAULT/hubspot_hit_test.json @@ -0,0 +1,235 @@ +{ + "authentication":{ + "type":"bearer", + "token":"pat-na1-37da6668-e0b1-44cb-bd2d-596f5f65634a", + "crmPhoneTest":"5514987659932" + }, + "crmRest":[ + { + "createContactRecord":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://api.hubapi.com/contacts/v1/contact" + }, + "body":{ + "properties":[ + { + "property":"phone", + "value":"crmPhone" + } + ] + }, + "response":{ + "id":"vid" + } + } + }, + { + "lookupContactByPhone":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Get", + "responseType":"Json", + "url":"https://api.hubapi.com/contacts/v1/search/query?q=crmPhone" + }, + "response":{ + "phone":"contacts.properties.phone.value", + "id":"contacts.vid" + } + } + }, + { + "callJournaling":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://api.hubapi.com/engagements/v1/engagements" + }, + "calls":[ + { + "inboundAnsweredCall":{ + "engagement":{ + "active":true, + "type":"CALL" + }, + "associations":{ + "contactIds":[ + { + "_prop":"crmContactId", + "_type":"number" + } + ] + }, + "metadata":{ + "toNumber":{ + "_prop":"crmAgent", + "_type":"string" + }, + "fromNumber":{ + "_prop":"crmPhone", + "_type":"string" + }, + "status":"COMPLETED", + "durationMilliseconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"milliseconds" + }, + "body":"Ligação recebida - inbound call", + "disposition":"f240bbac-87c9-4f6e-bf70-924b57d47db7" + } + } + }, + { + "inboundMissedCall":{ + "engagement":{ + "active":true, + "type":"CALL" + }, + "associations":{ + "contactIds":[ + { + "_prop":"crmContactId", + "_type":"number" + } + ] + }, + "metadata":{ + "toNumber":{ + "_prop":"crmAgent", + "_type":"string" + }, + "fromNumber":{ + "_prop":"crmPhone", + "_type":"string" + }, + "status":"COMPLETED", + "body":"Ligação perdida - inbound call", + "disposition":"f240bbac-87c9-4f6e-bf70-924b57d47db7" + } + } + }, + { + "outboundAnsweredCall":{ + "engagement":{ + "active":true, + "type":"CALL" + }, + "associations":{ + "contactIds":[ + { + "_prop":"crmContactId", + "_type":"number" + } + ] + }, + "metadata":{ + "fromNumber":{ + "_prop":"crmPhone", + "_type":"string" + }, + "toNumber":{ + "_prop":"crmAgent", + "_type":"string" + }, + "status":"COMPLETED", + "durationMilliseconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"milliseconds" + }, + "body":"Ligação atendida - outbound call", + "disposition":"f240bbac-87c9-4f6e-bf70-924b57d47db7" + } + } + }, + { + "outboundUnansweredCall":{ + "engagement":{ + "active":true, + "type":"CALL" + }, + "associations":{ + "contactIds":[ + { + "_prop":"crmContactId", + "_type":"number" + } + ] + }, + "metadata":{ + "fromNumber":{ + "_prop":"crmAgent", + "_type":"string" + }, + "toNumber":{ + "_prop":"crmPhone", + "_type":"string" + }, + "status":"COMPLETED", + "body":"Ligação perdida - oubound call", + "disposition":"f240bbac-87c9-4f6e-bf70-924b57d47db7" + } + } + } + ] + } + }, + { + "createTicketRecord":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://api.hubapi.com/crm/v3/objects/tickets" + }, + "body":{ + "properties":{ + "hs_pipeline":"0", + "hs_pipeline_stage":"1", + "hs_ticket_priority":"HIGH", + "subject":"Teste" + }, + "associations":[ + { + "to":{ + "id":"crmContactId" + }, + "types":[ + { + "associationCategory":"HUBSPOT_DEFINED", + "associationTypeId":16 + } + ] + } + ] + }, + "response":{ + "id":"id" + } + } + }, + { + "lookupTicket":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Get", + "responseType":"Json", + "url":"https://api.hubapi.com/crm/v3/objects/tickets/ticketId" + }, + "response":{ + "status":"properties.hs_pipeline_stage", + "id":"id" + } + } + } + ] +} \ No newline at end of file diff --git a/backend/Templates-test/TEMPLATES-DEFAULT/salesforce_hit_test.json b/backend/Templates-test/TEMPLATES-DEFAULT/salesforce_hit_test.json new file mode 100644 index 0000000..803872d --- /dev/null +++ b/backend/Templates-test/TEMPLATES-DEFAULT/salesforce_hit_test.json @@ -0,0 +1,181 @@ +{ + "authentication":{ + "type":"oauth2", + "crmClientId":"3MVG9JJwBBbcN47Kv0Z7EuNd19INI1Bhe7uX_Wz6M0VlMyWJD4xPKTtn_b39bGn6LmdSkKJ.aLNGdV1brj16C", + "crmClientSecret":"870E8D51A1CA06896D966A3D92ABD885346DAD4428926E965776C479055969E7", + "crmScopes":"full refresh_token", + "crmPhoneTest":"5514983253326" + }, + "crmRest":[ + { + "authorizationEndpoint":{ + "request":{ + "requestContentType":"empty", + "requestEncoding":"empty", + "requestType":"Get", + "responseType":"empty", + "url":"https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=crmClientId&code_challenge=bDXEJ0wxr0s369lGxHwewLULiOuyl6Y3W7QZABmn2S4&redirect_uri=crmRedirectURI&scope=crmScopes&code_challenge_method=S256" + } + } + }, + { + "tokenEndpoint":{ + "request":{ + "requestContentType":"none", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://login.salesforce.com/services/oauth2/token" + } + } + }, + { + "createContactRecord":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://nocompany-a9-dev-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/Lead" + }, + "body":{ + "Phone":"crmPhone", + "LastName":"crmLastName", + "FirstName":"crmFirstName", + "Company":"Unknown", + "LeadSource":"Phone Inquiry", + "Status":"Working - Contacted" + }, + "response":{ + "id":"id" + } + } + }, + { + "lookupContactByPhone":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Get", + "responseType":"Json", + "url":"https://nocompany-a9-dev-ed.develop.my.salesforce.com/services/data/v61.0/query/?q=SELECT+Id,Phone+FROM+Lead+WHERE+Phone='crmPhone'" + }, + "response":{ + "phone":"records[0].Phone", + "id":"records[0].Id" + } + } + }, + { + "callJournaling":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://nocompany-a9-dev-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/Task" + }, + "calls":[ + { + "inboundAnsweredCall":{ + "Subject":"Call Journal", + "WhoId":"crmContactId", + "Description":"Ligação recebida", + "Status":"Completed", + "Priority":"Normal", + "CallType":"Outbound", + "CallDurationInSeconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"seconds" + }, + "ActivityDate":"YYYY-MM-DD", + "TaskSubtype":"Call" + } + }, + { + "inboundMissedCall":{ + "Subject":"Call Journal", + "WhoId":"crmContactId", + "Description":"Ligação recebida perdida", + "Status":"Completed", + "Priority":"Normal", + "CallType":"Outbound", + "CallDurationInSeconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"seconds" + }, + "ActivityDate":"YYYY-MM-DD", + "TaskSubtype":"Call" + } + }, + { + "outboundAnsweredCall":{ + "Subject":"Call Journal", + "WhoId":"crmContactId", + "Description":"Ligação realizada", + "Status":"Completed", + "Priority":"Normal", + "CallType":"Outbound", + "CallDurationInSeconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"seconds" + }, + "ActivityDate":"YYYY-MM-DD", + "TaskSubtype":"Call" + } + }, + { + "outboundUnansweredCall":{ + "Subject":"Call Journal", + "WhoId":"crmContactId", + "Description":"Ligação realizada nao atendida", + "Status":"Completed", + "Priority":"Normal", + "CallType":"Outbound", + "CallDurationInSeconds":{ + "_prop":"crmCallDuration", + "_type":"number", + "_format":"seconds" + }, + "ActivityDate":"YYYY-MM-DD", + "TaskSubtype":"Call" + } + } + ] + } + }, + { + "chatJournaling":{ + "request":{ + "requestContentType":"application/json", + "requestEncoding":"Json", + "requestType":"Post", + "responseType":"Json", + "url":"https://nocompany-a9-dev-ed.develop.my.salesforce.com/services/data/v61.0/sobjects/Task" + }, + "chats":[ + { + "chatDone":{ + "WhoId":"crmContactId", + "Subject":"WhatsApp Chat", + "Description":"Conversation started via WhatsApp. Conversation link: chatLink", + "ActivityDate":"YYYY-MM-DD", + "Status":"Completed", + "Priority":"Normal" + } + } + ] + } + }, + { + "redirectLink":{ + "request":{ + "url":"https://nocompany-a9-dev-ed.develop.lightning.force.com/lightning/r/Lead/crmContactId/edit?count=1&backgroundContext=%2Flightning%2Fr%2FLead%2F00Qak0000098YFhEAM%2Fview" + } + } + } + ] +} \ No newline at end of file diff --git a/backend/controllers/crmController.js b/backend/controllers/crmController.js index 5769bc8..96eb2a5 100644 --- a/backend/controllers/crmController.js +++ b/backend/controllers/crmController.js @@ -263,7 +263,7 @@ const oauthCallBack = async (req, res) => { const testTemplate = async (req, res) => { - const { clientId, companyId } = req.body + let { clientId, companyId } = req.body let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId, testing: true }) @@ -273,6 +273,7 @@ const testTemplate = async (req, res) => { crmOauth = crmOauth.toObject() const { crmPhoneTest } = crmOauth.crm.authentication + await templateValidator(crmPhoneTest, crmOauth.crm, companyId) crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId }) diff --git a/backend/utils/createContact.js b/backend/utils/createContact.js index 2d379e5..f9e8c90 100644 --- a/backend/utils/createContact.js +++ b/backend/utils/createContact.js @@ -41,8 +41,8 @@ async function createContact(companyId, rest, authentication, crmPhone, crmFirst const { type, userName, passWord, token, crmClientId } = authentication - //url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, data = '', ticketId = '', companyId - const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, body, '', companyId) + //url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, data = '', ticketId = '', companyId + const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, body, '', companyId) if (test?.testing) { msg = `Tentanto criar contato de numero ${crmPhone} no crm` @@ -51,9 +51,30 @@ async function createContact(companyId, rest, authentication, crmPhone, crmFirst console.log('#####################') console.log('CREATE CONTACT PAYLOAD: ', JSON.stringify(config, null, 6)) - console.log('#####################') + console.log('#####################') + + let data + try { + let { data: _data } = await axios(config) + data = _data + } catch (error) { + if (error.response) { + console.error('==================> createContact Erro na resposta da API:', { + status: error.response.status, + data: error.response.data, + }) + } + else if (error.request) { + console.error('==================> createContact Nenhuma resposta recebida da API:', error.request) + } + else { + console.error('==================> createContact Erro ao configurar a request:', error.message) + } - let { data } = await axios(config) + throw error + } + + // let { data } = await axios(config) data = flatten(data) diff --git a/backend/utils/lookupCRMContactByPhone.js b/backend/utils/lookupCRMContactByPhone.js index a46c9cf..184a871 100644 --- a/backend/utils/lookupCRMContactByPhone.js +++ b/backend/utils/lookupCRMContactByPhone.js @@ -12,7 +12,7 @@ const sendMessageSocket = require('./sendMessageSocket') const CRM_Ticket = require('../models/CRM_Ticket') async function lookupContactByPhone(rest, authentication, crmPhone, companyId, test = {}, cacheContact = false) { - + let { request, body, response } = findProperty(rest, 'lookupContactByPhone') let { requestContentType, requestEncoding, requestType, responseType, url } = request diff --git a/backend/utils/oauth2.js b/backend/utils/oauth2.js index b37493f..af8d020 100644 --- a/backend/utils/oauth2.js +++ b/backend/utils/oauth2.js @@ -92,6 +92,7 @@ const exchangeForTokens = async (crmOauth, exchangeProof, companyId) => { const refreshAccessToken = async (clientId, companyId) => { let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, companyId }) + crmOauth = crmOauth.toObject() const refreshTokenProof = { diff --git a/backend/utils/requestConfigHeader.js b/backend/utils/requestConfigHeader.js index ce24826..50a7107 100644 --- a/backend/utils/requestConfigHeader.js +++ b/backend/utils/requestConfigHeader.js @@ -2,7 +2,7 @@ const { getAccessToken } = require('./oauth2') async function requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, data = '', ticketId = '', companyId) { let config = {} - + console.log('requestConfigHeader ticketId: ', ticketId) url = url.replace('crmPhone', crmPhone) url = url.replace('ticketId', ticketId) diff --git a/backend/utils/templateValidator.js b/backend/utils/templateValidator.js index 44e3763..38fb224 100644 --- a/backend/utils/templateValidator.js +++ b/backend/utils/templateValidator.js @@ -33,6 +33,7 @@ async function templateValidator(crmPhoneTest, crm, companyId) { } else { msg = `Contato de numero ${phoneTest} já existe no crm` + console.log("======> msg testing: ", msg) sendMessageSocket({ companyId, status: 'processing', data: { msg } }) } @@ -43,6 +44,8 @@ async function templateValidator(crmPhoneTest, crm, companyId) { msg = `Tentando inserir registro de chamada(call journal) ${Object.keys(operation)[0]} para o contato ${phoneTest}` + console.log("======> msg testing: ", msg, " | companyId: ", companyId) + await journalingRequest(request, body = operation[Object.keys(operation)[0]], crmCallDuration = "900", @@ -50,9 +53,11 @@ async function templateValidator(crmPhoneTest, crm, companyId) { crmAgent = "2245", crmPhone = phoneTest, authentication = crm.authentication, - test = { testing: true, msg, companyId }) + test = { testing: true, msg, companyId }, + companyId) msg = `Registro de chamada inserido com sucesso ${Object.keys(operation)[0]} para o contato ${phoneTest}` + console.log("======> msg testing: ", msg) sendMessageSocket({ companyId, status: 'processing', data: { msg } }) }