chore: remove unnecessary comments and improve requests handling

master
adriano 2024-09-24 09:10:18 -03:00
parent 0524aef1b0
commit 75659672bf
25 changed files with 573 additions and 412 deletions

3
.gitignore vendored
View File

@ -7,5 +7,8 @@
**/backend/public/jsonfiles **/backend/public/jsonfiles
**/backend/public/uploads **/backend/public/uploads
**/backend/build
**/frontend/dist
/node_modules /node_modules

View File

@ -64,7 +64,7 @@ app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerDocument))
app.use('/api/v1/crm', crmRouter) app.use('/api/v1/crm', crmRouter)
app.use(notFoundMiddlware) app.use(notFoundMiddlware)
app.use(errorHandlerMiddleware) // app.use(errorHandlerMiddleware)
const port = process.env.PORT || 3000 const port = process.env.PORT || 3000

View File

@ -33,10 +33,14 @@ const contactCreate = async (req, res) => {
const deleteCrm = async (req, res) => { const deleteCrm = async (req, res) => {
const { companyId, crmBaseURL } = req.body let { companyId, crmBaseURL } = req.body
mustContainProperties(req, ['companyId', 'crmBaseURL',]) mustContainProperties(req, ['companyId', 'crmBaseURL',])
if (!crmBaseURL.startsWith('http://') && !crmBaseURL.startsWith('https://')) {
crmBaseURL = `https://${crmBaseURL.trim()}`
}
const crm = await CRM.findOne({ const crm = await CRM.findOne({
companyId, crmBaseURL: new URL(crmBaseURL.trim()).hostname companyId, crmBaseURL: new URL(crmBaseURL.trim()).hostname
}) })
@ -61,10 +65,19 @@ const deleteCompany = async (req, res) => {
const callJournaling = async (req, res) => { const callJournaling = async (req, res) => {
const { companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName, operationStatus } = req.body let { companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName, operationStatus } = req.body
console.log('REQ.BODY CRM TEST: ', JSON.stringify(req.body, null, 6)) console.log('REQ.BODY CRM TESTe: ', JSON.stringify(req.body, null, 6))
// return res.status(StatusCodes.OK).send()
crmPhone = '55' + crmPhone
console.log('========> CRMPHONE: ', crmPhone)
console.log('========> COMPANY ID before: ', companyId)
companyId = '40'
console.log('========> COMPANY ID after: ', companyId)
mustContainProperties(req, ['companyId', 'operation', 'crmPhone', 'crmAgent',]) mustContainProperties(req, ['companyId', 'operation', 'crmPhone', 'crmAgent',])
// if (operation == 'inboundAnsweredCall' && !crmCallDuration) // if (operation == 'inboundAnsweredCall' && !crmCallDuration)
@ -72,9 +85,15 @@ const callJournaling = async (req, res) => {
// if (operation == 'outboundAsweredCall' && !crmCallDuration) // if (operation == 'outboundAsweredCall' && !crmCallDuration)
// throw new CustomError.BadRequestError(`The crmCallDuration property must be provided when operation is outboundAsweredCall`) // throw new CustomError.BadRequestError(`The crmCallDuration property must be provided when operation is outboundAsweredCall`)
if (!crmCallDuration || crmCallDuration.trim() == "")
crmCallDuration = "300"
if (operationStatus == "hangup") if (operationStatus == "hangup")
await journaling(companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName) await journaling(companyId, operation, crmPhone, crmAgent, crmCallDuration, crmFirstName)
else if (operationStatus == "update-answer") { else if (operationStatus == "update-answer") {
console.log('update-answer')
await ticketCRM(companyId, crmPhone, crmAgent, crmFirstName) await ticketCRM(companyId, crmPhone, crmAgent, crmFirstName)
} }
@ -85,6 +104,8 @@ const install = async (req, res) => {
const { authUrl, companyId } = req.query const { authUrl, companyId } = req.query
console.log('--------> authUrl: ', authUrl)
// Store the authUrl in the session // Store the authUrl in the session
req.session.authUrl = authUrl req.session.authUrl = authUrl
@ -98,23 +119,33 @@ const oauthCallBack = async (req, res) => {
// Retrieve the stored authUrl from the session // Retrieve the stored authUrl from the session
const storedAuthUrl = req.session.authUrl const storedAuthUrl = req.session.authUrl
console.log('xxxxxxxxxx storedAuthUrl: ', storedAuthUrl)
const parsedUrl = new URL(storedAuthUrl) const parsedUrl = new URL(storedAuthUrl)
const clientId = parsedUrl.searchParams.get('client_id') const clientId = parsedUrl.searchParams.get('client_id')
if (code) { if (code) {
let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId }) let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId })
crmOauth = crmOauth.toObject() crmOauth = crmOauth.toObject()
const authCodeProof = { let authCodeProof = {
grant_type: 'authorization_code', grant_type: 'authorization_code',
client_id: crmOauth.crm.authentication.crmClientId, client_id: crmOauth.crm.authentication.crmClientId,
client_secret: crmOauth.crm.authentication.crmClientSecret, client_secret: crmOauth.crm.authentication.crmClientSecret,
redirect_uri: process.env.URL_OAUTH_CALLBACK, redirect_uri: process.env.URL_OAUTH_CALLBACK,
code
}
//remove this
// refactor this. To salesforce only when using oauth2
code_verifier: `gwkPueV2GSzkFvGFiHbNjpRuq_XBEGBsihM59pMaiFalZrOQ_7J4hgtBR8GIbLHutcuUwba2k0xeKhD8ELjWEswE3xv-H2e6Jh8EOwOccj2i_rYPUlMGdPDqpuRs8D3w`,
code: `${code.split('%')[0]}`
//
//enable this
// code
}
// Exchange the authorization code for an access token and refresh token // Exchange the authorization code for an access token and refresh token
await exchangeForTokens(crmOauth, authCodeProof) await exchangeForTokens(crmOauth, authCodeProof)
const url = `${process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT}?clientId=${encodeURIComponent(clientId)}` const url = `${process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT}?clientId=${encodeURIComponent(clientId)}`
@ -127,18 +158,17 @@ const oauthCallBack = async (req, res) => {
const testTemplate = async (req, res) => { const testTemplate = async (req, res) => {
const { clientId, companyId } = req.body const { clientId, companyId } = req.body
let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, testing: true }) let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, testing: true })
if (!crmOauth) if (!crmOauth)
return res.status(StatusCodes.OK).send() return res.status(StatusCodes.OK).send()
crmOauth = crmOauth.toObject() crmOauth = crmOauth.toObject()
const { crmPhoneTest } = crmOauth.crm.authentication const { crmPhoneTest } = crmOauth.crm.authentication
await templateValidator(crmPhoneTest, crmOauth.crm, companyId)
await templateValidator(crmPhoneTest, crmOauth.crm, companyId)
crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId }) crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId })
crmOauth.testing = false crmOauth.testing = false
@ -206,7 +236,7 @@ const uploadCrmConfig = async (req, res) => {
.replace('crmRedirectURI', process.env.URL_OAUTH_CALLBACK) .replace('crmRedirectURI', process.env.URL_OAUTH_CALLBACK)
const authUrl = `http://localhost:6001/api/v1/crm/install?authUrl=${encodeURIComponent(url)}&companyId=${encodeURIComponent(companyId)}` const authUrl = `https://api-integracao-crm.hitmanager.app.br/api/v1/crm/install?authUrl=${encodeURIComponent(url)}&companyId=${encodeURIComponent(companyId)}`
console.log('--------> authUrl: ', authUrl) console.log('--------> authUrl: ', authUrl)
return res.status(StatusCodes.OK).json({ url: authUrl }) return res.status(StatusCodes.OK).json({ url: authUrl })
@ -223,6 +253,18 @@ const uploadCrmConfig = async (req, res) => {
res.status(StatusCodes.OK).send() res.status(StatusCodes.OK).send()
} }
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)
}
module.exports = { module.exports = {
contactCreate, contactCreate,
uploadCrmConfig, uploadCrmConfig,
@ -231,7 +273,8 @@ module.exports = {
install, install,
deleteCrm, deleteCrm,
deleteCompany, deleteCompany,
testTemplate testTemplate,
getCrms
} }

View File

@ -1,27 +1,29 @@
const CustomError = require('../errors') const CustomError = require('../errors')
const authorization = async (req, res, next) => { const authorization = async (req, res, next) => {
const authHeader = req.headers.authorization // next()
const authHeader = req.headers.authorization
if (!authHeader) { if (!authHeader) {
throw new CustomError.BadRequestError('Authorization not found into header!') throw new CustomError.BadRequestError('Authorization not found into header!')
} }
const [, token] = authHeader.split(" "); const [, token] = authHeader.split(" ")
if (!token) { if (!token) {
throw new CustomError.BadRequestError('Authorization token not found into header!') throw new CustomError.BadRequestError('Authorization token not found into header!')
} }
if (token != process.env.TOKEN){ if (token != process.env.TOKEN) {
throw new CustomError.UnauthorizedError('Authorization token Invalid') throw new CustomError.UnauthorizedError('Authorization token Invalid')
} }
next() next()
} }
module.exports = { module.exports = {
authorization, authorization,
} }

View File

@ -3449,7 +3449,8 @@
"express-async-errors": { "express-async-errors": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz",
"integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==" "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==",
"requires": {}
}, },
"express-rate-limit": { "express-rate-limit": {
"version": "5.5.1", "version": "5.5.1",
@ -4791,7 +4792,8 @@
"ws": { "ws": {
"version": "8.11.0", "version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==" "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"requires": {}
}, },
"xdg-basedir": { "xdg-basedir": {
"version": "4.0.0", "version": "4.0.0",

View File

@ -1,7 +1,7 @@
const express = require('express') const express = require('express')
const router = express.Router() const router = express.Router()
const { authorization, } = require('../middleware/authentication') const { authorization, } = require('../middleware/authentication')
const { contactCreate, testTemplate, uploadCrmConfig, callJournaling, oauthCallBack, install, deleteCrm, deleteCompany } = require('../controllers/crmController') const { contactCreate, testTemplate, uploadCrmConfig, callJournaling, oauthCallBack, install, deleteCrm, deleteCompany, getCrms } = require('../controllers/crmController')
const { fileUpload } = require("../utils") const { fileUpload } = require("../utils")
router.route('/create-contact').post(authorization, contactCreate) router.route('/create-contact').post(authorization, contactCreate)
@ -12,5 +12,6 @@ router.route('/delete-company').post(authorization, deleteCompany)
router.route('/oauth-callback').get(oauthCallBack) router.route('/oauth-callback').get(oauthCallBack)
router.route('/install').get(install) router.route('/install').get(install)
router.route('/test').post(testTemplate) router.route('/test').post(testTemplate)
router.route('/:companyId').get(authorization, getCrms)
module.exports = router module.exports = router

View File

@ -47,10 +47,14 @@ async function createContact(companyId, rest, authentication, crmPhone, crmFirst
if (test?.testing) { if (test?.testing) {
msg = `Tentanto criar contato de numero ${crmPhone} no crm` msg = `Tentanto criar contato de numero ${crmPhone} no crm`
sendMessageSocket({ companyId, status: 'processing', data: { request: config, msg } }) sendMessageSocket({ companyId, status: 'processing', data: { request: config, msg } })
} }
console.log('#####################')
console.log('CREATE CONTACT PAYLOAD: ', JSON.stringify(config, null, 6))
console.log('#####################')
let { data } = await axios(config) let { data } = await axios(config)
data = flatten(data) data = flatten(data)
let auxContactId let auxContactId
@ -64,7 +68,7 @@ async function createContact(companyId, rest, authentication, crmPhone, crmFirst
break break
} }
} }
if (auxContactId && !test?.testing) { if (auxContactId && !test?.testing) {
const crm = await CRM.findOne({ companyId, crmBaseURL: new URL(url).hostname }) const crm = await CRM.findOne({ companyId, crmBaseURL: new URL(url).hostname })

View File

@ -5,7 +5,7 @@ function dateTime() {
const currentDateBrazil = DateTime.now().setZone(brazilTimeZone) // Get current date and time in Brazil timezone const currentDateBrazil = DateTime.now().setZone(brazilTimeZone) // Get current date and time in Brazil timezone
const formattedDateTime = currentDateBrazil.toFormat("yyyy-MM-dd'T'HH:mm:ssZZ") // Format to ISO 8601 const formattedDateTime = currentDateBrazil.toFormat("yyyy-MM-dd'T'HH:mm:ssZZ") // Format to ISO 8601
console.log('FORMATTED DATE TIME: ', formattedDateTime) console.log('FORMATTED DATE TIME: ', formattedDateTime)
return formattedDateTime return formattedDateTime
@ -14,7 +14,7 @@ function dateTime() {
function secondsFormat(seconds, format = '') { function secondsFormat(seconds, format = '') {
seconds = parseInt(seconds, 10) seconds = parseInt(seconds, 10)
switch (format) { switch (format) {
case 'hh:mm': case 'hh:mm':
@ -33,7 +33,7 @@ function secondsFormat(seconds, format = '') {
} }
function getPastDateTimeFromSeconds(currentTime, secondsToSubtract) { function getPastDateTimeFromSeconds(currentTime, secondsToSubtract) {
const currentDateTime = DateTime.fromISO(currentTime) const currentDateTime = DateTime.fromISO(currentTime)
@ -49,6 +49,20 @@ function getPastDateTimeFromSeconds(currentTime, secondsToSubtract) {
return formattedPastDateTime return formattedPastDateTime
} }
function currentYearMonthDay() {
const originalDate = 'YYYY-MM-DD'
const parsedDate = new Date(originalDate)
const today = new Date()
parsedDate.setFullYear(today.getFullYear())
parsedDate.setMonth(today.getMonth())
parsedDate.setDate(today.getDate())
return parsedDate.toISOString().split('T')[0]
}
module.exports = { dateTime, secondsFormat, getPastDateTimeFromSeconds }
module.exports = { dateTime, secondsFormat, getPastDateTimeFromSeconds, currentYearMonthDay }

View File

@ -0,0 +1,17 @@
function get75PercentTimeInSeconds(issuedAt) {
const twoHoursInSeconds = 2 * 60 * 60
const seventyFivePercent = twoHoursInSeconds * 0.75
const currentTimeInSeconds = Math.floor(Date.now() / 1000)
const issuedAtInSeconds = Math.floor(issuedAt / 1000)
const elapsedTimeInSeconds = currentTimeInSeconds - issuedAtInSeconds
const remainingTimeInSeconds = seventyFivePercent - elapsedTimeInSeconds
if (remainingTimeInSeconds <= 0) {
return 0
}
return Math.round(remainingTimeInSeconds)
}
module.exports = get75PercentTimeInSeconds

View File

@ -24,10 +24,11 @@ const lookupContactByPhone = require('./lookupCRMContactByPhone')
const socketIO = require('./socketIO') const socketIO = require('./socketIO')
const sendMessageSocket = require('./sendMessageSocket') const sendMessageSocket = require('./sendMessageSocket')
const templateValidator = require('./templateValidator') const templateValidator = require('./templateValidator')
const ticketCRM = require('./ticketCRM') const ticketCRM = require('./ticketCRM')
const get75PercentTimeInSeconds = require('./get75PercentTimeInSeconds')
module.exports = { module.exports = {
get75PercentTimeInSeconds,
fileUpload, fileUpload,
loadCRM, loadCRM,
crmCompany, crmCompany,

View File

@ -6,18 +6,18 @@ const findProperty = require('./findProperty')
const journalingRequest = require('./journalingRequest') const journalingRequest = require('./journalingRequest')
async function journaling(companyId, operation, crmPhone, crmAgent, crmCallDuration = 0, crmFirstName ='unnamed') { async function journaling(companyId, operation, crmPhone, crmAgent, crmCallDuration = 0, crmFirstName ='unnamed') {
const crmFiles = await loadCRM(companyId) const crmFiles = await loadCRM(companyId)
for (const crmConfig of crmFiles) { for (const crmConfig of crmFiles) {
const { crmRest: rest, authentication } = crmConfig.crm const { crmRest: rest, authentication } = crmConfig.crm
let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId) let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId)
if (!contact.exist) { if (!contact.exist) {
contact = await createContact(companyId, rest, authentication, crmPhone, crmFirstName) contact = await createContact(companyId, rest, authentication, crmPhone, crmFirstName)
} }
let { request, calls, response } = findProperty(rest, 'callJournaling') let { request, calls, response } = findProperty(rest, 'callJournaling')

View File

@ -1,4 +1,4 @@
const { dateTime, secondsFormat, getPastDateTimeFromSeconds } = require('./dateTime') const { dateTime, secondsFormat, getPastDateTimeFromSeconds, currentYearMonthDay } = require('./dateTime')
const requestConfigHeader = require('./requestConfigHeader') const requestConfigHeader = require('./requestConfigHeader')
const flatten = require('flat') const flatten = require('flat')
const unflatten = require('flat').unflatten const unflatten = require('flat').unflatten
@ -10,6 +10,9 @@ const sendMessageSocket = require('./sendMessageSocket')
async function journalingRequest(request, body, crmCallDuration, contact, crmAgent, crmPhone, authentication, test = {}) { async function journalingRequest(request, body, crmCallDuration, contact, crmAgent, crmPhone, authentication, test = {}) {
const { requestContentType, requestEncoding, requestType, responseType, url } = request const { requestContentType, requestEncoding, requestType, responseType, url } = request
console.log('----------> crmCallDuration: ', crmCallDuration)
console.log('----------> url: ', url)
body = flatten(body) body = flatten(body)
let ignore = [] let ignore = []
@ -90,22 +93,46 @@ async function journalingRequest(request, body, crmCallDuration, contact, crmAge
case 'crmCallDuration': case 'crmCallDuration':
body[key] = crmCallDuration body[key] = crmCallDuration
break break
case 'YYYY-MM-DD':
body[key] = currentYearMonthDay()
break
} }
} }
const data = unflatten(body) const data = unflatten(body)
// Refactor this. Some times the crmCallDuration is comming with the value like 'crmCallDuration' instead of number when
// creating call journaling for salesforce
if (url.includes('salesforce')) {
for (let key in data) {
if (data[key] == 'crmCallDuration') {
data[key] = 300
}
}
}
const { type, userName, passWord, token, crmClientId } = authentication const { type, userName, passWord, token, crmClientId } = authentication
const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, data) const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, data)
if (test?.testing && test?.companyId && test?.msg) { if (test?.testing && test?.companyId && test?.msg) {
sendMessageSocket({ companyId: test.companyId, status: 'processing', data: { request: config, msg: test.msg } }) sendMessageSocket({ companyId: test.companyId, status: 'processing', data: { request: config, msg: test.msg } })
} }
// console.log('JOURNALING CONFIG: ', config)
const res = await axios(config) console.log('#####################')
console.log('CONFIG CALL JOURNALING: ', JSON.stringify(config, null, 6))
console.log('#####################')
try {
const res = await axios(config)
} catch (error) {
console.log(`CALL JOURNALING ERROR: `, error)
}
} }
module.exports = journalingRequest module.exports = journalingRequest

View File

@ -13,23 +13,23 @@ const sendMessageSocket = require('./sendMessageSocket')
async function lookupContactByPhone(rest, authentication, crmPhone, companyId, test = {}) { async function lookupContactByPhone(rest, authentication, crmPhone, companyId, test = {}) {
let { request, body, response } = findProperty(rest, 'lookupContactByPhone') let { request, body, response } = findProperty(rest, 'lookupContactByPhone')
let { requestContentType, requestEncoding, requestType, responseType, url } = request let { requestContentType, requestEncoding, requestType, responseType, url } = request
const { type, userName, passWord, token, crmClientId } = authentication const { type, userName, passWord, token, crmClientId } = authentication
const crmInfo = await CRM_Contact.findOne({ companyId, crmBaseURL: new URL(url).hostname, phone: crmPhone }) const crmInfo = await CRM_Contact.findOne({ companyId, crmBaseURL: new URL(url).hostname, phone: crmPhone })
if (crmInfo) return { exist: true, contactId: crmInfo.contactId, phone: crmPhone } if (crmInfo) return { exist: true, contactId: crmInfo.contactId, phone: crmPhone }
const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId) const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId)
if (test?.testing){ if (test?.testing){
let msg = `Tentanto checar se o contato de numero ${crmPhone} existe no crm` let msg = `Tentanto checar se o contato de numero ${crmPhone} existe no crm`
sendMessageSocket({ companyId, status: 'processing', data: { request: config, msg } }) sendMessageSocket({ companyId, status: 'processing', data: { request: config, msg } })
} }
let { data } = await axios(config) let { data } = await axios(config)
console.log('DATA: ', JSON.stringify(data, null, 6)) console.log('DATA: ', JSON.stringify(data, null, 6))

View File

@ -1,9 +1,10 @@
const qs = require('qs') const qs = require('qs')
const axios = require('axios') const axios = require('axios')
const findProperty = require('./findProperty') const findProperty = require('./findProperty')
const CRM = require('../models/CRM') const CRM = require('../models/CRM')
const { set, get, del } = require('./redisClient') const { set, get, del } = require('./redisClient')
const get75PercentTimeInSeconds = require('./get75PercentTimeInSeconds')
const exchangeForTokens = async (crmOauth, exchangeProof) => { const exchangeForTokens = async (crmOauth, exchangeProof) => {
@ -23,22 +24,31 @@ const exchangeForTokens = async (crmOauth, exchangeProof) => {
'Content-Type': requestContentType 'Content-Type': requestContentType
} }
} }
} }
const { data } = await axios(config) console.log('CONFIG: ', config)
const { refresh_token, access_token, token_type, expires_in } = data const { data } = await axios(config)
await set(crmOauth.crm.authentication.crmClientId, access_token, Math.round(expires_in * 0.75)) const { refresh_token, access_token, token_type, expires_in, issued_at } = data
console.log('===========> refresh_token: ', refresh_token)
console.log('===========> access_token: ', access_token)
// salesforce case
if (issued_at)
await set(crmOauth.crm.authentication.crmClientId, access_token, get75PercentTimeInSeconds(issued_at))
else
await set(crmOauth.crm.authentication.crmClientId, access_token, Math.round(expires_in * 0.75))
crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': crmOauth.crm.authentication.crmClientId }) crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': crmOauth.crm.authentication.crmClientId })
if (refresh_token) { if (refresh_token) {
crmOauth.crm.authentication.crmOAuthRefreshToken = refresh_token crmOauth.crm.authentication.crmOAuthRefreshToken = refresh_token
} }
crmOauth.crm.authentication.crmOAuthToken = access_token crmOauth.crm.authentication.crmOAuthToken = access_token
await crmOauth.save() await crmOauth.save()
return access_token return access_token
} }
@ -46,7 +56,7 @@ const exchangeForTokens = async (crmOauth, exchangeProof) => {
const refreshAccessToken = async (clientId) => { const refreshAccessToken = async (clientId) => {
let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId }) let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId })
crmOauth = crmOauth.toObject() crmOauth = crmOauth.toObject()
const refreshTokenProof = { const refreshTokenProof = {
grant_type: 'refresh_token', grant_type: 'refresh_token',

View File

@ -1,4 +1,4 @@
const SocketIO = require('socket.io') const SocketIO = require('socket.io')
let io let io
const onSocketHandshakeAuthVerifier = (socket, next) => { const onSocketHandshakeAuthVerifier = (socket, next) => {
@ -16,8 +16,8 @@ const onSocketHandshakeAuthVerifier = (socket, next) => {
socket.data.isFromHitphoneWebClient = false socket.data.isFromHitphoneWebClient = false
return next() return next()
} }
if (!codWeb || !extension) { if (!codWeb || !extension) {
console.log(`${new Date().toISOString()} ===========> MIDDLEWARE: Socket with data ${JSON.stringify(socket.handshake.auth)} disconnected because didn't send extension or codWeb`) console.log(`${new Date().toISOString()} ===========> MIDDLEWARE: Socket with data ${JSON.stringify(socket.handshake.auth)} disconnected because didn't send extension or codWeb`)
return next(new Error(`Invalid handshake auth information, required attributes codWeb, extension`)) return next(new Error(`Invalid handshake auth information, required attributes codWeb, extension`))
} }
@ -38,20 +38,20 @@ const onConnectionHitphoneWebClient = (socket) => {
socket.on("disconnect", (data) => { socket.on("disconnect", (data) => {
console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "Hitphone WEB Client" Client disconnected socket: ${data}`) console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "Hitphone WEB Client" Client disconnected socket: ${data}`)
}) })
} }
const onConnectionCrmWizardClient = (socket) => { const onConnectionCrmWizardClient = (socket) => {
const { isFromHitphoneWebClient } = socket.data const { isFromHitphoneWebClient } = socket.data
if (isFromHitphoneWebClient) return if (isFromHitphoneWebClient) return
console.log(`${new Date().toISOString()} ===========> SOCKET CONNECTION: Client connected from "CRM Wizard client"`) console.log(`${new Date().toISOString()} ===========> SOCKET CONNECTION: Client connected from "CRM Wizard client"`)
const { codWeb, extension } = socket.data const { codWeb, extension } = socket.data
socket.join(`${codWeb}@${extension}`) socket.join(`${codWeb}@${extension}`)
socket.on("disconnect", (data) => { socket.on("disconnect", (data) => {
console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "CRM Wizard client" Client disconnected, data: ${data}`) console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "CRM Wizard client" Client disconnected, data: ${data}`)
}) })
} }
const initIO = (httpServer) => { const initIO = (httpServer) => {
@ -59,8 +59,9 @@ const initIO = (httpServer) => {
io = SocketIO(httpServer, { io = SocketIO(httpServer, {
cors: { cors: {
origin: IS_DEV ? "*" : [process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT, process.env.URL_HITPHONE_FRONTEND] origin: IS_DEV ? "*" : [process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT, 'https://integracao-crm.hitmanager.app.br', process.env.URL_HITPHONE_FRONTEND]
}, },
maxHttpBufferSize: 1e8 maxHttpBufferSize: 1e8
}) })
@ -73,13 +74,29 @@ const initIO = (httpServer) => {
* Hitphone Client Flow * Hitphone Client Flow
*/ */
io.on("connection", onConnectionHitphoneWebClient) io.on("connection", onConnectionHitphoneWebClient)
/**
* CRM template frontend test
*/
io.on("connection", socket => {
console.log('CLIENT CONNECTED')
socket.on("companySession", (companyId) => {
console.log(`A client joined a companySession channel: ${companyId}`)
socket.join(`company_${companyId}`)
})
socket.on("disconnect", (data) => {
console.log(`Client disconnected socket: ${data}`)
})
})
return io return io
} }
const getIO = () => { const getIO = () => {
if (!io) { if (!io) {
throw new AppError("Socket IO not initialized") console.log("Socket IO not initialized")
} }
return io return io
} }

View File

@ -4,7 +4,7 @@ const sendMessageSocket = require('./sendMessageSocket')
const findProperty = require('./findProperty') const findProperty = require('./findProperty')
const journalingRequest = require('./journalingRequest') const journalingRequest = require('./journalingRequest')
async function templateValidator(crmPhoneTest, crm, companyId) { async function templateValidator(crmPhoneTest, crm, companyId) {
let phoneTest = crmPhoneTest ? crmPhoneTest : '5511900112233' let phoneTest = crmPhoneTest ? crmPhoneTest : '5511900112233'
@ -13,7 +13,7 @@ async function templateValidator(crmPhoneTest, crm, companyId) {
authentication = crm.authentication, authentication = crm.authentication,
crmPhone = phoneTest, crmPhone = phoneTest,
companyId, companyId,
test = { testing: true }) test = { testing: true })
if (!contact.exist) { if (!contact.exist) {

View File

@ -14,13 +14,15 @@ async function ticketCRM(companyId, crmPhone, crmAgent, crmFirstName = 'unnamed'
const crmFiles = await loadCRM(companyId) const crmFiles = await loadCRM(companyId)
// console.log('xxxxxxxx crmFiles: ', JSON.stringify(crmFiles, null, 6))
for (const crmConfig of crmFiles) { for (const crmConfig of crmFiles) {
const { crmRest: rest, authentication } = crmConfig.crm const { crmRest: rest, authentication } = crmConfig.crm
let obj = findProperty(rest, 'lookupTicket') let obj = findProperty(rest, 'lookupTicket')
if (obj) { if (obj) {
let { url } = obj.request let { url } = obj.request
let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId) let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId)

View File

@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.ae60ab08.css", "main.css": "/static/css/main.ae60ab08.css",
"main.js": "/static/js/main.f5640aba.js", "main.js": "/static/js/main.0f480c22.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.ae60ab08.css.map": "/static/css/main.ae60ab08.css.map", "main.ae60ab08.css.map": "/static/css/main.ae60ab08.css.map",
"main.f5640aba.js.map": "/static/js/main.f5640aba.js.map" "main.0f480c22.js.map": "/static/js/main.0f480c22.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.ae60ab08.css", "static/css/main.ae60ab08.css",
"static/js/main.f5640aba.js" "static/js/main.0f480c22.js"
] ]
} }

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.f5640aba.js"></script><link href="/static/css/main.ae60ab08.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.0f480c22.js"></script><link href="/static/css/main.ae60ab08.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ const UploadFile = () => {
const formData = new FormData() const formData = new FormData()
formData.append('crm', file) formData.append('crm', file)
formData.append('companyId', process.env.REACT_APP_COMPANY_ID) formData.append('companyId', process.env.REACT_APP_COMPANY_ID)
try { try {
const response = await axios.post(`${process.env.REACT_APP_URL_API}/api/v1/crm/upload`, formData, { const response = await axios.post(`${process.env.REACT_APP_URL_API}/api/v1/crm/upload`, formData, {
@ -42,7 +42,7 @@ const UploadFile = () => {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer 2ivck10D3o9qAZi0pkKudVDl9bdEVXY2s8gdxZ0jYgL1DZWTgDz6wDiIjlWgYmJtVOoqf0b42ZTLBRrfo8WoAaScRsujz3jQUNXdchSg0o43YilZGmVhheGJNAeIQRknHEll4nRJ7avcFgmDGoYbEey7TSC8EHS4Z3gzeufYYSfnKNDBwwzBURIQrTOxYFe3tBHsGOzwnuD2lU5tnEx7tr2XRO4zRNYeNY4lMBOFM0mRuyAe4kuqTrKXmJ8As200' 'Authorization': 'Bearer 2ivck10D3o9qAZi0pkKudVDl9bdEVXY2s8gdxZ0jYgL1DZWTgDz6wDiIjlWgYmJtVOoqf0b42ZTLBRrfo8WoAaScRsujz3jQUNXdchSg0o43YilZGmVhheGJNAeIQRknHEll4nRJ7avcFgmDGoYbEey7TSC8EHS4Z3gzeufYYSfnKNDBwwzBURIQrTOxYFe3tBHsGOzwnuD2lU5tnEx7tr2XRO4zRNYeNY4lMBOFM0mRuyAe4kuqTrKXmJ8As200'
}, },
}) })
if (response.status === 200) { if (response.status === 200) {
@ -75,8 +75,6 @@ const UploadFile = () => {
console.log('process.env.REACT_APP_COMPANY_ID: ', process.env.REACT_APP_COMPANY_ID) console.log('process.env.REACT_APP_COMPANY_ID: ', process.env.REACT_APP_COMPANY_ID)
const socket = socketIOClient(process.env.REACT_APP_URL_API)
const currentURL = window.location.href const currentURL = window.location.href
const urlObject = new URL(currentURL) const urlObject = new URL(currentURL)
const clientId = urlObject.searchParams.get('clientId') const clientId = urlObject.searchParams.get('clientId')
@ -92,7 +90,7 @@ const UploadFile = () => {
}) })
} catch (error) { } catch (error) {
setStatus('error') setStatus('error')
console.error('-----> Error:', error) console.log('-----> Error:', error)
console.log('TEST: ', error.response.data.msg) console.log('TEST: ', error.response.data.msg)
setErrorResponse(error.response.data.msg) setErrorResponse(error.response.data.msg)
} }
@ -102,6 +100,8 @@ const UploadFile = () => {
} }
const socket = socketIOClient(process.env.REACT_APP_URL_API)
socket.emit('companySession', process.env.REACT_APP_COMPANY_ID) socket.emit('companySession', process.env.REACT_APP_COMPANY_ID)
socket.on('crm_upload', (data) => { socket.on('crm_upload', (data) => {
@ -133,7 +133,7 @@ const UploadFile = () => {
const handleAfterOpenModal = () => { const handleAfterOpenModal = () => {
} }
return ( return (
<div className="centered"> <div className="centered">
<input type="file" onChange={handleFileChange} /> <input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>Upload</button> <button onClick={handleUpload}>Upload</button>