chore: add suport to xml request and response
parent
4ae9104454
commit
70f0fc992d
|
@ -10,10 +10,24 @@ const express = require('express')
|
|||
const app = express()
|
||||
const session = require('express-session')
|
||||
|
||||
const bodyParser = require('body-parser'); // Para JSON
|
||||
require('body-parser-xml')(bodyParser); // Para XML
|
||||
|
||||
// rest of the packages
|
||||
const morgan = require('morgan')
|
||||
// const fileUpload = require('express-fileupload')
|
||||
|
||||
// Middleware para lidar com JSON
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// Middleware para lidar com XML
|
||||
app.use(bodyParser.xml({
|
||||
limit: '1MB',
|
||||
xmlParseOptions: {
|
||||
explicitArray: false,
|
||||
}
|
||||
}));
|
||||
|
||||
const rateLimiter = require('express-rate-limit')
|
||||
|
||||
// Swagger
|
||||
|
@ -51,7 +65,7 @@ app.use(cors())
|
|||
app.use(xss())
|
||||
|
||||
app.use(morgan('tiny'))
|
||||
app.use(express.json())
|
||||
// app.use(express.json())
|
||||
|
||||
// app.use(fileUpload())
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ const { exchangeForTokens } = oauth2
|
|||
const Company = require('../models/Company')
|
||||
const CRM = require('../models/CRM')
|
||||
const CustomError = require('../errors')
|
||||
const CRM_Contact = require('../models/CRM_Contact')
|
||||
const axios = require('axios')
|
||||
const { get, set } = require('../utils/redisClient')
|
||||
|
||||
const contactCreate = async (req, res) => {
|
||||
|
||||
|
@ -289,8 +292,8 @@ const getCrms = async (req, res) => {
|
|||
|
||||
const webhook = async (req, res) => {
|
||||
|
||||
console.log('========> webhook req.body: ', JSON.stringify(req.body, null, 6))
|
||||
|
||||
console.log('========> webhook req.body: ', JSON.stringify(req.body, null, 6))
|
||||
|
||||
console.log('========> req.body: ', req.body)
|
||||
|
||||
if (!req.body?.meta)
|
||||
|
@ -324,6 +327,73 @@ const webhook = async (req, res) => {
|
|||
res.status(StatusCodes.OK).send()
|
||||
}
|
||||
|
||||
const webhook_crm = async (req, res) => {
|
||||
|
||||
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) {
|
||||
res.set('Content-Type', 'text/xml')
|
||||
return res.status(StatusCodes.OK).send(responseXml)
|
||||
}
|
||||
|
||||
const whoId = sObject['sf:WhoId']
|
||||
const EventSubtype = sObject['sf:EventSubtype']
|
||||
const StartDateTime = sObject['sf:StartDateTime']
|
||||
|
||||
|
||||
console.log('==========> crm EventSubtype: ', EventSubtype)
|
||||
console.log('==========> crm StartDateTime: ', StartDateTime)
|
||||
console.log('==========> crm StartDateTime timeStamp: ', timeStamp(StartDateTime))
|
||||
|
||||
|
||||
|
||||
if (EventSubtype == 'Event') {
|
||||
|
||||
const contact = await CRM_Contact.findOne({
|
||||
companyId: "99",
|
||||
crmBaseURL: 'nocompany-a9-dev-ed.develop.my.salesforce.com',
|
||||
contactId: whoId
|
||||
})
|
||||
|
||||
console.log('==========> crm whoId: ', whoId)
|
||||
console.log('==========> crm contact: ', contact)
|
||||
|
||||
const { phone } = contact
|
||||
|
||||
const contactIdChatwoot = await getContactIdChatwoot(phone)
|
||||
|
||||
if (!contactIdChatwoot) {
|
||||
res.set('Content-Type', 'text/xml')
|
||||
return res.status(StatusCodes.OK).send(responseXml)
|
||||
}
|
||||
|
||||
console.log('==========> crm contactIdChatwoot: ', contactIdChatwoot)
|
||||
|
||||
const ticketId = await createConversation(contactIdChatwoot)
|
||||
|
||||
console.log('==========> crm ticketId: ', ticketId)
|
||||
|
||||
await toggleConversationStatus({ "status": "snoozed", "snoozed_until": timeStamp(StartDateTime) }, ticketId)
|
||||
|
||||
}
|
||||
|
||||
|
||||
res.set('Content-Type', 'text/xml')
|
||||
return res.status(StatusCodes.OK).send(responseXml)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
contactCreate,
|
||||
uploadCrmConfig,
|
||||
|
@ -334,7 +404,87 @@ module.exports = {
|
|||
deleteCompany,
|
||||
testTemplate,
|
||||
getCrms,
|
||||
webhook
|
||||
webhook,
|
||||
webhook_crm
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async function getContactIdChatwoot(phone) {
|
||||
|
||||
const config = {
|
||||
method: 'get',
|
||||
url: `http://172.31.187.47:3333/api/v1/accounts/15/contacts/search?q=${phone}`,
|
||||
headers: {
|
||||
'api_access_token': 'WpeGuicvuQ3pyLvYQ11eAxxL'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await axios(config)
|
||||
|
||||
return data.payload[0].id
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
async function createConversation(contact_id) {
|
||||
const data = JSON.stringify({
|
||||
"inbox_id": "2",
|
||||
"contact_id": `${contact_id}`,
|
||||
"status": "pending",
|
||||
"team_id": "1"
|
||||
})
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: 'http://172.31.187.47:3333/api/v1/accounts/15/conversations',
|
||||
headers: {
|
||||
'api_access_token': 'WpeGuicvuQ3pyLvYQ11eAxxL',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: data
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const { data } = await axios(config)
|
||||
return data.id
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleConversationStatus(payload, ticketId) {
|
||||
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: `http://172.31.187.47:3333/api/v1/accounts/15/conversations/${ticketId}/toggle_status`,
|
||||
headers: {
|
||||
'api_access_token': 'WpeGuicvuQ3pyLvYQ11eAxxL',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: JSON.stringify(payload)
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios(config)
|
||||
console.log(JSON.stringify(response.data))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
function timeStamp(dateTimeISO8601) {
|
||||
const date = new Date(dateTimeISO8601)
|
||||
|
||||
date.setHours(date.getUTCHours() - 3)
|
||||
|
||||
const timestamp = date.getTime() / 1000
|
||||
|
||||
return timestamp
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.1",
|
||||
"body-parser-xml": "^2.0.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^10.0.0",
|
||||
"express": "^4.17.1",
|
||||
|
@ -301,6 +302,17 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser-xml": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/body-parser-xml/-/body-parser-xml-2.0.5.tgz",
|
||||
"integrity": "sha512-m1Kvr+0OVo1+t5hEgTrEQMIxFomck4682EJgFx4UpKcKVk9gViifgaFvSNwnQE+S10pPy8Q+dz9iWHYCol51Hw==",
|
||||
"dependencies": {
|
||||
"xml2js": "^0.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/boxen": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
|
||||
|
@ -2154,6 +2166,11 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
|
@ -2713,6 +2730,26 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xss-clean": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xss-clean/-/xss-clean-0.1.1.tgz",
|
||||
|
@ -2981,6 +3018,14 @@
|
|||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"body-parser-xml": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/body-parser-xml/-/body-parser-xml-2.0.5.tgz",
|
||||
"integrity": "sha512-m1Kvr+0OVo1+t5hEgTrEQMIxFomck4682EJgFx4UpKcKVk9gViifgaFvSNwnQE+S10pPy8Q+dz9iWHYCol51Hw==",
|
||||
"requires": {
|
||||
"xml2js": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"boxen": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
|
||||
|
@ -4377,6 +4422,11 @@
|
|||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
|
@ -4801,6 +4851,20 @@
|
|||
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
|
||||
"requires": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
|
||||
},
|
||||
"xss-clean": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xss-clean/-/xss-clean-0.1.1.tgz",
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.1",
|
||||
"body-parser-xml": "^2.0.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^10.0.0",
|
||||
"express": "^4.17.1",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const { authorization, } = require('../middleware/authentication')
|
||||
const { contactCreate, testTemplate, uploadCrmConfig, callJournaling, oauthCallBack, install, deleteCrm, deleteCompany, getCrms, webhook } = require('../controllers/crmController')
|
||||
const { contactCreate, testTemplate, webhook_crm, uploadCrmConfig, callJournaling, oauthCallBack, install, deleteCrm, deleteCompany, getCrms, webhook } = require('../controllers/crmController')
|
||||
const { fileUpload } = require("../utils")
|
||||
|
||||
router.route('/create-contact').post(authorization, contactCreate)
|
||||
|
@ -13,6 +13,7 @@ router.route('/oauth-callback').get(oauthCallBack)
|
|||
router.route('/install').get(install)
|
||||
router.route('/test').post(testTemplate)
|
||||
router.route('/webhook').post(webhook)
|
||||
router.route('/webhook-crm').post(webhook_crm)
|
||||
router.route('/:companyId').get(authorization, getCrms)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue