diff --git a/backend/Templates-test/salesforce_oauth2_lead.json b/backend/Templates-test/salesforce_oauth2_lead.json new file mode 100644 index 0000000..d9f2644 --- /dev/null +++ b/backend/Templates-test/salesforce_oauth2_lead.json @@ -0,0 +1,155 @@ +{ + "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" + }, + "body": {}, + "response": {} + } + }, + { + "tokenEndpoint": { + "request": { + "requestContentType": "none", + "requestEncoding": "Json", + "requestType": "Post", + "responseType": "Json", + "url": "https://login.salesforce.com/services/oauth2/token" + }, + "body": {}, + "response": {} + } + }, + { + "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", + "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" + } + } + ], + "response": {} + } + } + ] +} diff --git a/backend/Templates-test/salesforce_oauth2_lead_editing_redirectlink.json b/backend/Templates-test/salesforce_oauth2_lead_editing_redirectlink.json new file mode 100644 index 0000000..2414d27 --- /dev/null +++ b/backend/Templates-test/salesforce_oauth2_lead_editing_redirectlink.json @@ -0,0 +1,162 @@ +{ + "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" + }, + "body": {}, + "response": {} + } + }, + { + "tokenEndpoint": { + "request": { + "requestContentType": "none", + "requestEncoding": "Json", + "requestType": "Post", + "responseType": "Json", + "url": "https://login.salesforce.com/services/oauth2/token" + }, + "body": {}, + "response": {} + } + }, + { + "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", + "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" + } + } + ], + "response": {} + } + }, + { + "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" + } + } + } + ] +} diff --git a/backend/controllers/crmController.js b/backend/controllers/crmController.js index 75e5bfe..f5c0bc1 100644 --- a/backend/controllers/crmController.js +++ b/backend/controllers/crmController.js @@ -139,9 +139,9 @@ const oauthCallBack = async (req, res) => { const rest = crmOauth.crm.crmRest const salesforceUrls = rest.map(endpoint => { const key = Object.keys(endpoint)[0] - const url = endpoint[key].request.url + const url = endpoint[key]?.request?.url - if (url.includes("salesforce")) { + if (url?.includes("salesforce")) { return `${key} URL: ${url}` } }).filter(Boolean) diff --git a/backend/models/CRM.js b/backend/models/CRM.js index ca5515b..3f01141 100644 --- a/backend/models/CRM.js +++ b/backend/models/CRM.js @@ -44,6 +44,22 @@ const CallJournalingSchema = new Schema({ response: Object }) + + +const RedirectUrlSchema = new Schema({ + url: { + type: String, + required: false + } +}) + +// const redirectLinkSchema = new Schema({ +// request: RedirectUrlSchema, +// }) + + + + // Define main schema const CRMRestSchema = new Schema({ authorizationEndpoint: { @@ -72,6 +88,9 @@ const CRMRestSchema = new Schema({ request: RequestSchema, response: Object }, + redirectLink: { + request: RedirectUrlSchema + }, callJournaling: CallJournalingSchema }) diff --git a/backend/utils/ticketCRM.js b/backend/utils/ticketCRM.js index fba5e03..8cf965b 100644 --- a/backend/utils/ticketCRM.js +++ b/backend/utils/ticketCRM.js @@ -8,28 +8,41 @@ const CRM = require('../models/CRM') const createTicket = require('./createTicket') const lookupCRMTicket = require('./lookupCRMTicket') +const sendEventTicketCreatedToSocket = require('./sendEventTicketCreatedToSocket') async function ticketCRM(companyId, crmPhone, crmAgent, crmFirstName = 'Username') { - const crmFiles = await loadCRM(companyId) - - // console.log('xxxxxxxx crmFiles: ', JSON.stringify(crmFiles, null, 6)) - + const crmFiles = await loadCRM(companyId) + for (const crmConfig of crmFiles) { - const { crmRest: rest, authentication } = crmConfig.crm + const { crmRest: rest, authentication } = crmConfig.crm - let obj = findProperty(rest, 'lookupTicket') + // Send the edited contact/lead link url to hitphone to open on another browser tab + let redirectLink = findProperty(rest, 'redirectLink') - if (obj) { + if (redirectLink) { + let contact = await _lookupContact(rest, authentication, crmPhone, companyId, crmFirstName) + + const { contactId } = contact + + const url = redirectLink?.request?.url?.replace(/crmContactId/g, contactId) + + console.log('===============> Edit url rediret sended to hitphone: ', url) + + sendEventTicketCreatedToSocket({ companyId, extension: crmAgent, ticketUrl: url }) + } + // + + + // Send the ticket url link to hitphone to open on another browser tab + let obj = findProperty(rest, 'lookupTicket') + + if (obj) { let { url } = obj.request - let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId) - - if (!contact?.exist) { - contact = await createContact(companyId, rest, authentication, crmPhone, crmFirstName) - } + let contact = await _lookupContact(rest, authentication, crmPhone, companyId, crmFirstName) const crm = await CRM.findOne({ companyId, crmBaseURL: new URL(url.trim()).hostname @@ -68,6 +81,7 @@ async function ticketCRM(companyId, crmPhone, crmAgent, crmFirstName = 'Username } } + // } @@ -76,6 +90,15 @@ async function ticketCRM(companyId, crmPhone, crmAgent, crmFirstName = 'Username module.exports = ticketCRM +async function _lookupContact(rest, authentication, crmPhone, companyId, crmFirstName) { + let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId) + + if (!contact?.exist) { + contact = await createContact(companyId, rest, authentication, crmPhone, crmFirstName) + } + return contact +} + async function _createTicket(rest, crmPhone, companyId, authentication, crmFirstName, contact, crmAgent) { let obj = findProperty(rest, 'createTicketRecord')