2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
const path = require('path')
|
2024-10-07 14:25:08 +00:00
|
|
|
const omnihitV2Integration = require('../data/omihitV2IntegrationCRM.json')
|
2023-11-29 20:05:48 +00:00
|
|
|
const { StatusCodes } = require("http-status-codes")
|
|
|
|
const { createCRMContact,
|
|
|
|
sendMessageSocket,
|
|
|
|
mustContainProperties,
|
|
|
|
journaling,
|
2024-07-19 18:48:34 +00:00
|
|
|
ticketCRM,
|
2023-11-29 20:05:48 +00:00
|
|
|
findProperty,
|
|
|
|
journalingRequest,
|
|
|
|
createContact,
|
|
|
|
lookupContactByPhone,
|
|
|
|
templateValidator } = require('../utils')
|
|
|
|
const fs = require("fs")
|
|
|
|
const { URL } = require('url')
|
|
|
|
const { oauth2 } = require('../utils')
|
|
|
|
const { exchangeForTokens } = oauth2
|
|
|
|
const Company = require('../models/Company')
|
|
|
|
const CRM = require('../models/CRM')
|
|
|
|
const CustomError = require('../errors')
|
2024-10-04 17:59:10 +00:00
|
|
|
const CRM_Contact = require('../models/CRM_Contact')
|
|
|
|
const axios = require('axios')
|
|
|
|
const { get, set } = require('../utils/redisClient')
|
2024-10-07 14:25:08 +00:00
|
|
|
const { getContactIdChatwoot, createConversation, toggleConversationStatus } = require('../utils/ScheduleTicketCRM')
|
|
|
|
const timeStamp = require('../utils/toTimestamp')
|
2024-11-05 18:37:36 +00:00
|
|
|
const whatsappJournalingCRM = require('../utils/whatsappJournalingCRM')
|
|
|
|
const redirectContactLinkCRM = require('../utils/redirectContactLinkCRM')
|
|
|
|
const sfcase = require('../utils/sfCase')
|
|
|
|
const sfCaseUpdate = require('../utils/sfCaseUpdate')
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
const contactCreate = async (req, res) => {
|
|
|
|
|
|
|
|
const { companyId, crmFirstName, crmLastName, crmPhone, crmEmail } = req.body
|
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId', 'crmPhone',])
|
|
|
|
|
|
|
|
await createCRMContact(companyId, crmFirstName, crmPhone, crmEmail, crmLastName)
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const deleteCrm = async (req, res) => {
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
let { companyId, crmBaseURL } = req.body
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId', 'crmBaseURL',])
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
if (!crmBaseURL.startsWith('http://') && !crmBaseURL.startsWith('https://')) {
|
|
|
|
crmBaseURL = `https://${crmBaseURL.trim()}`
|
2024-09-24 13:23:08 +00:00
|
|
|
}
|
2024-09-24 12:10:18 +00:00
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
const crm = await CRM.findOne({
|
|
|
|
companyId, crmBaseURL: new URL(crmBaseURL.trim()).hostname
|
|
|
|
})
|
|
|
|
|
|
|
|
if (crm) await crm.deleteOne()
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
}
|
|
|
|
|
|
|
|
const deleteCompany = async (req, res) => {
|
|
|
|
|
|
|
|
const { companyId } = req.body
|
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId',])
|
|
|
|
|
|
|
|
const company = await Company.findOne({ companyId, })
|
|
|
|
|
|
|
|
if (company) await company.deleteOne()
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
}
|
|
|
|
|
|
|
|
const callJournaling = async (req, res) => {
|
|
|
|
|
2025-01-14 18:23:45 +00:00
|
|
|
try {
|
|
|
|
let { companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName, operationStatus } = req.body
|
|
|
|
|
|
|
|
// console.log('REQ.BODY CRM TESTe: ', JSON.stringify(req.body, null, 6))
|
|
|
|
|
|
|
|
|
|
|
|
// 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')
|
|
|
|
|
|
|
|
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)
|
|
|
|
res.status(StatusCodes.INTERNAL_SERVER_ERROR).send()
|
2024-07-19 18:48:34 +00:00
|
|
|
}
|
2023-11-29 20:05:48 +00:00
|
|
|
|
2025-01-14 18:23:45 +00:00
|
|
|
|
2024-07-19 18:48:34 +00:00
|
|
|
}
|
|
|
|
|
2024-11-05 18:37:36 +00:00
|
|
|
|
|
|
|
const sfCreateCase = async (req, res) => {
|
|
|
|
|
|
|
|
const { companyId, crmPhone } = req.body
|
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId', 'crmPhone',])
|
|
|
|
|
|
|
|
const sfCaseRes = await sfcase(companyId, crmPhone)
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).json({ ...sfCaseRes })
|
|
|
|
}
|
|
|
|
|
|
|
|
const sfUpdateCase = async (req, res) => {
|
|
|
|
|
|
|
|
const { companyId, caseId, case: caseUpdate } = req.body
|
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId', 'caseId', 'case'])
|
|
|
|
|
|
|
|
const resCaseUpdate = await sfCaseUpdate(companyId, caseId, caseUpdate)
|
|
|
|
|
|
|
|
if (resCaseUpdate) res.status(StatusCodes.OK).send()
|
|
|
|
|
|
|
|
if (!resCaseUpdate) res.status(StatusCodes.UNPROCESSABLE_ENTITY).send()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
const install = async (req, res) => {
|
|
|
|
|
|
|
|
const { authUrl, companyId } = req.query
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
console.log('--------> authUrl: ', authUrl)
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
// Store the authUrl in the session
|
2025-01-14 18:23:45 +00:00
|
|
|
req.session.authUrl = authUrl + `&companyId=${companyId}`
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
res.redirect(authUrl)
|
|
|
|
}
|
|
|
|
|
|
|
|
const oauthCallBack = async (req, res) => {
|
|
|
|
|
|
|
|
const { code } = req.query
|
|
|
|
|
|
|
|
// Retrieve the stored authUrl from the session
|
|
|
|
const storedAuthUrl = req.session.authUrl
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
console.log('xxxxxxxxxx storedAuthUrl: ', storedAuthUrl)
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
const parsedUrl = new URL(storedAuthUrl)
|
|
|
|
const clientId = parsedUrl.searchParams.get('client_id')
|
2025-01-14 18:23:45 +00:00
|
|
|
const companyId = parsedUrl.searchParams.get('companyId')
|
|
|
|
|
|
|
|
console.log('xxxxxxxxxx clientId: ', clientId)
|
|
|
|
console.log('xxxxxxxxxx companyId: ', companyId)
|
2025-01-15 14:53:39 +00:00
|
|
|
console.log('xxxxxxxxxx code: ', code)
|
2024-09-24 13:23:08 +00:00
|
|
|
|
|
|
|
if (code) {
|
2025-01-15 14:53:39 +00:00
|
|
|
|
|
|
|
console.log('xxxxxxxxxx passed')
|
|
|
|
|
|
|
|
let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId })
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
crmOauth = crmOauth.toObject()
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
let authCodeProof = {
|
2023-11-29 20:05:48 +00:00
|
|
|
grant_type: 'authorization_code',
|
|
|
|
client_id: crmOauth.crm.authentication.crmClientId,
|
|
|
|
client_secret: crmOauth.crm.authentication.crmClientSecret,
|
|
|
|
redirect_uri: process.env.URL_OAUTH_CALLBACK,
|
2024-09-24 13:23:08 +00:00
|
|
|
code
|
|
|
|
}
|
2024-09-24 16:00:14 +00:00
|
|
|
|
2024-09-25 13:28:42 +00:00
|
|
|
//The PKCE is mandatory for salesforce. This is for salesforce only oauth2 that need a code_challenge and code_verifier.
|
2024-09-24 16:00:14 +00:00
|
|
|
const rest = crmOauth.crm.crmRest
|
2024-09-24 13:23:08 +00:00
|
|
|
const salesforceUrls = rest.map(endpoint => {
|
|
|
|
const key = Object.keys(endpoint)[0]
|
2024-10-02 13:06:07 +00:00
|
|
|
const url = endpoint[key]?.request?.url
|
2024-09-24 13:23:08 +00:00
|
|
|
|
2024-10-02 13:06:07 +00:00
|
|
|
if (url?.includes("salesforce")) {
|
2024-09-24 13:23:08 +00:00
|
|
|
return `${key} URL: ${url}`
|
|
|
|
}
|
2024-09-24 16:00:14 +00:00
|
|
|
}).filter(Boolean)
|
|
|
|
|
2024-09-24 13:23:08 +00:00
|
|
|
if (salesforceUrls.find(url => url.includes('salesforce'))) {
|
|
|
|
authCodeProof = {
|
|
|
|
...authCodeProof, ...{
|
|
|
|
code_verifier: `gwkPueV2GSzkFvGFiHbNjpRuq_XBEGBsihM59pMaiFalZrOQ_7J4hgtBR8GIbLHutcuUwba2k0xeKhD8ELjWEswE3xv-H2e6Jh8EOwOccj2i_rYPUlMGdPDqpuRs8D3w`,
|
|
|
|
code: `${code.split('%')[0]}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
// Exchange the authorization code for an access token and refresh token
|
2025-01-15 14:53:39 +00:00
|
|
|
await exchangeForTokens(crmOauth, authCodeProof, companyId)
|
2023-11-29 20:05:48 +00:00
|
|
|
|
2025-01-14 18:23:45 +00:00
|
|
|
const url = `${process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT}?clientId=${encodeURIComponent(clientId)}&codWeb=${companyId}`
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
return res.redirect(url)
|
|
|
|
// return res.redirect(process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT)
|
|
|
|
}
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
}
|
|
|
|
|
|
|
|
const testTemplate = async (req, res) => {
|
|
|
|
|
2024-09-24 13:23:08 +00:00
|
|
|
const { clientId, companyId } = req.body
|
2023-11-29 20:05:48 +00:00
|
|
|
|
2025-01-14 18:23:45 +00:00
|
|
|
let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId, testing: true })
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
if (!crmOauth)
|
|
|
|
return res.status(StatusCodes.OK).send()
|
|
|
|
|
2024-09-24 13:23:08 +00:00
|
|
|
crmOauth = crmOauth.toObject()
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
const { crmPhoneTest } = crmOauth.crm.authentication
|
2024-09-24 13:23:08 +00:00
|
|
|
await templateValidator(crmPhoneTest, crmOauth.crm, companyId)
|
2023-11-29 20:05:48 +00:00
|
|
|
|
2025-01-14 18:23:45 +00:00
|
|
|
crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, 'companyId': companyId })
|
2023-11-29 20:05:48 +00:00
|
|
|
crmOauth.testing = false
|
|
|
|
await crmOauth.save()
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const uploadCrmConfig = async (req, res) => {
|
|
|
|
|
|
|
|
const { companyId, } = req.body
|
|
|
|
|
|
|
|
mustContainProperties(req, ['companyId',])
|
|
|
|
|
2025-01-15 14:53:39 +00:00
|
|
|
//test
|
|
|
|
// console.log('============> uploadCrmConfig companyId: ', companyId)
|
|
|
|
// return res.send()
|
|
|
|
//
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
if (!req?.file)
|
|
|
|
throw new CustomError.BadRequestError(`The crm property file must be provided`)
|
|
|
|
|
|
|
|
const file = req.file
|
|
|
|
|
|
|
|
let newCrm = fs.readFileSync(file.path, "utf8")
|
|
|
|
|
|
|
|
newCrm = JSON.parse(newCrm)
|
|
|
|
|
2024-11-05 18:37:36 +00:00
|
|
|
// console.log('===========> NEW CRM: ', JSON.stringify(newCrm, null, 6))
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
const index = newCrm.crmRest.findIndex(rest => rest?.createContactRecord)
|
|
|
|
|
|
|
|
const crmBaseURL = new URL(newCrm.crmRest[index].createContactRecord.request.url.trim()).hostname
|
|
|
|
|
|
|
|
let company = await Company.findOne({ companyId })
|
|
|
|
|
|
|
|
if (!company) {
|
|
|
|
company = await Company.create({ companyId })
|
|
|
|
}
|
|
|
|
|
|
|
|
let crm = await CRM.findOne({ companyId, crmBaseURL })
|
|
|
|
|
|
|
|
if (crm) {
|
|
|
|
crm.testing = true
|
|
|
|
crm.crm = newCrm
|
|
|
|
await crm.save()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
crm = await CRM.create({
|
|
|
|
crmBaseURL,
|
|
|
|
companyId: company.companyId,
|
|
|
|
company,
|
|
|
|
testing: true,
|
|
|
|
crm: newCrm
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fs.unlinkSync(file.path)
|
|
|
|
|
|
|
|
const { type, crmClientId, crmClientSecret, crmScopes, crmPhoneTest } = crm.crm.authentication
|
|
|
|
|
|
|
|
if (type == 'oauth2') {
|
|
|
|
|
|
|
|
const { request, body, response } = findProperty(crm.crm.crmRest, 'authorizationEndpoint')
|
|
|
|
|
|
|
|
let { url } = request
|
|
|
|
|
|
|
|
url = url.replace('crmClientId', crmClientId)
|
|
|
|
.replace('crmClientSecret', crmClientSecret)
|
|
|
|
.replace('crmScopes', crmScopes)
|
|
|
|
.replace('crmRedirectURI', process.env.URL_OAUTH_CALLBACK)
|
|
|
|
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
const authUrl = `https://api-integracao-crm.hitmanager.app.br/api/v1/crm/install?authUrl=${encodeURIComponent(url)}&companyId=${encodeURIComponent(companyId)}`
|
2023-11-29 20:05:48 +00:00
|
|
|
console.log('--------> authUrl: ', authUrl)
|
|
|
|
|
|
|
|
return res.status(StatusCodes.OK).json({ url: authUrl })
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
await templateValidator(crmPhoneTest, newCrm, companyId)
|
|
|
|
|
|
|
|
crm.testing = false
|
|
|
|
await crm.save()
|
|
|
|
}
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
}
|
|
|
|
|
2024-09-24 12:10:18 +00:00
|
|
|
|
|
|
|
const getCrms = async (req, res) => {
|
|
|
|
const { companyId, } = req.params
|
|
|
|
|
|
|
|
if (!companyId)
|
|
|
|
throw new CustomError.BadRequestError(`The companyId must be provided in the URL`)
|
|
|
|
|
|
|
|
const crms = await CRM.find({ companyId }, { _id: 1, crmBaseURL: 1, createdAt: 1, companyId: 1, enabled: 1 })
|
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send(crms)
|
|
|
|
}
|
|
|
|
|
2024-10-03 20:53:55 +00:00
|
|
|
|
|
|
|
const webhook = async (req, res) => {
|
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const originIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
|
|
|
console.log('========> Origem da requisição IP: ', originIP)
|
|
|
|
|
2024-10-04 17:59:10 +00:00
|
|
|
console.log('========> webhook req.body: ', JSON.stringify(req.body, null, 6))
|
|
|
|
|
2024-10-03 20:53:55 +00:00
|
|
|
console.log('========> req.body: ', req.body)
|
|
|
|
|
|
|
|
if (!req.body?.meta)
|
|
|
|
return res.status(StatusCodes.OK).send()
|
|
|
|
|
|
|
|
let { name, phone_number } = req.body.meta.sender
|
|
|
|
|
2024-11-05 18:37:36 +00:00
|
|
|
const ticketId = req.body?.id
|
|
|
|
|
2024-10-04 02:12:31 +00:00
|
|
|
// const accountId = req.body.account_id
|
|
|
|
const accountId = "15"
|
2024-10-03 20:53:55 +00:00
|
|
|
|
|
|
|
let crmPhone = phone_number.replace('+', '')
|
|
|
|
|
|
|
|
const companies = [
|
2024-10-04 02:12:31 +00:00
|
|
|
// { companyId: "99", account_id: "1" },
|
|
|
|
{ companyId: "99", account_id: "15" },
|
2024-10-03 20:53:55 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
const obj = companies.find(c => +c.account_id == +accountId)
|
|
|
|
|
|
|
|
console.log('=======> name: ', name)
|
|
|
|
console.log('=======> crmPhone: ', crmPhone)
|
|
|
|
console.log('=======> accountId: ', accountId)
|
|
|
|
console.log('=======> companyId: ', obj.companyId)
|
|
|
|
|
2024-11-05 18:37:36 +00:00
|
|
|
console.log('=======> ticketId: ', ticketId)
|
|
|
|
|
|
|
|
|
|
|
|
await whatsappJournalingCRM(
|
2024-10-03 20:53:55 +00:00
|
|
|
companyId = obj.companyId,
|
|
|
|
crmPhone = crmPhone,
|
|
|
|
crmAgent = '0000',
|
2024-11-05 18:37:36 +00:00
|
|
|
crmFirstName = name,
|
|
|
|
ticketId
|
|
|
|
)
|
2024-10-03 20:53:55 +00:00
|
|
|
|
|
|
|
res.status(StatusCodes.OK).send()
|
|
|
|
}
|
|
|
|
|
2024-10-04 17:59:10 +00:00
|
|
|
const webhook_crm = async (req, res) => {
|
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const originIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
|
|
|
console.log('========> Crm Origem da requisição IP: ', originIP)
|
|
|
|
|
2024-10-04 17:59:10 +00:00
|
|
|
console.log('========> webhook crm req.body: ', JSON.stringify(req.body, null, 6))
|
|
|
|
|
|
|
|
const responseXml = `
|
|
|
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
|
|
|
<soapenv:Header/>
|
|
|
|
<soapenv:Body>
|
|
|
|
<notificationsResponse xmlns="urn:enterprise.soap.sforce.com">
|
|
|
|
<Ack>true</Ack>
|
|
|
|
</notificationsResponse>
|
|
|
|
</soapenv:Body>
|
|
|
|
</soapenv:Envelope>`
|
|
|
|
|
|
|
|
const sObject = req.body['soapenv:Envelope']['soapenv:Body']?.notifications?.Notification?.sObject
|
|
|
|
|
|
|
|
if (!sObject) {
|
2024-10-04 18:08:36 +00:00
|
|
|
return res.set('Content-Type', 'text/xml').status(StatusCodes.OK).send(responseXml)
|
2024-10-04 17:59:10 +00:00
|
|
|
}
|
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const url = req.body['soapenv:Envelope']['soapenv:Body']?.notifications?.EnterpriseUrl
|
|
|
|
|
|
|
|
console.log('========> salesforce url: ', url)
|
|
|
|
|
|
|
|
const crm = await CRM.findOne({ crmBaseURL: new URL(url.trim()).hostname })
|
|
|
|
|
|
|
|
const { companyId } = crm
|
|
|
|
|
|
|
|
console.log('========> crm companyId: ', companyId)
|
|
|
|
|
2024-10-04 17:59:10 +00:00
|
|
|
const whoId = sObject['sf:WhoId']
|
|
|
|
const EventSubtype = sObject['sf:EventSubtype']
|
|
|
|
const StartDateTime = sObject['sf:StartDateTime']
|
|
|
|
|
|
|
|
console.log('==========> crm EventSubtype: ', EventSubtype)
|
2024-10-04 18:08:36 +00:00
|
|
|
console.log('==========> crm StartDateTime: ', StartDateTime)
|
|
|
|
console.log('==========> crm StartDateTime timeStamp: ', timeStamp(StartDateTime))
|
|
|
|
|
2024-10-04 17:59:10 +00:00
|
|
|
if (EventSubtype == 'Event') {
|
|
|
|
|
|
|
|
const contact = await CRM_Contact.findOne({
|
2024-10-07 14:25:08 +00:00
|
|
|
companyId,
|
|
|
|
crmBaseURL: new URL(url.trim()).hostname,
|
2024-10-04 17:59:10 +00:00
|
|
|
contactId: whoId
|
|
|
|
})
|
|
|
|
|
|
|
|
console.log('==========> crm whoId: ', whoId)
|
|
|
|
console.log('==========> crm contact: ', contact)
|
|
|
|
|
|
|
|
const { phone } = contact
|
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const obj = omnihitV2Integration.find(o => o.companyId == companyId)
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
if (obj) {
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const { companyId,
|
|
|
|
omnihit: { accountId, api: { url, token } = {},
|
|
|
|
createConversation: { inbox_id, status, team_id } = {} } = {} } = obj
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
const contactIdChatwoot = await getContactIdChatwoot(url, token, phone)
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
if (!contactIdChatwoot) {
|
|
|
|
return res.set('Content-Type', 'text/xml').status(StatusCodes.OK).send(responseXml)
|
|
|
|
}
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
console.log('==========> crm contactIdChatwoot: ', contactIdChatwoot)
|
2024-10-04 17:59:10 +00:00
|
|
|
|
2024-10-07 14:25:08 +00:00
|
|
|
let data = { inbox_id, contact_id: contactIdChatwoot, status, team_id }
|
|
|
|
const omnihitConfig = { url, accountId, token }
|
|
|
|
const ticketId = await createConversation(data, omnihitConfig)
|
|
|
|
|
|
|
|
console.log('==========> crm ticketId: ', ticketId)
|
|
|
|
|
|
|
|
data = { "status": "snoozed", "snoozed_until": timeStamp(StartDateTime) }
|
|
|
|
|
|
|
|
await toggleConversationStatus(url, accountId, token, ticketId, data)
|
2024-11-05 18:37:36 +00:00
|
|
|
}
|
2024-10-04 17:59:10 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 18:08:36 +00:00
|
|
|
return res.set('Content-Type', 'text/xml').status(StatusCodes.OK).send(responseXml)
|
2024-10-04 17:59:10 +00:00
|
|
|
}
|
|
|
|
|
2023-11-29 20:05:48 +00:00
|
|
|
module.exports = {
|
|
|
|
contactCreate,
|
|
|
|
uploadCrmConfig,
|
|
|
|
callJournaling,
|
|
|
|
oauthCallBack,
|
|
|
|
install,
|
|
|
|
deleteCrm,
|
|
|
|
deleteCompany,
|
2024-09-24 12:10:18 +00:00
|
|
|
testTemplate,
|
2024-10-03 20:53:55 +00:00
|
|
|
getCrms,
|
2024-10-04 17:59:10 +00:00
|
|
|
webhook,
|
2024-11-05 18:37:36 +00:00
|
|
|
webhook_crm,
|
|
|
|
sfCreateCase,
|
|
|
|
sfUpdateCase
|
|
|
|
}
|
2023-11-29 20:05:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|